sem_new.c (265847) | sem_new.c (273604) |
---|---|
1/* 2 * Copyright (C) 2010 David Xu <davidxu@freebsd.org>. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * | 1/* 2 * Copyright (C) 2010 David Xu <davidxu@freebsd.org>. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 12 unchanged lines hidden (view full) --- 21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 27 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * |
29 * $FreeBSD: head/lib/libc/gen/sem_new.c 265847 2014-05-10 19:08:07Z kib $ | 29 * $FreeBSD: head/lib/libc/gen/sem_new.c 273604 2014-10-24 20:02:44Z jhb $ |
30 */ 31 32#include "namespace.h" 33#include <sys/types.h> 34#include <sys/queue.h> 35#include <sys/mman.h> 36#include <sys/stat.h> 37#include <errno.h> --- 18 unchanged lines hidden (view full) --- 56__weak_reference(_sem_open, sem_open); 57__weak_reference(_sem_post, sem_post); 58__weak_reference(_sem_timedwait, sem_timedwait); 59__weak_reference(_sem_trywait, sem_trywait); 60__weak_reference(_sem_unlink, sem_unlink); 61__weak_reference(_sem_wait, sem_wait); 62 63#define SEM_PREFIX "/tmp/SEMD" | 30 */ 31 32#include "namespace.h" 33#include <sys/types.h> 34#include <sys/queue.h> 35#include <sys/mman.h> 36#include <sys/stat.h> 37#include <errno.h> --- 18 unchanged lines hidden (view full) --- 56__weak_reference(_sem_open, sem_open); 57__weak_reference(_sem_post, sem_post); 58__weak_reference(_sem_timedwait, sem_timedwait); 59__weak_reference(_sem_trywait, sem_trywait); 60__weak_reference(_sem_unlink, sem_unlink); 61__weak_reference(_sem_wait, sem_wait); 62 63#define SEM_PREFIX "/tmp/SEMD" |
64#define SEM_MAGIC ((u_int32_t)0x73656d31) | 64#define SEM_MAGIC ((u_int32_t)0x73656d32) |
65 | 65 |
66_Static_assert(SEM_VALUE_MAX <= USEM_MAX_COUNT, "SEM_VALUE_MAX too large"); 67 |
|
66struct sem_nameinfo { 67 int open_count; 68 char *name; 69 dev_t dev; 70 ino_t ino; 71 sem_t *sem; 72 LIST_ENTRY(sem_nameinfo) next; 73}; --- 52 unchanged lines hidden (view full) --- 126 if (value > SEM_VALUE_MAX) { 127 errno = EINVAL; 128 return (-1); 129 } 130 131 bzero(sem, sizeof(sem_t)); 132 sem->_magic = SEM_MAGIC; 133 sem->_kern._count = (u_int32_t)value; | 68struct sem_nameinfo { 69 int open_count; 70 char *name; 71 dev_t dev; 72 ino_t ino; 73 sem_t *sem; 74 LIST_ENTRY(sem_nameinfo) next; 75}; --- 52 unchanged lines hidden (view full) --- 128 if (value > SEM_VALUE_MAX) { 129 errno = EINVAL; 130 return (-1); 131 } 132 133 bzero(sem, sizeof(sem_t)); 134 sem->_magic = SEM_MAGIC; 135 sem->_kern._count = (u_int32_t)value; |
134 sem->_kern._has_waiters = 0; | |
135 sem->_kern._flags = pshared ? USYNC_PROCESS_SHARED : 0; 136 return (0); 137} 138 139sem_t * 140_sem_open(const char *name, int flags, ...) 141{ 142 char path[PATH_MAX]; --- 64 unchanged lines hidden (view full) --- 207 fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode); 208 if (fd == -1 || _fstat(fd, &sb) == -1) 209 goto error; 210 } 211 if (sb.st_size < sizeof(sem_t)) { 212 sem_t tmp; 213 214 tmp._magic = SEM_MAGIC; | 136 sem->_kern._flags = pshared ? USYNC_PROCESS_SHARED : 0; 137 return (0); 138} 139 140sem_t * 141_sem_open(const char *name, int flags, ...) 142{ 143 char path[PATH_MAX]; --- 64 unchanged lines hidden (view full) --- 208 fd = _open(path, flags | O_RDWR | O_CLOEXEC | O_EXLOCK, mode); 209 if (fd == -1 || _fstat(fd, &sb) == -1) 210 goto error; 211 } 212 if (sb.st_size < sizeof(sem_t)) { 213 sem_t tmp; 214 215 tmp._magic = SEM_MAGIC; |
215 tmp._kern._has_waiters = 0; | |
216 tmp._kern._count = value; 217 tmp._kern._flags = USYNC_PROCESS_SHARED | SEM_NAMED; 218 if (_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) 219 goto error; 220 } 221 flock(fd, LOCK_UN); 222 sem = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, 223 MAP_SHARED|MAP_NOSYNC, fd, 0); --- 103 unchanged lines hidden (view full) --- 327 328int 329_sem_getvalue(sem_t * __restrict sem, int * __restrict sval) 330{ 331 332 if (sem_check_validity(sem) != 0) 333 return (-1); 334 | 216 tmp._kern._count = value; 217 tmp._kern._flags = USYNC_PROCESS_SHARED | SEM_NAMED; 218 if (_write(fd, &tmp, sizeof(tmp)) != sizeof(tmp)) 219 goto error; 220 } 221 flock(fd, LOCK_UN); 222 sem = (sem_t *)mmap(NULL, sizeof(sem_t), PROT_READ|PROT_WRITE, 223 MAP_SHARED|MAP_NOSYNC, fd, 0); --- 103 unchanged lines hidden (view full) --- 327 328int 329_sem_getvalue(sem_t * __restrict sem, int * __restrict sval) 330{ 331 332 if (sem_check_validity(sem) != 0) 333 return (-1); 334 |
335 *sval = (int)sem->_kern._count; | 335 *sval = (int)USEM_COUNT(sem->_kern._count); |
336 return (0); 337} 338 339static __inline int | 336 return (0); 337} 338 339static __inline int |
340usem_wake(struct _usem *sem) | 340usem_wake(struct _usem2 *sem) |
341{ | 341{ |
342 return _umtx_op(sem, UMTX_OP_SEM_WAKE, 0, NULL, NULL); | 342 return _umtx_op(sem, UMTX_OP_SEM2_WAKE, 0, NULL, NULL); |
343} 344 345static __inline int | 343} 344 345static __inline int |
346usem_wait(struct _usem *sem, const struct timespec *abstime) | 346usem_wait(struct _usem2 *sem, const struct timespec *abstime) |
347{ 348 struct _umtx_time *tm_p, timeout; 349 size_t tm_size; 350 351 if (abstime == NULL) { 352 tm_p = NULL; 353 tm_size = 0; 354 } else { 355 timeout._clockid = CLOCK_REALTIME; 356 timeout._flags = UMTX_ABSTIME; 357 timeout._timeout = *abstime; 358 tm_p = &timeout; 359 tm_size = sizeof(timeout); 360 } | 347{ 348 struct _umtx_time *tm_p, timeout; 349 size_t tm_size; 350 351 if (abstime == NULL) { 352 tm_p = NULL; 353 tm_size = 0; 354 } else { 355 timeout._clockid = CLOCK_REALTIME; 356 timeout._flags = UMTX_ABSTIME; 357 timeout._timeout = *abstime; 358 tm_p = &timeout; 359 tm_size = sizeof(timeout); 360 } |
361 return _umtx_op(sem, UMTX_OP_SEM_WAIT, 0, | 361 return _umtx_op(sem, UMTX_OP_SEM2_WAIT, 0, |
362 (void *)tm_size, __DECONST(void*, tm_p)); 363} 364 365int 366_sem_trywait(sem_t *sem) 367{ 368 int val; 369 370 if (sem_check_validity(sem) != 0) 371 return (-1); 372 | 362 (void *)tm_size, __DECONST(void*, tm_p)); 363} 364 365int 366_sem_trywait(sem_t *sem) 367{ 368 int val; 369 370 if (sem_check_validity(sem) != 0) 371 return (-1); 372 |
373 while ((val = sem->_kern._count) > 0) { | 373 while (USEM_COUNT(val = sem->_kern._count) > 0) { |
374 if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) 375 return (0); 376 } 377 errno = EAGAIN; 378 return (-1); 379} 380 381int 382_sem_timedwait(sem_t * __restrict sem, 383 const struct timespec * __restrict abstime) 384{ 385 int val, retval; 386 387 if (sem_check_validity(sem) != 0) 388 return (-1); 389 390 retval = 0; 391 _pthread_testcancel(); 392 for (;;) { | 374 if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) 375 return (0); 376 } 377 errno = EAGAIN; 378 return (-1); 379} 380 381int 382_sem_timedwait(sem_t * __restrict sem, 383 const struct timespec * __restrict abstime) 384{ 385 int val, retval; 386 387 if (sem_check_validity(sem) != 0) 388 return (-1); 389 390 retval = 0; 391 _pthread_testcancel(); 392 for (;;) { |
393 while ((val = sem->_kern._count) > 0) { | 393 while (USEM_COUNT(val = sem->_kern._count) > 0) { |
394 if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) 395 return (0); 396 } 397 398 if (retval) { 399 _pthread_testcancel(); 400 break; 401 } --- 32 unchanged lines hidden (view full) --- 434{ 435 unsigned int count; 436 437 if (sem_check_validity(sem) != 0) 438 return (-1); 439 440 do { 441 count = sem->_kern._count; | 394 if (atomic_cmpset_acq_int(&sem->_kern._count, val, val - 1)) 395 return (0); 396 } 397 398 if (retval) { 399 _pthread_testcancel(); 400 break; 401 } --- 32 unchanged lines hidden (view full) --- 434{ 435 unsigned int count; 436 437 if (sem_check_validity(sem) != 0) 438 return (-1); 439 440 do { 441 count = sem->_kern._count; |
442 if (count + 1 > SEM_VALUE_MAX) | 442 if (USEM_COUNT(count) + 1 > SEM_VALUE_MAX) |
443 return (EOVERFLOW); | 443 return (EOVERFLOW); |
444 } while(!atomic_cmpset_rel_int(&sem->_kern._count, count, count+1)); 445 (void)usem_wake(&sem->_kern); | 444 } while (!atomic_cmpset_rel_int(&sem->_kern._count, count, count + 1)); 445 if (count & USEM_HAS_WAITERS) 446 usem_wake(&sem->_kern); |
446 return (0); 447} | 447 return (0); 448} |