sem.c (202883) | sem.c (213153) |
---|---|
1/* 2 * Copyright (C) 2010 David Xu <davidxu@freebsd.org>. 3 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * | 1/* 2 * Copyright (C) 2010 David Xu <davidxu@freebsd.org>. 3 * Copyright (C) 2000 Jason Evans <jasone@freebsd.org>. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 13 unchanged lines hidden (view full) --- 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 25 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 27 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 28 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * |
30 * $FreeBSD: head/lib/libc/gen/sem.c 202883 2010-01-23 12:48:46Z antoine $ | 30 * $FreeBSD: head/lib/libc/gen/sem.c 213153 2010-09-25 01:57:47Z davidxu $ |
31 */ 32 33/* 34 * Some notes about this implementation. 35 * 36 * This is mostly a simple implementation of POSIX semaphores that 37 * does not need threading. Any semaphore created is a kernel-based 38 * semaphore regardless of the pshared attribute. This is necessary --- 268 unchanged lines hidden (view full) --- 307int 308_libc_sem_unlink_compat(const char *name) 309{ 310 311 return (ksem_unlink(name)); 312} 313 314static int | 31 */ 32 33/* 34 * Some notes about this implementation. 35 * 36 * This is mostly a simple implementation of POSIX semaphores that 37 * does not need threading. Any semaphore created is a kernel-based 38 * semaphore regardless of the pshared attribute. This is necessary --- 268 unchanged lines hidden (view full) --- 307int 308_libc_sem_unlink_compat(const char *name) 309{ 310 311 return (ksem_unlink(name)); 312} 313 314static int |
315enable_async_cancel(void) 316{ 317 int old; 318 319 _pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &old); 320 return (old); 321} 322 323static void 324restore_async_cancel(int val) 325{ 326 _pthread_setcanceltype(val, NULL); 327} 328 329static int | |
330_umtx_wait_uint(volatile unsigned *mtx, unsigned id, const struct timespec *timeout) 331{ 332 if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && 333 timeout->tv_nsec <= 0))) { 334 errno = ETIMEDOUT; 335 return (-1); 336 } 337 return _umtx_op(__DEVOLATILE(void *, mtx), --- 28 unchanged lines hidden (view full) --- 366 _umtx_wake(&(*sem)->count); 367} 368 369int 370_libc_sem_timedwait_compat(sem_t * __restrict sem, 371 const struct timespec * __restrict abstime) 372{ 373 struct timespec ts, ts2; | 315_umtx_wait_uint(volatile unsigned *mtx, unsigned id, const struct timespec *timeout) 316{ 317 if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && 318 timeout->tv_nsec <= 0))) { 319 errno = ETIMEDOUT; 320 return (-1); 321 } 322 return _umtx_op(__DEVOLATILE(void *, mtx), --- 28 unchanged lines hidden (view full) --- 351 _umtx_wake(&(*sem)->count); 352} 353 354int 355_libc_sem_timedwait_compat(sem_t * __restrict sem, 356 const struct timespec * __restrict abstime) 357{ 358 struct timespec ts, ts2; |
374 int val, retval, saved_cancel; | 359 int val, retval; |
375 376 if (sem_check_validity(sem) != 0) 377 return (-1); 378 379 if ((*sem)->syssem != 0) { | 360 361 if (sem_check_validity(sem) != 0) 362 return (-1); 363 364 if ((*sem)->syssem != 0) { |
380 saved_cancel = enable_async_cancel(); 381 retval = ksem_wait((*sem)->semid); 382 restore_async_cancel(saved_cancel); | 365 _pthread_cancel_enter(1); 366 retval = ksem_wait((*sem)->semid); /* XXX no timeout */ 367 _pthread_cancel_leave(retval == -1); |
383 return (retval); 384 } 385 386 retval = 0; 387 _pthread_testcancel(); 388 for (;;) { 389 while ((val = (*sem)->count) > 0) { 390 if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1)) 391 return (0); 392 } | 368 return (retval); 369 } 370 371 retval = 0; 372 _pthread_testcancel(); 373 for (;;) { 374 while ((val = (*sem)->count) > 0) { 375 if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1)) 376 return (0); 377 } |
393 if (retval) | 378 if (retval) { 379 _pthread_testcancel(); |
394 break; | 380 break; |
381 } |
|
395 if (abstime) { 396 if (abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0) { 397 errno = EINVAL; 398 return (-1); 399 } 400 clock_gettime(CLOCK_REALTIME, &ts); 401 TIMESPEC_SUB(&ts2, abstime, &ts); 402 } 403 atomic_add_int(&(*sem)->nwaiters, 1); 404 pthread_cleanup_push(sem_cancel_handler, sem); | 382 if (abstime) { 383 if (abstime->tv_nsec >= 1000000000 || abstime->tv_nsec < 0) { 384 errno = EINVAL; 385 return (-1); 386 } 387 clock_gettime(CLOCK_REALTIME, &ts); 388 TIMESPEC_SUB(&ts2, abstime, &ts); 389 } 390 atomic_add_int(&(*sem)->nwaiters, 1); 391 pthread_cleanup_push(sem_cancel_handler, sem); |
405 saved_cancel = enable_async_cancel(); | 392 _pthread_cancel_enter(1); |
406 retval = _umtx_wait_uint(&(*sem)->count, 0, abstime ? &ts2 : NULL); | 393 retval = _umtx_wait_uint(&(*sem)->count, 0, abstime ? &ts2 : NULL); |
407 restore_async_cancel(saved_cancel); | 394 _pthread_cancel_leave(0); |
408 pthread_cleanup_pop(0); 409 atomic_add_int(&(*sem)->nwaiters, -1); 410 } 411 return (retval); 412} 413 414int 415_libc_sem_wait_compat(sem_t *sem) --- 56 unchanged lines hidden --- | 395 pthread_cleanup_pop(0); 396 atomic_add_int(&(*sem)->nwaiters, -1); 397 } 398 return (retval); 399} 400 401int 402_libc_sem_wait_compat(sem_t *sem) --- 56 unchanged lines hidden --- |