Deleted Added
full compact
30c30
< * $FreeBSD: head/lib/libthr/thread/thr_sem.c 178647 2008-04-29 03:58:18Z davidxu $
---
> * $FreeBSD: head/lib/libthr/thread/thr_sem.c 201546 2010-01-05 02:37:59Z davidxu $
39d38
< #include <semaphore.h>
46a46,52
> FB10_COMPAT(_sem_init_compat, sem_init);
> FB10_COMPAT(_sem_destroy_compat, sem_destroy);
> FB10_COMPAT(_sem_getvalue_compat, sem_getvalue);
> FB10_COMPAT(_sem_trywait_compat, sem_trywait);
> FB10_COMPAT(_sem_wait_compat, sem_wait);
> FB10_COMPAT(_sem_timedwait_compat, sem_timedwait);
> FB10_COMPAT(_sem_post_compat, sem_post);
48,54c54
< __weak_reference(_sem_init, sem_init);
< __weak_reference(_sem_destroy, sem_destroy);
< __weak_reference(_sem_getvalue, sem_getvalue);
< __weak_reference(_sem_trywait, sem_trywait);
< __weak_reference(_sem_wait, sem_wait);
< __weak_reference(_sem_timedwait, sem_timedwait);
< __weak_reference(_sem_post, sem_post);
---
> typedef struct sem *sem_t;
55a56,63
> extern int _libc_sem_init_compat(sem_t *sem, int pshared, unsigned int value);
> extern int _libc_sem_destroy_compat(sem_t *sem);
> extern int _libc_sem_getvalue_compat(sem_t * __restrict sem, int * __restrict sval);
> extern int _libc_sem_trywait_compat(sem_t *sem);
> extern int _libc_sem_wait_compat(sem_t *sem);
> extern int _libc_sem_timedwait_compat(sem_t * __restrict sem,
> const struct timespec * __restrict abstime);
> extern int _libc_sem_post_compat(sem_t *sem);
57,59c65,72
< static inline int
< sem_check_validity(sem_t *sem)
< {
---
> int _sem_init_compat(sem_t *sem, int pshared, unsigned int value);
> int _sem_destroy_compat(sem_t *sem);
> int _sem_getvalue_compat(sem_t * __restrict sem, int * __restrict sval);
> int _sem_trywait_compat(sem_t *sem);
> int _sem_wait_compat(sem_t *sem);
> int _sem_timedwait_compat(sem_t * __restrict sem,
> const struct timespec * __restrict abstime);
> int _sem_post_compat(sem_t *sem);
61,97d73
< if ((sem != NULL) && ((*sem)->magic == SEM_MAGIC))
< return (0);
< else {
< errno = EINVAL;
< return (-1);
< }
< }
<
< static sem_t
< sem_alloc(unsigned int value, semid_t semid, int system_sem)
< {
< sem_t sem;
<
< if (value > SEM_VALUE_MAX) {
< errno = EINVAL;
< return (NULL);
< }
<
< sem = (sem_t)malloc(sizeof(struct sem));
< if (sem == NULL) {
< errno = ENOSPC;
< return (NULL);
< }
< bzero(sem, sizeof(*sem));
< /*
< * Fortunatly count and nwaiters are adjacency, so we can
< * use umtx_wait to wait on it, umtx_wait needs an address
< * can be accessed as a long interger.
< */
< sem->count = (u_int32_t)value;
< sem->nwaiters = 0;
< sem->magic = SEM_MAGIC;
< sem->semid = semid;
< sem->syssem = system_sem;
< return (sem);
< }
<
99c75
< _sem_init(sem_t *sem, int pshared, unsigned int value)
---
> _sem_init_compat(sem_t *sem, int pshared, unsigned int value)
101,113c77
< semid_t semid;
<
< semid = (semid_t)SEM_USER;
< if ((pshared != 0) && (ksem_init(&semid, value) != 0))
< return (-1);
<
< (*sem) = sem_alloc(value, semid, pshared);
< if ((*sem) == NULL) {
< if (pshared != 0)
< ksem_destroy(semid);
< return (-1);
< }
< return (0);
---
> return _libc_sem_init_compat(sem, pshared, value);
117c81
< _sem_destroy(sem_t *sem)
---
> _sem_destroy_compat(sem_t *sem)
119,136c83
< int retval;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< /*
< * If this is a system semaphore let the kernel track it otherwise
< * make sure there are no waiters.
< */
< if ((*sem)->syssem != 0)
< retval = ksem_destroy((*sem)->semid);
< else {
< retval = 0;
< (*sem)->magic = 0;
< }
< if (retval == 0)
< free(*sem);
< return (retval);
---
> return _libc_sem_destroy_compat(sem);
140c87
< _sem_getvalue(sem_t * __restrict sem, int * __restrict sval)
---
> _sem_getvalue_compat(sem_t * __restrict sem, int * __restrict sval)
142,153c89
< int retval;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< if ((*sem)->syssem != 0)
< retval = ksem_getvalue((*sem)->semid, sval);
< else {
< *sval = (int)(*sem)->count;
< retval = 0;
< }
< return (retval);
---
> return _libc_sem_getvalue_compat(sem, sval);
157c93
< _sem_trywait(sem_t *sem)
---
> _sem_trywait_compat(sem_t *sem)
159,172c95
< int val;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< if ((*sem)->syssem != 0)
< return (ksem_trywait((*sem)->semid));
<
< while ((val = (*sem)->count) > 0) {
< if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1))
< return (0);
< }
< errno = EAGAIN;
< return (-1);
---
> return _libc_sem_trywait_compat(sem);
175,184d97
< static void
< sem_cancel_handler(void *arg)
< {
< sem_t *sem = arg;
<
< atomic_add_int(&(*sem)->nwaiters, -1);
< if ((*sem)->nwaiters && (*sem)->count)
< _thr_umtx_wake(&(*sem)->count, 1, 0);
< }
<
186c99
< _sem_wait(sem_t *sem)
---
> _sem_wait_compat(sem_t *sem)
188,217c101
< struct pthread *curthread;
< int val, retval;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< curthread = _get_curthread();
< if ((*sem)->syssem != 0) {
< _thr_cancel_enter(curthread);
< retval = ksem_wait((*sem)->semid);
< _thr_cancel_leave(curthread);
< return (retval);
< }
<
< _pthread_testcancel();
< do {
< while ((val = (*sem)->count) > 0) {
< if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1))
< return (0);
< }
< atomic_add_int(&(*sem)->nwaiters, 1);
< THR_CLEANUP_PUSH(curthread, sem_cancel_handler, sem);
< _thr_cancel_enter(curthread);
< retval = _thr_umtx_wait_uint(&(*sem)->count, 0, NULL, 0);
< _thr_cancel_leave(curthread);
< THR_CLEANUP_POP(curthread, 0);
< atomic_add_int(&(*sem)->nwaiters, -1);
< } while (retval == 0);
< errno = retval;
< return (-1);
---
> return _libc_sem_wait_compat(sem);
221c105
< _sem_timedwait(sem_t * __restrict sem,
---
> _sem_timedwait_compat(sem_t * __restrict sem,
224,264c108
< struct timespec ts, ts2;
< struct pthread *curthread;
< int val, retval;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< curthread = _get_curthread();
< if ((*sem)->syssem != 0) {
< _thr_cancel_enter(curthread);
< retval = ksem_timedwait((*sem)->semid, abstime);
< _thr_cancel_leave(curthread);
< return (retval);
< }
<
< /*
< * The timeout argument is only supposed to
< * be checked if the thread would have blocked.
< */
< _pthread_testcancel();
< do {
< while ((val = (*sem)->count) > 0) {
< if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1))
< return (0);
< }
< if (abstime == NULL) {
< errno = EINVAL;
< return (-1);
< }
< clock_gettime(CLOCK_REALTIME, &ts);
< TIMESPEC_SUB(&ts2, abstime, &ts);
< atomic_add_int(&(*sem)->nwaiters, 1);
< THR_CLEANUP_PUSH(curthread, sem_cancel_handler, sem);
< _thr_cancel_enter(curthread);
< retval = _thr_umtx_wait_uint((uint32_t*)&(*sem)->count, 0, &ts2, 0);
< _thr_cancel_leave(curthread);
< THR_CLEANUP_POP(curthread, 0);
< atomic_add_int(&(*sem)->nwaiters, -1);
< } while (retval == 0);
< errno = retval;
< return (-1);
---
> return _libc_sem_timedwait_compat(sem, abstime);
267,271d110
< /*
< * sem_post() is required to be safe to call from within
< * signal handlers, these code should work as that.
< */
<
273c112
< _sem_post(sem_t *sem)
---
> _sem_post_compat(sem_t *sem)
275,290c114
< int retval = 0;
<
< if (sem_check_validity(sem) != 0)
< return (-1);
<
< if ((*sem)->syssem != 0)
< return (ksem_post((*sem)->semid));
<
< atomic_add_rel_int(&(*sem)->count, 1);
<
< if ((*sem)->nwaiters) {
< retval = _thr_umtx_wake(&(*sem)->count, 1, 0);
< if (retval != 0)
< retval = -1;
< }
< return (retval);
---
> return _libc_sem_post_compat(sem);