Deleted Added
full compact
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}