t_join.c revision 314817
192108Sphk/* $NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $ */ 292108Sphk 392108Sphk/*- 492108Sphk * Copyright (c) 2010 The NetBSD Foundation, Inc. 592108Sphk * All rights reserved. 692108Sphk * 792108Sphk * This code is derived from software contributed to The NetBSD Foundation 892108Sphk * by Jukka Ruohonen. 992108Sphk * 1092108Sphk * Redistribution and use in source and binary forms, with or without 1192108Sphk * modification, are permitted provided that the following conditions 1292108Sphk * are met: 1392108Sphk * 1. Redistributions of source code must retain the above copyright 1492108Sphk * notice, this list of conditions and the following disclaimer. 1592108Sphk * 2. Redistributions in binary form must reproduce the above copyright 1692108Sphk * notice, this list of conditions and the following disclaimer in the 1792108Sphk * documentation and/or other materials provided with the distribution. 1892108Sphk * 1992108Sphk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 2092108Sphk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 2192108Sphk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 2292108Sphk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 2392108Sphk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2492108Sphk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2592108Sphk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2692108Sphk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2792108Sphk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2892108Sphk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2992108Sphk * POSSIBILITY OF SUCH DAMAGE. 3092108Sphk */ 3192108Sphk#include <sys/cdefs.h> 3292108Sphk__RCSID("$NetBSD: t_join.c,v 1.8 2012/03/12 20:17:16 joerg Exp $"); 3392108Sphk 34139778Simp#include <errno.h> 35139778Simp#include <pthread.h> 36139778Simp#include <stdint.h> 37104065Sphk 38104065Sphk#include <atf-c.h> 39108819Sphk 4092108Sphk#include "h_common.h" 4192108Sphk 42116196Sobrien#ifdef CHECK_STACK_ALIGNMENT 43116196Sobrienextern int check_stack_alignment(void); 44116196Sobrien#endif 4592108Sphk 46113011Sphk#define STACKSIZE 65536 4792108Sphk 48219029Snetchildstatic bool error; 4992108Sphk 50138732Sphkstatic void *threadfunc1(void *); 5192108Sphkstatic void *threadfunc2(void *); 5292108Sphk 5392108SphkATF_TC(pthread_join); 5492108SphkATF_TC_HEAD(pthread_join, tc) 5592108Sphk{ 56108819Sphk 5792108Sphk atf_tc_set_md_var(tc, "descr", 5892108Sphk "Checks basic error conditions in pthread_join(3)"); 59174347Sjhb} 60235480Savg 61223921SaeATF_TC_BODY(pthread_join, tc) 62174347Sjhb{ 6392108Sphk pthread_t thread; 6492108Sphk 6592108Sphk PTHREAD_REQUIRE(pthread_create(&thread, NULL, threadfunc1, NULL)); 66219029Snetchild PTHREAD_REQUIRE(pthread_join(thread, NULL)); 67219029Snetchild} 68105505Sphk 6992108Sphkstatic void * 70106634Sphkthreadfunc1(void *arg) 71152972Ssobomax{ 72106634Sphk pthread_t thread[25]; 73114556Sphk pthread_t caller; 74114556Sphk void *val = NULL; 75113713Sphk uintptr_t i; 76104065Sphk int rv; 77104065Sphk pthread_attr_t attr; 78105505Sphk 79104065Sphk caller = pthread_self(); 80104065Sphk 8192108Sphk#ifdef CHECK_STACK_ALIGNMENT 8295323Sphk /* 83106076Sphk * Check alignment of thread stack, if supported. 84104065Sphk */ 8592108Sphk ATF_REQUIRE(check_stack_alignment()); 86114556Sphk#endif 87108819Sphk 8892108Sphk /* 8992108Sphk * The behavior is undefined, but should error 90104065Sphk * out, if we try to join the calling thread. 91104065Sphk */ 92114556Sphk rv = pthread_join(caller, NULL); 93104065Sphk 94104065Sphk /* 95114556Sphk * The specification recommends EDEADLK. 96104065Sphk */ 97104065Sphk ATF_REQUIRE(rv != 0); 98104065Sphk ATF_REQUIRE_EQ(rv, EDEADLK); 99104065Sphk 100104065Sphk ATF_REQUIRE(pthread_attr_init(&attr) == 0); 101113713Sphk 102107953Sphk for (i = 0; i < __arraycount(thread); i++) { 103115509Sphk 104114556Sphk error = true; 105114556Sphk 106104065Sphk ATF_REQUIRE(pthread_attr_setstacksize(&attr, STACKSIZE * (i + 1)) == 0); 107114556Sphk 108114556Sphk rv = pthread_create(&thread[i], &attr, threadfunc2, (void *)i); 109114556Sphk 110114556Sphk ATF_REQUIRE_EQ(rv, 0); 111114556Sphk 112114556Sphk /* 113105505Sphk * Check join and exit condition. 114114556Sphk */ 115104065Sphk PTHREAD_REQUIRE(pthread_join(thread[i], &val)); 116105505Sphk 117104065Sphk ATF_REQUIRE_EQ(error, false); 118105551Sphk 119104065Sphk ATF_REQUIRE(val != NULL); 120105505Sphk ATF_REQUIRE(val == (void *)(i + 1)); 121114556Sphk 122104065Sphk /* 123114556Sphk * Once the thread has returned, ESRCH should 124104065Sphk * again follow if we try to join it again. 125105505Sphk */ 126114556Sphk rv = pthread_join(thread[i], NULL); 127104065Sphk 128114556Sphk ATF_REQUIRE_EQ(rv, ESRCH); 129104065Sphk 130114556Sphk /* 131114556Sphk * Try to detach the exited thread. 132114672Sphk */ 133114556Sphk rv = pthread_detach(thread[i]); 134114556Sphk 135114556Sphk ATF_REQUIRE(rv != 0); 136114556Sphk } 137114556Sphk 138104065Sphk ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); 139114556Sphk 140114556Sphk pthread_exit(NULL); 141114556Sphk 142114705Sphk return NULL; 143114785Sphk} 144185518Sivoras 145185518Sivorasstatic void * 146114705Sphkthreadfunc2(void *arg) 147114785Sphk{ 148114556Sphk static uintptr_t i = 0; 149105505Sphk uintptr_t j; 150114556Sphk pthread_attr_t attr; 151114556Sphk size_t stacksize; 152104065Sphk 153114556Sphk j = (uintptr_t)arg; 154114556Sphk 155114556Sphk#ifdef __FreeBSD__ 156104065Sphk pthread_attr_init(&attr); 157114556Sphk#endif 158114556Sphk ATF_REQUIRE(pthread_attr_get_np(pthread_self(), &attr) == 0); 159114556Sphk ATF_REQUIRE(pthread_attr_getstacksize(&attr, &stacksize) == 0); 160104065Sphk ATF_REQUIRE(stacksize == STACKSIZE * (j + 1)); 161114556Sphk ATF_REQUIRE(pthread_attr_destroy(&attr) == 0); 162104065Sphk 163104065Sphk if (i++ == j) 164104065Sphk error = false; 165104065Sphk 166107953Sphk pthread_exit((void *)i); 167114556Sphk 168114556Sphk return NULL; 169114556Sphk} 170114556Sphk 171107953SphkATF_TP_ADD_TCS(tp) 172114556Sphk{ 173114556Sphk 174114556Sphk ATF_TP_ADD_TC(tp, pthread_join); 175107953Sphk 176104065Sphk return atf_no_error(); 177104065Sphk} 178114556Sphk