Wed Mar 7 23:31:44 2012 UTC ()
Remove libpthread's semaphore implementation and always use the kernel
one. The implementation doesn't provide an async-safe sem_post and can't
without a lot of work on the pthread primitives.

Remove bogus time out requirement in test case, it should have been
a "known failure" if anything.


(joerg)
diff -r1.21 -r1.22 src/lib/libpthread/sem.c
diff -r1.5 -r1.6 src/tests/lib/libpthread/t_sem.c

cvs diff -r1.21 -r1.22 src/lib/libpthread/Attic/sem.c (expand / switch to unified diff)

--- src/lib/libpthread/Attic/sem.c 2008/11/14 15:49:20 1.21
+++ src/lib/libpthread/Attic/sem.c 2012/03/07 23:31:44 1.22
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sem.c,v 1.21 2008/11/14 15:49:20 ad Exp $ */ 1/* $NetBSD: sem.c,v 1.22 2012/03/07 23:31:44 joerg Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran. 8 * by Jason R. Thorpe of Wasabi Systems, Inc, and by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -49,138 +49,112 @@ @@ -49,138 +49,112 @@
49 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE 51 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
52 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 52 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 53 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
55 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 55 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
56 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 56 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
57 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 57 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
58 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 58 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62__RCSID("$NetBSD: sem.c,v 1.21 2008/11/14 15:49:20 ad Exp $"); 62__RCSID("$NetBSD: sem.c,v 1.22 2012/03/07 23:31:44 joerg Exp $");
63 63
64#include <sys/types.h> 64#include <sys/types.h>
65#include <sys/ksem.h> 65#include <sys/ksem.h>
66#include <sys/queue.h> 66#include <sys/queue.h>
67#include <stdlib.h> 67#include <stdlib.h>
68#include <errno.h> 68#include <errno.h>
69#include <fcntl.h> 69#include <fcntl.h>
70#include <semaphore.h> 70#include <semaphore.h>
71#include <stdarg.h> 71#include <stdarg.h>
72 72
73#include "pthread.h" 73#include "pthread.h"
74#include "pthread_int.h" 
75 74
76struct _sem_st { 75struct _sem_st {
77 unsigned int usem_magic; 76 unsigned int ksem_magic;
78#define USEM_MAGIC 0x09fa4012 77#define KSEM_MAGIC 0x90af0421U
79 78
80 LIST_ENTRY(_sem_st) usem_list; 79 LIST_ENTRY(_sem_st) ksem_list;
81 intptr_t usem_semid; /* 0 -> user (non-shared) */ 80 intptr_t ksem_semid; /* 0 -> user (non-shared) */
82#define USEM_USER 0 /* assumes kernel does not use NULL */ 81 sem_t *ksem_identity;
83 sem_t *usem_identity; 
84 
85 /* Protects data below. */ 
86 pthread_mutex_t usem_interlock; 
87 pthread_cond_t usem_cv; 
88 unsigned int usem_count; 
89}; 82};
90 83
91static int sem_alloc(unsigned int value, intptr_t semid, sem_t *semp); 84static int sem_alloc(unsigned int value, intptr_t semid, sem_t *semp);
92static void sem_free(sem_t sem); 85static void sem_free(sem_t sem);
93 86
94static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems); 87static LIST_HEAD(, _sem_st) named_sems = LIST_HEAD_INITIALIZER(&named_sems);
95static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER; 88static pthread_mutex_t named_sems_mtx = PTHREAD_MUTEX_INITIALIZER;
96 89
97static void 90static void
98sem_free(sem_t sem) 91sem_free(sem_t sem)
99{ 92{
100 93
101 if (sem->usem_semid == USEM_USER) { 94 sem->ksem_magic = 0;
102 pthread_cond_destroy(&sem->usem_cv); 
103 pthread_mutex_destroy(&sem->usem_interlock); 
104 } 
105 sem->usem_magic = 0; 
106 free(sem); 95 free(sem);
107} 96}
108 97
109static int 98static int
110sem_alloc(unsigned int value, intptr_t semid, sem_t *semp) 99sem_alloc(unsigned int value, intptr_t semid, sem_t *semp)
111{ 100{
112 sem_t sem; 101 sem_t sem;
113 102
114 if (value > SEM_VALUE_MAX) 103 if (value > SEM_VALUE_MAX)
115 return (EINVAL); 104 return (EINVAL);
116 105
117 if ((sem = malloc(sizeof(struct _sem_st))) == NULL) 106 if ((sem = malloc(sizeof(struct _sem_st))) == NULL)
118 return (ENOSPC); 107 return (ENOSPC);
119 108
120 sem->usem_magic = USEM_MAGIC; 109 sem->ksem_magic = KSEM_MAGIC;
121 pthread_mutex_init(&sem->usem_interlock, NULL); 110 sem->ksem_semid = semid;
122 pthread_cond_init(&sem->usem_cv, NULL); 111
123 sem->usem_count = value; 
124 sem->usem_semid = semid; 
125 
126 *semp = sem; 112 *semp = sem;
127 return (0); 113 return (0);
128} 114}
129 115
 116/* ARGSUSED */
130int 117int
131sem_init(sem_t *sem, int pshared, unsigned int value) 118sem_init(sem_t *sem, int pshared, unsigned int value)
132{ 119{
133 intptr_t semid; 120 intptr_t semid;
134 int error; 121 int error;
135 122
136 semid = USEM_USER; 123 if (_ksem_init(value, &semid) == -1)
137 
138 if (pshared && _ksem_init(value, &semid) == -1) 
139 return (-1); 124 return (-1);
140 125
141 if ((error = sem_alloc(value, semid, sem)) != 0) { 126 if ((error = sem_alloc(value, semid, sem)) != 0) {
142 if (semid != USEM_USER) 127 _ksem_destroy(semid);
143 _ksem_destroy(semid); 
144 errno = error; 128 errno = error;
145 return (-1); 129 return (-1);
146 } 130 }
147 131
148 return (0); 132 return (0);
149} 133}
150 134
151int 135int
152sem_destroy(sem_t *sem) 136sem_destroy(sem_t *sem)
153{ 137{
154 138
155#ifdef ERRORCHECK 139#ifdef ERRORCHECK
156 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 140 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
157 errno = EINVAL; 141 errno = EINVAL;
158 return (-1); 142 return (-1);
159 } 143 }
160#endif 144#endif
161 145
162 if ((*sem)->usem_semid != USEM_USER) { 146 if (_ksem_destroy((*sem)->ksem_semid) == -1)
163 if (_ksem_destroy((*sem)->usem_semid)) 147 return (-1);
164 return (-1); 
165 } else { 
166 pthread_mutex_lock(&(*sem)->usem_interlock); 
167 if (!PTQ_EMPTY(&(*sem)->usem_cv.ptc_waiters)) { 
168 pthread_mutex_unlock(&(*sem)->usem_interlock); 
169 errno = EBUSY; 
170 return (-1); 
171 } 
172 pthread_mutex_unlock(&(*sem)->usem_interlock); 
173 } 
174 148
175 sem_free(*sem); 149 sem_free(*sem);
176 150
177 return (0); 151 return (0);
178} 152}
179 153
180sem_t * 154sem_t *
181sem_open(const char *name, int oflag, ...) 155sem_open(const char *name, int oflag, ...)
182{ 156{
183 sem_t *sem, s; 157 sem_t *sem, s;
184 intptr_t semid; 158 intptr_t semid;
185 mode_t mode; 159 mode_t mode;
186 unsigned int value; 160 unsigned int value;
@@ -199,217 +173,130 @@ sem_open(const char *name, int oflag, .. @@ -199,217 +173,130 @@ sem_open(const char *name, int oflag, ..
199 173
200 /* 174 /*
201 * We can be lazy and let the kernel handle the oflag, 175 * We can be lazy and let the kernel handle the oflag,
202 * we'll just merge duplicate IDs into our list. 176 * we'll just merge duplicate IDs into our list.
203 */ 177 */
204 if (_ksem_open(name, oflag, mode, value, &semid) == -1) 178 if (_ksem_open(name, oflag, mode, value, &semid) == -1)
205 return (SEM_FAILED); 179 return (SEM_FAILED);
206 180
207 /* 181 /*
208 * Search for a duplicate ID, we must return the same sem_t * 182 * Search for a duplicate ID, we must return the same sem_t *
209 * if we locate one. 183 * if we locate one.
210 */ 184 */
211 pthread_mutex_lock(&named_sems_mtx); 185 pthread_mutex_lock(&named_sems_mtx);
212 LIST_FOREACH(s, &named_sems, usem_list) { 186 LIST_FOREACH(s, &named_sems, ksem_list) {
213 if (s->usem_semid == semid) { 187 if (s->ksem_semid == semid) {
214 pthread_mutex_unlock(&named_sems_mtx); 188 pthread_mutex_unlock(&named_sems_mtx);
215 return (s->usem_identity); 189 return (s->ksem_identity);
216 } 190 }
217 } 191 }
218 192
219 if ((sem = malloc(sizeof(*sem))) == NULL) { 193 if ((sem = malloc(sizeof(*sem))) == NULL) {
220 error = ENOSPC; 194 error = ENOSPC;
221 goto bad; 195 goto bad;
222 } 196 }
223 if ((error = sem_alloc(value, semid, sem)) != 0) 197 if ((error = sem_alloc(value, semid, sem)) != 0)
224 goto bad; 198 goto bad;
225 199
226 LIST_INSERT_HEAD(&named_sems, *sem, usem_list); 200 LIST_INSERT_HEAD(&named_sems, *sem, ksem_list);
227 (*sem)->usem_identity = sem; 
228 pthread_mutex_unlock(&named_sems_mtx); 201 pthread_mutex_unlock(&named_sems_mtx);
 202 (*sem)->ksem_identity = sem;
229 203
230 return (sem); 204 return (sem);
231 205
232 bad: 206 bad:
233 pthread_mutex_unlock(&named_sems_mtx); 207 pthread_mutex_unlock(&named_sems_mtx);
234 _ksem_close(semid); 208 _ksem_close(semid);
235 if (sem != NULL) { 209 if (sem != NULL) {
236 if (*sem != NULL) 210 if (*sem != NULL)
237 sem_free(*sem); 211 sem_free(*sem);
238 free(sem); 212 free(sem);
239 } 213 }
240 errno = error; 214 errno = error;
241 return (SEM_FAILED); 215 return (SEM_FAILED);
242} 216}
243 217
244int 218int
245sem_close(sem_t *sem) 219sem_close(sem_t *sem)
246{ 220{
247 221
248#ifdef ERRORCHECK 222#ifdef ERRORCHECK
249 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 223 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
250 errno = EINVAL; 224 errno = EINVAL;
251 return (-1); 225 return (-1);
252 } 226 }
253#endif 227#endif
254 228
255 if ((*sem)->usem_semid == USEM_USER) { 
256 errno = EINVAL; 
257 return (-1); 
258 } 
259 
260 pthread_mutex_lock(&named_sems_mtx); 229 pthread_mutex_lock(&named_sems_mtx);
261 if (_ksem_close((*sem)->usem_semid) == -1) { 230 if (_ksem_close((*sem)->ksem_semid) == -1) {
262 pthread_mutex_unlock(&named_sems_mtx); 231 pthread_mutex_unlock(&named_sems_mtx);
263 return (-1); 232 return (-1);
264 } 233 }
265 LIST_REMOVE((*sem), usem_list); 234
 235 LIST_REMOVE((*sem), ksem_list);
266 pthread_mutex_unlock(&named_sems_mtx); 236 pthread_mutex_unlock(&named_sems_mtx);
267 sem_free(*sem); 237 sem_free(*sem);
268 free(sem); 238 free(sem);
269 return (0); 239 return (0);
270} 240}
271 241
272int 242int
273sem_unlink(const char *name) 243sem_unlink(const char *name)
274{ 244{
275 245
276 return (_ksem_unlink(name)); 246 return (_ksem_unlink(name));
277} 247}
278 248
279int 249int
280sem_wait(sem_t *sem) 250sem_wait(sem_t *sem)
281{ 251{
282 pthread_t self; 
283 extern int pthread__started; 
284 252
285#ifdef ERRORCHECK 253#ifdef ERRORCHECK
286 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 254 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
287 errno = EINVAL; 255 errno = EINVAL;
288 return (-1); 256 return (-1);
289 } 257 }
290#endif 258#endif
291 259
292 self = pthread__self(); 260 return (_ksem_wait((*sem)->ksem_semid));
293 
294 if ((*sem)->usem_semid != USEM_USER) { 
295 pthread__testcancel(self); 
296 return (_ksem_wait((*sem)->usem_semid)); 
297 } 
298 
299 if (pthread__started == 0) { 
300 sigset_t set, oset; 
301 
302 sigfillset(&set); 
303 (void) sigprocmask(SIG_SETMASK, &set, &oset); 
304 for (;;) { 
305 if ((*sem)->usem_count > 0) { 
306 break; 
307 } 
308 (void) sigsuspend(&oset); 
309 } 
310 (*sem)->usem_count--; 
311 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 
312 return 0; 
313 } 
314 
315 pthread_mutex_lock(&(*sem)->usem_interlock); 
316 for (;;) { 
317 if (self->pt_cancel) { 
318 pthread_mutex_unlock(&(*sem)->usem_interlock); 
319 pthread__cancelled(); 
320 } 
321 if ((*sem)->usem_count > 0) 
322 break; 
323 (void)pthread_cond_wait(&(*sem)->usem_cv, 
324 &(*sem)->usem_interlock); 
325 } 
326 (*sem)->usem_count--; 
327 pthread_mutex_unlock(&(*sem)->usem_interlock); 
328 
329 return (0); 
330} 261}
331 262
332int 263int
333sem_trywait(sem_t *sem) 264sem_trywait(sem_t *sem)
334{ 265{
335 extern int pthread__started; 
336 266
337#ifdef ERRORCHECK 267#ifdef ERRORCHECK
338 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 268 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
339 errno = EINVAL; 269 errno = EINVAL;
340 return (-1); 270 return (-1);
341 } 271 }
342#endif 272#endif
343 273
344 if ((*sem)->usem_semid != USEM_USER) 274 return (_ksem_trywait((*sem)->ksem_semid));
345 return (_ksem_trywait((*sem)->usem_semid)); 
346 
347 if (pthread__started == 0) { 
348 sigset_t set, oset; 
349 int rv = 0; 
350 
351 sigfillset(&set); 
352 (void) sigprocmask(SIG_SETMASK, &set, &oset); 
353 if ((*sem)->usem_count > 0) { 
354 (*sem)->usem_count--; 
355 } else { 
356 errno = EAGAIN; 
357 rv = -1; 
358 } 
359 (void) sigprocmask(SIG_SETMASK, &oset, NULL); 
360 return rv; 
361 } 
362 
363 pthread_mutex_lock(&(*sem)->usem_interlock); 
364 if ((*sem)->usem_count == 0) { 
365 pthread_mutex_unlock(&(*sem)->usem_interlock); 
366 errno = EAGAIN; 
367 return (-1); 
368 } 
369 (*sem)->usem_count--; 
370 pthread_mutex_unlock(&(*sem)->usem_interlock); 
371 
372 return (0); 
373} 275}
374 276
375int 277int
376sem_post(sem_t *sem) 278sem_post(sem_t *sem)
377{ 279{
378 280
379#ifdef ERRORCHECK 281#ifdef ERRORCHECK
380 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 282 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
381 errno = EINVAL; 283 errno = EINVAL;
382 return (-1); 284 return (-1);
383 } 285 }
384#endif 286#endif
385 287
386 if ((*sem)->usem_semid != USEM_USER) 288 return (_ksem_post((*sem)->ksem_semid));
387 return (_ksem_post((*sem)->usem_semid)); 
388 
389 pthread_mutex_lock(&(*sem)->usem_interlock); 
390 (*sem)->usem_count++; 
391 pthread_cond_signal(&(*sem)->usem_cv); 
392 pthread_mutex_unlock(&(*sem)->usem_interlock); 
393 
394 return (0); 
395} 289}
396 290
397int 291int
398sem_getvalue(sem_t * __restrict sem, int * __restrict sval) 292sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
399{ 293{
400 294
401#ifdef ERRORCHECK 295#ifdef ERRORCHECK
402 if (sem == NULL || *sem == NULL || (*sem)->usem_magic != USEM_MAGIC) { 296 if (sem == NULL || *sem == NULL || (*sem)->ksem_magic != KSEM_MAGIC) {
403 errno = EINVAL; 297 errno = EINVAL;
404 return (-1); 298 return (-1);
405 } 299 }
406#endif 300#endif
407 if ((*sem)->usem_semid != USEM_USER) 301 return (_ksem_getvalue((*sem)->ksem_semid, sval));
408 return (_ksem_getvalue((*sem)->usem_semid, sval)); 
409 
410 pthread_mutex_lock(&(*sem)->usem_interlock); 
411 *sval = (int) (*sem)->usem_count; 
412 pthread_mutex_unlock(&(*sem)->usem_interlock); 
413 
414 return (0); 
415} 302}

cvs diff -r1.5 -r1.6 src/tests/lib/libpthread/t_sem.c (expand / switch to unified diff)

--- src/tests/lib/libpthread/t_sem.c 2010/11/03 16:10:22 1.5
+++ src/tests/lib/libpthread/t_sem.c 2012/03/07 23:31:44 1.6
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: t_sem.c,v 1.5 2010/11/03 16:10:22 christos Exp $ */ 1/* $NetBSD: t_sem.c,v 1.6 2012/03/07 23:31:44 joerg Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2010 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -76,27 +76,27 @@ @@ -76,27 +76,27 @@
76 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 76 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
77 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 77 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
78 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 78 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
79 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 79 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
80 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 80 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
81 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 81 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
82 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 82 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
83 * 83 *
84 ****************************************************************************/ 84 ****************************************************************************/
85 85
86#include <sys/cdefs.h> 86#include <sys/cdefs.h>
87__COPYRIGHT("@(#) Copyright (c) 2008, 2010\ 87__COPYRIGHT("@(#) Copyright (c) 2008, 2010\
88 The NetBSD Foundation, inc. All rights reserved."); 88 The NetBSD Foundation, inc. All rights reserved.");
89__RCSID("$NetBSD: t_sem.c,v 1.5 2010/11/03 16:10:22 christos Exp $"); 89__RCSID("$NetBSD: t_sem.c,v 1.6 2012/03/07 23:31:44 joerg Exp $");
90 90
91#include <errno.h> 91#include <errno.h>
92#include <fcntl.h> 92#include <fcntl.h>
93#include <pthread.h> 93#include <pthread.h>
94#include <semaphore.h> 94#include <semaphore.h>
95#include <signal.h> 95#include <signal.h>
96#include <stdio.h> 96#include <stdio.h>
97#include <stdlib.h> 97#include <stdlib.h>
98#include <string.h> 98#include <string.h>
99#include <unistd.h> 99#include <unistd.h>
100 100
101#include <atf-c.h> 101#include <atf-c.h>
102#include <atf-c/config.h> 102#include <atf-c/config.h>
@@ -280,32 +280,25 @@ ATF_TC_BODY(before_start_no_threads, tc) @@ -280,32 +280,25 @@ ATF_TC_BODY(before_start_no_threads, tc)
280{ 280{
281 before_start_test(false); 281 before_start_test(false);
282} 282}
283 283
284ATF_TC(before_start_one_thread); 284ATF_TC(before_start_one_thread);
285ATF_TC_HEAD(before_start_one_thread, tc) 285ATF_TC_HEAD(before_start_one_thread, tc)
286{ 286{
287 atf_tc_set_md_var(tc, "descr", "Checks using semaphores before " 287 atf_tc_set_md_var(tc, "descr", "Checks using semaphores before "
288 "starting one thread"); 288 "starting one thread");
289 atf_tc_set_md_var(tc, "timeout", "40"); 289 atf_tc_set_md_var(tc, "timeout", "40");
290} 290}
291ATF_TC_BODY(before_start_one_thread, tc) 291ATF_TC_BODY(before_start_one_thread, tc)
292{ 292{
293 /* TODO(jmmv): This really is a race condition test. However, we can't 
294 * yet mark it as such because ATF does not provide such functionality. 
295 * Let's just mark it as an unconditional expected timeout as I haven't 
296 * got it to pass any single time. */ 
297 atf_tc_expect_timeout("Race condition; it is probably unsafe to call " 
298 "sem_post from a signal handler when using the pthread version"); 
299 
300 before_start_test(true); 293 before_start_test(true);
301} 294}
302 295
303ATF_TP_ADD_TCS(tp) 296ATF_TP_ADD_TCS(tp)
304{ 297{
305 ATF_TP_ADD_TC(tp, named); 298 ATF_TP_ADD_TC(tp, named);
306 ATF_TP_ADD_TC(tp, unnamed); 299 ATF_TP_ADD_TC(tp, unnamed);
307 ATF_TP_ADD_TC(tp, before_start_no_threads); 300 ATF_TP_ADD_TC(tp, before_start_no_threads);
308 ATF_TP_ADD_TC(tp, before_start_one_thread); 301 ATF_TP_ADD_TC(tp, before_start_one_thread);
309 302
310 return atf_no_error(); 303 return atf_no_error();
311} 304}