From a6dffc4afcfb78fbb043971ecffdf5a2cfa60989 Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Thu, 12 May 2005 11:50:42 +0000 Subject: libpthread/ 2005-05-12 Neal H. Walfield * Makefile (SRCS): Add sem-close.c sem-destroy.c sem-getvalue.c sem-init.c sem-open.c sem-post.c sem-timedwait.c sem-trywait.c sem-unlink.c and sem-wait.c. (sysdeps_headers): Add semaphore.h bits/semaphore.h. * include/semaphore.h: New file. * sysdeps/generic/sem-close.c: New file. * sysdeps/generic/sem-destroy.c: New file. * sysdeps/generic/sem-getvalue.c: New file. * sysdeps/generic/sem-init.c: New file. * sysdeps/generic/sem-open.c: New file. * sysdeps/generic/sem-post.c: New file. * sysdeps/generic/sem-timedwait.c: New file. * sysdeps/generic/sem-trywait.c: New file. * sysdeps/generic/sem-unlink.c: New file. * sysdeps/generic/sem-wait.c: New file. * sysdeps/generic/bits/semaphore.h: New file. --- sysdeps/generic/sem-timedwait.c | 92 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 sysdeps/generic/sem-timedwait.c (limited to 'sysdeps/generic/sem-timedwait.c') diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c new file mode 100644 index 0000000..f3d280b --- /dev/null +++ b/sysdeps/generic/sem-timedwait.c @@ -0,0 +1,92 @@ +/* Wait on a semaphore with a timeout. Generic version. + Copyright (C) 2005 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include + +#include + +int +__sem_timedwait_internal (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + struct __pthread *self; + + __pthread_spin_lock (&sem->__lock); + if (sem->__value > 0) + /* Successful down. */ + { + sem->__value --; + __pthread_spin_unlock (&sem->__lock); + return 0; + } + + /* Add ourselves to the queue. */ + self = _pthread_self (); + + __pthread_enqueue (&sem->__queue, self); + __pthread_spin_unlock (&sem->__lock); + + /* Block the thread. */ + if (timeout) + { + error_t err; + + if (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000) + { + errno = EINVAL; + return -1; + } + + err = __pthread_timedblock (self, timeout); + if (err) + /* We timed out. We may need to disconnect ourself from the + waiter queue. + + FIXME: What do we do if we get a wakeup message before we + disconnect ourself? It may remain until the next time we + block. */ + { + assert (err == ETIMEDOUT); + + __pthread_spin_lock (&sem->__lock); + if (self->prevp) + __pthread_dequeue (self); + __pthread_spin_unlock (&sem->__lock); + + errno = err; + return -1; + } + } + else + __pthread_block (self); + + return 0; +} + +int +__sem_timedwait (sem_t *restrict sem, + const struct timespec *restrict timeout) +{ + return __sem_timedwait_internal (sem, timeout); +} + +weak_alias (__sem_timedwait, sem_timedwait); -- cgit v1.2.3 From a2c46ac956613c162b5162d2ef2c725229b08aca Mon Sep 17 00:00:00 2001 From: "Neal H. Walfield" Date: Thu, 12 May 2005 20:55:38 +0000 Subject: libpthread/ 2005-05-12 Neal H. Walfield * include/pthread/pthread.h (pthread_exit): Add noreturn attribute. * sysdeps/generic/bits/condition.h (__PTHREAD_COND_INITIALIZER): Don't create a compound literal. * sysdeps/generic/bits/mutex.h (__PTHREAD_MUTEX_INITIALIZER): Don't create a compound literal. (pthread_mutex_init): Don't assign to *__MUTEX directly. Initialize an intermediate local variable and then copy the result. * sysdeps/generic/bits/rwlock.h (__PTHREAD_RWLOCK_INITIALIZER): Don't create a compound literal. (pthread_rwlock_init): Don't assign to *__RWLOCK directly. Initialize an intermediate local variable and then copy the result. * sysdeps/i386/bits/spin-lock.h (__SPIN_LOCK_INITIALIZER): Don't create a compound literal. * pthread/pt-alloc.c (initialize_pthread): Cast PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER to create a compound literal. * tests/test-1.c (main): Use pthread_mutex_init, not PTHREAD_MUTEX_INIT for mutex initialization * sysdeps/generic/pt-barrier-init.c (pthread_barrier_init): Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-init.c (pthread_cond_init): Include . Remove assert. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Cast PTHREAD_MUTEX_INITIALIZER to create a compound literal. * sysdeps/generic/pt-rwlock-init.c: Include . (_pthread_rwlock_init): Cast __PTHREAD_RWLOCK_INITIALIZER to create a compound literal. Copy ATTR if non-defaults are used. * sysdeps/generic/pt-cond-timedwait.c (__pthread_cond_timedwait_internal): Check that ABSTIME->TV_NSEC is valid. Don't shadow ERR. Don't return before cleaning up. * sysdeps/generic/pt-mutex-timedlock.c (pthread_mutex_timedlock): Move after __pthread_mutex_timedlock_internal. Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedrdlock.c (pthread_rwlock_timedrdlock): Move after. __pthread_rwlock_timedrdlock_internal. (__pthread_rwlock_timedrdlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/pt-rwlock-timedwrlock.c (pthread_rwlock_timedwrlock): Move after __pthread_rwlock_timedwrlock_internal. (__pthread_rwlock_timedwrlock_internal): Check that ABSTIME->TV_NSEC is valid. * sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal): Check that TIMEOUT->TV_NSEC is valid before enqueuing the thread. * sysdeps/generic/pt-rwlock-rdlock.c (__pthread_rwlock_timedrdlock_internal): Fix declaration. * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock): Don't return EDEADLK. POSIX does not allow it. * sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Calculate the relative timeout without overflowing. * sysdeps/mach/hurd/i386/pt-setup.c (stack_setup): Cast THREAD. --- ChangeLog | 72 +++++++++++++++++++++++++++++++-- include/pthread/pthread.h | 4 +- pthread/pt-alloc.c | 4 +- sysdeps/generic/bits/condition.h | 5 +-- sysdeps/generic/bits/mutex.h | 10 ++--- sysdeps/generic/bits/rwlock.h | 8 ++-- sysdeps/generic/pt-barrier-init.c | 16 ++++++-- sysdeps/generic/pt-cond-init.c | 17 ++++++-- sysdeps/generic/pt-cond-timedwait.c | 9 ++--- sysdeps/generic/pt-mutex-init.c | 4 +- sysdeps/generic/pt-mutex-timedlock.c | 19 +++++---- sysdeps/generic/pt-mutex-trylock.c | 5 ++- sysdeps/generic/pt-rwlock-init.c | 18 ++++++++- sysdeps/generic/pt-rwlock-rdlock.c | 4 +- sysdeps/generic/pt-rwlock-timedrdlock.c | 19 +++++---- sysdeps/generic/pt-rwlock-timedwrlock.c | 19 +++++---- sysdeps/generic/sem-timedwait.c | 12 +++--- sysdeps/i386/bits/spin-lock.h | 4 +- sysdeps/mach/hurd/i386/pt-setup.c | 4 +- sysdeps/mach/pt-timedblock.c | 22 ++++++---- tests/test-1.c | 2 +- 21 files changed, 197 insertions(+), 80 deletions(-) (limited to 'sysdeps/generic/sem-timedwait.c') diff --git a/ChangeLog b/ChangeLog index 194b6ff..998ece5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,9 +1,75 @@ 2005-05-12 Neal H. Walfield - * Makefile (SRCS): Add sem-close.c sem-destroy.c sem-getvalue.c - sem-init.c sem-open.c sem-post.c sem-timedwait.c sem-trywait.c + * include/pthread/pthread.h (pthread_exit): Add noreturn + attribute. + + * sysdeps/generic/bits/condition.h (__PTHREAD_COND_INITIALIZER): + Don't create a compound literal. + * sysdeps/generic/bits/mutex.h (__PTHREAD_MUTEX_INITIALIZER): + Don't create a compound literal. + (pthread_mutex_init): Don't assign to *__MUTEX directly. + Initialize an intermediate local variable and then copy the + result. + * sysdeps/generic/bits/rwlock.h (__PTHREAD_RWLOCK_INITIALIZER): + Don't create a compound literal. + (pthread_rwlock_init): Don't assign to *__RWLOCK directly. + Initialize an intermediate local variable and then copy the + result. + * sysdeps/i386/bits/spin-lock.h (__SPIN_LOCK_INITIALIZER): + Don't create a compound literal. + + * pthread/pt-alloc.c (initialize_pthread): Cast + PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER to create a + compound literal. + * tests/test-1.c (main): Use pthread_mutex_init, not + PTHREAD_MUTEX_INIT for mutex initialization + + * sysdeps/generic/pt-barrier-init.c (pthread_barrier_init): Remove + assert. Copy ATTR if non-defaults are used. + * sysdeps/generic/pt-cond-init.c (pthread_cond_init): Include + . Remove assert. Copy ATTR if non-defaults are used. + * sysdeps/generic/pt-mutex-init.c (_pthread_mutex_init): Cast + PTHREAD_MUTEX_INITIALIZER to create a compound literal. + * sysdeps/generic/pt-rwlock-init.c: Include . + (_pthread_rwlock_init): Cast __PTHREAD_RWLOCK_INITIALIZER to + create a compound literal. Copy ATTR if non-defaults are used. + + * sysdeps/generic/pt-cond-timedwait.c + (__pthread_cond_timedwait_internal): Check that ABSTIME->TV_NSEC + is valid. Don't shadow ERR. Don't return before cleaning up. + * sysdeps/generic/pt-mutex-timedlock.c (pthread_mutex_timedlock): + Move after __pthread_mutex_timedlock_internal. Check that + ABSTIME->TV_NSEC is valid. + * sysdeps/generic/pt-rwlock-timedrdlock.c + (pthread_rwlock_timedrdlock): Move after. + __pthread_rwlock_timedrdlock_internal. + (__pthread_rwlock_timedrdlock_internal): Check that + ABSTIME->TV_NSEC is valid. + * sysdeps/generic/pt-rwlock-timedwrlock.c + (pthread_rwlock_timedwrlock): Move after + __pthread_rwlock_timedwrlock_internal. + (__pthread_rwlock_timedwrlock_internal): Check that + ABSTIME->TV_NSEC is valid. + * sysdeps/generic/sem-timedwait.c (__sem_timedwait_internal): + Check that TIMEOUT->TV_NSEC is valid before enqueuing the thread. + + * sysdeps/generic/pt-rwlock-rdlock.c + (__pthread_rwlock_timedrdlock_internal): Fix declaration. + + * sysdeps/generic/pt-mutex-trylock.c (__pthread_mutex_trylock): + Don't return EDEADLK. POSIX does not allow it. + + * sysdeps/mach/pt-timedblock.c (__pthread_timedblock): Calculate + the relative timeout without overflowing. + + * sysdeps/mach/hurd/i386/pt-setup.c (stack_setup): Cast THREAD. + +2005-05-12 Neal H. Walfield + + * Makefile (SRCS): Add sem-close.c, sem-destroy.c, sem-getvalue.c, + sem-init.c, sem-open.c, sem-post.c, sem-timedwait.c, sem-trywait.c, sem-unlink.c and sem-wait.c. - (sysdeps_headers): Add semaphore.h bits/semaphore.h. + (sysdeps_headers): Add semaphore.h and bits/semaphore.h. * include/semaphore.h: New file. * sysdeps/generic/sem-close.c: New file. * sysdeps/generic/sem-destroy.c: New file. diff --git a/include/pthread/pthread.h b/include/pthread/pthread.h index 7e0e7de..3e69cd7 100644 --- a/include/pthread/pthread.h +++ b/include/pthread/pthread.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000,02 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -185,7 +185,7 @@ extern int pthread_create (pthread_t *__threadp, /* Terminate the current thread and make STATUS available to any thread that might join us. */ -extern void pthread_exit (void *__status); +extern void pthread_exit (void *__status) __attribute__ ((noreturn)); /* Make calling thread wait for termination of thread THREAD. Return the exit status of the thread in *STATUS. */ diff --git a/pthread/pt-alloc.c b/pthread/pt-alloc.c index e8d3c03..30dcede 100644 --- a/pthread/pt-alloc.c +++ b/pthread/pt-alloc.c @@ -69,8 +69,8 @@ initialize_pthread (struct __pthread *new, int recycling) new->stack = 0; - new->state_lock = PTHREAD_MUTEX_INITIALIZER; - new->state_cond = PTHREAD_COND_INITIALIZER; + new->state_lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; + new->state_cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER; new->cancelation_handlers = 0; diff --git a/sysdeps/generic/bits/condition.h b/sysdeps/generic/bits/condition.h index cb7e935..f3b09be 100644 --- a/sysdeps/generic/bits/condition.h +++ b/sysdeps/generic/bits/condition.h @@ -1,5 +1,5 @@ /* Condition type. Generic version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,7 +34,6 @@ struct __pthread_cond /* Initializer for a condition variable. */ #define __PTHREAD_COND_INITIALIZER \ - ((struct __pthread_cond) \ - { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL }) + { __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, NULL } #endif /* bits/condition.h */ diff --git a/sysdeps/generic/bits/mutex.h b/sysdeps/generic/bits/mutex.h index 9958b8d..2e32d78 100644 --- a/sysdeps/generic/bits/mutex.h +++ b/sysdeps/generic/bits/mutex.h @@ -1,5 +1,5 @@ /* Mutex type. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -52,9 +52,7 @@ struct __pthread_mutex /* Initializer for a mutex. N.B. this also happens to be compatible with the cthread mutex initializer. */ # define __PTHREAD_MUTEX_INITIALIZER \ - ((struct __pthread_mutex) \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, NULL, NULL, NULL, \ - NULL, 0, 0 }) + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0, 0 } # endif #endif /* Not __pthread_mutex_defined. */ @@ -74,13 +72,15 @@ _EXTERN_INLINE int pthread_mutex_init (struct __pthread_mutex *__mutex, const pthread_mutexattr_t *attr) { + struct __pthread_mutex initialized_mutex = __PTHREAD_MUTEX_INITIALIZER; + extern int _pthread_mutex_init (struct __pthread_mutex *, const pthread_mutexattr_t *); if (attr) return _pthread_mutex_init (__mutex, attr); - *__mutex = __PTHREAD_MUTEX_INITIALIZER; + *__mutex = initialized_mutex; return 0; } diff --git a/sysdeps/generic/bits/rwlock.h b/sysdeps/generic/bits/rwlock.h index d089b0c..5793f65 100644 --- a/sysdeps/generic/bits/rwlock.h +++ b/sysdeps/generic/bits/rwlock.h @@ -1,5 +1,5 @@ /* rwlock type. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -40,21 +40,21 @@ struct __pthread_rwlock /* Initializer for a rwlock. */ #define __PTHREAD_RWLOCK_INITIALIZER \ - ((struct __pthread_rwlock) \ - { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 }) + { __SPIN_LOCK_INITIALIZER, __SPIN_LOCK_INITIALIZER, 0, 0, 0, 0, 0 } _EXTERN_INLINE int pthread_rwlock_init (struct __pthread_rwlock *__rwlock, const struct __pthread_rwlockattr *__attr) { + struct __pthread_rwlock initialized_rwlock = __PTHREAD_RWLOCK_INITIALIZER; extern int _pthread_rwlock_init (struct __pthread_rwlock *, const struct __pthread_rwlockattr *); if (__attr) return _pthread_rwlock_init (__rwlock, __attr); - *__rwlock = __PTHREAD_RWLOCK_INITIALIZER; + *__rwlock = initialized_rwlock; return 0; } diff --git a/sysdeps/generic/pt-barrier-init.c b/sysdeps/generic/pt-barrier-init.c index 57911d5..c42b3bb 100644 --- a/sysdeps/generic/pt-barrier-init.c +++ b/sysdeps/generic/pt-barrier-init.c @@ -1,5 +1,5 @@ /* pthread_barrier_init. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,8 +28,6 @@ pthread_barrier_init (pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned count) { - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); - if (count == 0) return EINVAL; @@ -39,5 +37,17 @@ pthread_barrier_init (pthread_barrier_t *barrier, barrier->pending = count; barrier->count = count; + if (! attr + || memcmp (attr, &__pthread_default_barrierattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + barrier->attr = malloc (sizeof *attr); + if (! barrier->attr) + return ENOMEM; + + *barrier->attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-init.c b/sysdeps/generic/pt-cond-init.c index 4afcc94..b9e9fb7 100644 --- a/sysdeps/generic/pt-cond-init.c +++ b/sysdeps/generic/pt-cond-init.c @@ -19,6 +19,7 @@ #include #include +#include #include @@ -26,9 +27,19 @@ int pthread_cond_init (pthread_cond_t *cond, const pthread_condattr_t *attr) { - if (attr) - assert (attr->pshared == PTHREAD_PROCESS_PRIVATE); + *cond = (pthread_cond_t) __PTHREAD_COND_INITIALIZER; - *cond = __PTHREAD_COND_INITIALIZER; + if (! attr + || memcmp (attr, &__pthread_default_condattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + cond->__attr = malloc (sizeof *attr); + if (! cond->__attr) + return ENOMEM; + + *cond->__attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-cond-timedwait.c b/sysdeps/generic/pt-cond-timedwait.c index 4abeb71..c10bdb3 100644 --- a/sysdeps/generic/pt-cond-timedwait.c +++ b/sysdeps/generic/pt-cond-timedwait.c @@ -1,5 +1,5 @@ /* Wait on a condition. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -58,6 +58,9 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, __pthread_mutex_lock (mutex); } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + struct __pthread *self = _pthread_self (); /* Add ourselves to the list of waiters. */ @@ -74,8 +77,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (abstime) { - error_t err; - err = __pthread_timedblock (self, abstime); if (err) /* We timed out. We may need to disconnect ourself from the @@ -91,8 +92,6 @@ __pthread_cond_timedwait_internal (pthread_cond_t *cond, if (self->prevp) __pthread_dequeue (self); __pthread_spin_unlock (&mutex->__lock); - - return err; } } else diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index 2902f6e..23c9f0d 100644 --- a/sysdeps/generic/pt-mutex-init.c +++ b/sysdeps/generic/pt-mutex-init.c @@ -1,5 +1,5 @@ /* Initialize a mutex. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -28,7 +28,7 @@ int _pthread_mutex_init (pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - *mutex = __PTHREAD_MUTEX_INITIALIZER; + *mutex = (pthread_mutex_t) __PTHREAD_MUTEX_INITIALIZER; if (! attr || memcmp (attr, &__pthread_default_mutexattr, sizeof (*attr) == 0)) diff --git a/sysdeps/generic/pt-mutex-timedlock.c b/sysdeps/generic/pt-mutex-timedlock.c index 3603986..5e222bd 100644 --- a/sysdeps/generic/pt-mutex-timedlock.c +++ b/sysdeps/generic/pt-mutex-timedlock.c @@ -1,5 +1,5 @@ /* Lock a mutex with a timeout. Generic version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -24,13 +24,6 @@ #define LOSE do { * (int *) 0 = 0; } while (1) -int -pthread_mutex_timedlock (struct __pthread_mutex *mutex, - const struct timespec *abstime) -{ - return __pthread_mutex_timedlock_internal (mutex, abstime); -} - /* Try to lock MUTEX, block until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ int @@ -96,6 +89,9 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, } } + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + /* Add ourselves to the queue. */ __pthread_enqueue (&mutex->__queue, self); __pthread_spin_unlock (&mutex->__lock); @@ -146,3 +142,10 @@ __pthread_mutex_timedlock_internal (struct __pthread_mutex *mutex, return 0; } + +int +pthread_mutex_timedlock (struct __pthread_mutex *mutex, + const struct timespec *abstime) +{ + return __pthread_mutex_timedlock_internal (mutex, abstime); +} diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index 9457dda..6fdea1a 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -65,8 +65,9 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) break; case PTHREAD_MUTEX_ERRORCHECK: - if (mutex->owner == self) - err = EDEADLK; + /* We could check if MUTEX->OWNER is SELF, however, POSIX + does not permit pthread_mutex_trylock to return EDEADLK + instead of EBUSY, only pthread_mutex_lock. */ break; case PTHREAD_MUTEX_RECURSIVE: diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c index 8fe8764..d6c8c1a 100644 --- a/sysdeps/generic/pt-rwlock-init.c +++ b/sysdeps/generic/pt-rwlock-init.c @@ -1,5 +1,5 @@ /* Initialize a rwlock. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -18,13 +18,27 @@ Boston, MA 02111-1307, USA. */ #include +#include #include int _pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) { - *rwlock = __PTHREAD_RWLOCK_INITIALIZER; + *rwlock = (pthread_rwlock_t) __PTHREAD_RWLOCK_INITIALIZER; + + if (! attr + || memcmp (attr, &__pthread_default_rwlockattr, sizeof (*attr) == 0)) + /* Use the default attributes. */ + return 0; + + /* Non-default attributes. */ + + rwlock->__attr = malloc (sizeof *attr); + if (! rwlock->__attr) + return ENOMEM; + + *rwlock->__attr = *attr; return 0; } diff --git a/sysdeps/generic/pt-rwlock-rdlock.c b/sysdeps/generic/pt-rwlock-rdlock.c index 22c1120..480cf48 100644 --- a/sysdeps/generic/pt-rwlock-rdlock.c +++ b/sysdeps/generic/pt-rwlock-rdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -21,7 +21,7 @@ #include /* Implemented in pt-rwlock-timedrdlock.c. */ -extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_mutex *mutex, +extern int __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, const struct timespec *abstime); /* Acquire RWLOCK for reading, block if we can't get it. */ diff --git a/sysdeps/generic/pt-rwlock-timedrdlock.c b/sysdeps/generic/pt-rwlock-timedrdlock.c index 85cb946..ba610fa 100644 --- a/sysdeps/generic/pt-rwlock-timedrdlock.c +++ b/sysdeps/generic/pt-rwlock-timedrdlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for reading. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,13 +22,6 @@ #include -int -pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); -} - /* Acquire the rwlock *RWLOCK for reading blocking until *ABSTIME if it is already held. As a GNU extension, if TIMESPEC is NULL then wait forever. */ @@ -66,6 +59,9 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, /* Better be blocked by a writer. */ assert (rwlock->readers == 0); + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourself to the queue. */ @@ -108,3 +104,10 @@ __pthread_rwlock_timedrdlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedrdlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedrdlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/pt-rwlock-timedwrlock.c b/sysdeps/generic/pt-rwlock-timedwrlock.c index edf6413..04eab51 100644 --- a/sysdeps/generic/pt-rwlock-timedwrlock.c +++ b/sysdeps/generic/pt-rwlock-timedwrlock.c @@ -1,5 +1,5 @@ /* Acquire a rwlock for writing. Generic version. - Copyright (C) 2002 Free Software Foundation, Inc. + Copyright (C) 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -22,13 +22,6 @@ #include -int -pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, - const struct timespec *abstime) -{ - return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); -} - /* Acquire RWLOCK for writing blocking until *ABSTIME if we cannot get it. As a special GNU extension, if ABSTIME is NULL then the wait shall not time out. */ @@ -52,6 +45,9 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, /* The lock is busy. */ + if (abstime && (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)) + return EINVAL; + self = _pthread_self (); /* Add ourselves to the queue. */ @@ -90,3 +86,10 @@ __pthread_rwlock_timedwrlock_internal (struct __pthread_rwlock *rwlock, return 0; } + +int +pthread_rwlock_timedwrlock (struct __pthread_rwlock *rwlock, + const struct timespec *abstime) +{ + return __pthread_rwlock_timedwrlock_internal (rwlock, abstime); +} diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c index f3d280b..0c52111 100644 --- a/sysdeps/generic/sem-timedwait.c +++ b/sysdeps/generic/sem-timedwait.c @@ -39,6 +39,12 @@ __sem_timedwait_internal (sem_t *restrict sem, return 0; } + if (timeout && (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000)) + { + errno = EINVAL; + return -1; + } + /* Add ourselves to the queue. */ self = _pthread_self (); @@ -50,12 +56,6 @@ __sem_timedwait_internal (sem_t *restrict sem, { error_t err; - if (timeout->tv_nsec < 0 || timeout->tv_nsec >= 1000000000) - { - errno = EINVAL; - return -1; - } - err = __pthread_timedblock (self, timeout); if (err) /* We timed out. We may need to disconnect ourself from the diff --git a/sysdeps/i386/bits/spin-lock.h b/sysdeps/i386/bits/spin-lock.h index 3176a15..e86bc13 100644 --- a/sysdeps/i386/bits/spin-lock.h +++ b/sysdeps/i386/bits/spin-lock.h @@ -1,5 +1,5 @@ /* Machine-specific definitions for spin locks. i386 version. - Copyright (C) 2000 Free Software Foundation, Inc. + Copyright (C) 2000, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -32,7 +32,7 @@ __BEGIN_DECLS typedef __volatile int __pthread_spinlock_t; /* Initializer for a spin lock object. */ -# define __SPIN_LOCK_INITIALIZER ((__pthread_spinlock_t) 0) +# define __SPIN_LOCK_INITIALIZER (0) #if defined __USE_EXTERN_INLINES || defined _FORCE_INLINES diff --git a/sysdeps/mach/hurd/i386/pt-setup.c b/sysdeps/mach/hurd/i386/pt-setup.c index 9a85584..32ace6a 100644 --- a/sysdeps/mach/hurd/i386/pt-setup.c +++ b/sysdeps/mach/hurd/i386/pt-setup.c @@ -1,5 +1,5 @@ /* Setup thread stack. Hurd/i386 version. - Copyright (C) 2000, 2002 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -58,7 +58,7 @@ stack_setup (struct __pthread *thread, top -= __hurd_threadvar_max; /* Save the self pointer. */ - top[_HURD_THREADVAR_THREAD] = thread; + top[_HURD_THREADVAR_THREAD] = (void *) thread; if (start_routine) { diff --git a/sysdeps/mach/pt-timedblock.c b/sysdeps/mach/pt-timedblock.c index 6324ae7..ddb8bae 100644 --- a/sysdeps/mach/pt-timedblock.c +++ b/sysdeps/mach/pt-timedblock.c @@ -1,5 +1,5 @@ /* Block a thread with a timeout. Mach version. - Copyright (C) 2000,02 Free Software Foundation, Inc. + Copyright (C) 2000, 2002, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -34,7 +34,7 @@ __pthread_timedblock (struct __pthread *thread, { error_t err; mach_msg_header_t msg; - mach_msg_timeout_t ms; + mach_msg_timeout_t timeout; struct timeval now; /* We have an absolute time and now we have to convert it to a @@ -43,15 +43,23 @@ __pthread_timedblock (struct __pthread *thread, err = gettimeofday(&now, NULL); assert (! err); - ms = abstime->tv_sec * 1000 + (abstime->tv_nsec + 999999) / 1000000 - - now.tv_sec * 1000 - (now.tv_usec + 999) / 1000; - - if (ms <= 0) + if (now.tv_sec > abstime->tv_sec + || (now.tv_sec == abstime->tv_sec + && now.tv_usec > ((abstime->tv_nsec + 999) / 1000))) return ETIMEDOUT; + timeout = (abstime->tv_sec - now.tv_sec) * 1000; + + if (((abstime->tv_nsec + 999) / 1000) >= now.tv_usec) + timeout -= (((abstime->tv_nsec + 999) / 1000) - now.tv_usec + 999) / 1000; + else + /* Need to do a carry. */ + timeout -= 1000 + ((abstime->tv_nsec + 999999) / 1000000) + - (now.tv_usec + 999) / 1000; + err = __mach_msg (&msg, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof msg, thread->wakeupmsg.msgh_remote_port, - ms, MACH_PORT_NULL); + timeout, MACH_PORT_NULL); if (err == EMACH_RCV_TIMED_OUT) return ETIMEDOUT; diff --git a/tests/test-1.c b/tests/test-1.c index 86c7c97..318fd6e 100644 --- a/tests/test-1.c +++ b/tests/test-1.c @@ -27,7 +27,7 @@ main (int argc, char **argv) for (i = 0; i < THREADS; i ++) { - mutex[i] = PTHREAD_MUTEX_INITIALIZER; + pthread_mutex_init (&mutex[i], 0); pthread_mutex_lock (&mutex[i]); err = pthread_create (&tid[i], 0, foo, &mutex[i]); if (err) -- cgit v1.2.3 From c9f6661d48de1d24a21093f70031bc9a055a6a33 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sat, 20 Jan 2007 13:07:06 +0000 Subject: 2006-01-20 Samuel Thibault Do not let other libraries (like libX11) override libpthread's pthread_mutex_*, pthread_rwlock_* and sem_* dynamic symbols. * libpthread/sysdeps/generic/pt-mutex-destroy.c (pthread_mutex_destroy): Make the alias strong. * libpthread/sysdeps/generic/pt-mutex-init.c (pthread_mutex_init): Likewise. * libpthread/sysdeps/generic/pt-mutex-lock.c (_pthread_mutex_lock, pthread_mutex_lock): Likewise. * libpthread/sysdeps/generic/pt-mutex-trylock.c (_pthread_mutex_trylock, pthread_mutex_trylock): Likewise. * libpthread/sysdeps/generic/pt-mutex-unlock.c (_pthread_mutex_lock, pthread_mutex_unlock): Likewise. * libpthread/sysdeps/generic/pt-rwlock-destroy.c (pthread_rwlock_destroy): Likewise. * libpthread/sysdeps/generic/pt-rwlock-init.c (pthread_rwlock_init): Likewise. * libpthread/sysdeps/generic/sem-destroy.c (sem_destroy): Likewise. * libpthread/sysdeps/generic/sem-getvalue.c (sem_getvalue): Likewise. * libpthread/sysdeps/generic/sem-init.c (sem_init): Likewise. * libpthread/sysdeps/generic/sem-open.c (sem_open): Likewise. * libpthread/sysdeps/generic/sem-post.c (sem_post): Likewise. * libpthread/sysdeps/generic/sem-timedwait.c (sem_timedwait): Likewise. * libpthread/sysdeps/generic/sem-trywait.c (sem_trywait): Likewise. * libpthread/sysdeps/generic/sem-unlink.c (sem_unlink): Likewise. * libpthread/sysdeps/generic/sem-wait.c (sem_wait): Likewise. --- sysdeps/generic/pt-mutex-destroy.c | 2 +- sysdeps/generic/pt-mutex-init.c | 2 +- sysdeps/generic/pt-mutex-lock.c | 4 ++-- sysdeps/generic/pt-mutex-trylock.c | 4 ++-- sysdeps/generic/pt-mutex-unlock.c | 4 ++-- sysdeps/generic/pt-rwlock-destroy.c | 2 +- sysdeps/generic/pt-rwlock-init.c | 2 +- sysdeps/generic/sem-close.c | 2 +- sysdeps/generic/sem-destroy.c | 2 +- sysdeps/generic/sem-getvalue.c | 2 +- sysdeps/generic/sem-init.c | 2 +- sysdeps/generic/sem-open.c | 2 +- sysdeps/generic/sem-post.c | 2 +- sysdeps/generic/sem-timedwait.c | 2 +- sysdeps/generic/sem-trywait.c | 2 +- sysdeps/generic/sem-unlink.c | 2 +- sysdeps/generic/sem-wait.c | 2 +- 17 files changed, 20 insertions(+), 20 deletions(-) (limited to 'sysdeps/generic/sem-timedwait.c') diff --git a/sysdeps/generic/pt-mutex-destroy.c b/sysdeps/generic/pt-mutex-destroy.c index d9fb59c..72faefe 100644 --- a/sysdeps/generic/pt-mutex-destroy.c +++ b/sysdeps/generic/pt-mutex-destroy.c @@ -32,4 +32,4 @@ _pthread_mutex_destroy (pthread_mutex_t *mutex) return 0; } -weak_alias (_pthread_mutex_destroy, pthread_mutex_destroy); +strong_alias (_pthread_mutex_destroy, pthread_mutex_destroy); diff --git a/sysdeps/generic/pt-mutex-init.c b/sysdeps/generic/pt-mutex-init.c index 23c9f0d..da1781b 100644 --- a/sysdeps/generic/pt-mutex-init.c +++ b/sysdeps/generic/pt-mutex-init.c @@ -45,4 +45,4 @@ _pthread_mutex_init (pthread_mutex_t *mutex, return 0; } -weak_alias (_pthread_mutex_init, pthread_mutex_init); +strong_alias (_pthread_mutex_init, pthread_mutex_init); diff --git a/sysdeps/generic/pt-mutex-lock.c b/sysdeps/generic/pt-mutex-lock.c index 58d3827..60fc55a 100644 --- a/sysdeps/generic/pt-mutex-lock.c +++ b/sysdeps/generic/pt-mutex-lock.c @@ -33,5 +33,5 @@ __pthread_mutex_lock (struct __pthread_mutex *mutex) return __pthread_mutex_timedlock_internal (mutex, 0); } -weak_alias (__pthread_mutex_lock, _pthread_mutex_lock); -weak_alias (__pthread_mutex_lock, pthread_mutex_lock); +strong_alias (__pthread_mutex_lock, _pthread_mutex_lock); +strong_alias (__pthread_mutex_lock, pthread_mutex_lock); diff --git a/sysdeps/generic/pt-mutex-trylock.c b/sysdeps/generic/pt-mutex-trylock.c index 6fdea1a..d56f6e1 100644 --- a/sysdeps/generic/pt-mutex-trylock.c +++ b/sysdeps/generic/pt-mutex-trylock.c @@ -88,5 +88,5 @@ __pthread_mutex_trylock (struct __pthread_mutex *mutex) return err; } -weak_alias (__pthread_mutex_trylock, _pthread_mutex_trylock); -weak_alias (__pthread_mutex_trylock, pthread_mutex_trylock); +strong_alias (__pthread_mutex_trylock, _pthread_mutex_trylock); +strong_alias (__pthread_mutex_trylock, pthread_mutex_trylock); diff --git a/sysdeps/generic/pt-mutex-unlock.c b/sysdeps/generic/pt-mutex-unlock.c index bbbe2b8..2f719d3 100644 --- a/sysdeps/generic/pt-mutex-unlock.c +++ b/sysdeps/generic/pt-mutex-unlock.c @@ -78,5 +78,5 @@ __pthread_mutex_unlock (pthread_mutex_t *mutex) return 0; } -weak_alias (__pthread_mutex_unlock, _pthread_mutex_unlock); -weak_alias (__pthread_mutex_unlock, pthread_mutex_unlock); +strong_alias (__pthread_mutex_unlock, _pthread_mutex_unlock); +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock); diff --git a/sysdeps/generic/pt-rwlock-destroy.c b/sysdeps/generic/pt-rwlock-destroy.c index f63c84d..034d930 100644 --- a/sysdeps/generic/pt-rwlock-destroy.c +++ b/sysdeps/generic/pt-rwlock-destroy.c @@ -26,4 +26,4 @@ _pthread_rwlock_destroy (pthread_rwlock_t *rwlock) return 0; } -weak_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy); +strong_alias (_pthread_rwlock_destroy, pthread_rwlock_destroy); diff --git a/sysdeps/generic/pt-rwlock-init.c b/sysdeps/generic/pt-rwlock-init.c index d6c8c1a..8aa495e 100644 --- a/sysdeps/generic/pt-rwlock-init.c +++ b/sysdeps/generic/pt-rwlock-init.c @@ -42,4 +42,4 @@ _pthread_rwlock_init (pthread_rwlock_t *rwlock, return 0; } -weak_alias (_pthread_rwlock_init, pthread_rwlock_init); +strong_alias (_pthread_rwlock_init, pthread_rwlock_init); diff --git a/sysdeps/generic/sem-close.c b/sysdeps/generic/sem-close.c index b82946b..9f48032 100644 --- a/sysdeps/generic/sem-close.c +++ b/sysdeps/generic/sem-close.c @@ -29,4 +29,4 @@ __sem_close (sem_t *sem) return -1; } -weak_alias (__sem_close, sem_close); +strong_alias (__sem_close, sem_close); diff --git a/sysdeps/generic/sem-destroy.c b/sysdeps/generic/sem-destroy.c index 693b06d..985f4ad 100644 --- a/sysdeps/generic/sem-destroy.c +++ b/sysdeps/generic/sem-destroy.c @@ -35,4 +35,4 @@ __sem_destroy (sem_t *sem) return 0; } -weak_alias (__sem_destroy, sem_destroy); +strong_alias (__sem_destroy, sem_destroy); diff --git a/sysdeps/generic/sem-getvalue.c b/sysdeps/generic/sem-getvalue.c index cb0439c..8e418e3 100644 --- a/sysdeps/generic/sem-getvalue.c +++ b/sysdeps/generic/sem-getvalue.c @@ -30,4 +30,4 @@ __sem_getvalue (sem_t *restrict sem, int *restrict value) return 0; } -weak_alias (__sem_getvalue, sem_getvalue); +strong_alias (__sem_getvalue, sem_getvalue); diff --git a/sysdeps/generic/sem-init.c b/sysdeps/generic/sem-init.c index f516ec9..6c6d79e 100644 --- a/sysdeps/generic/sem-init.c +++ b/sysdeps/generic/sem-init.c @@ -43,4 +43,4 @@ __sem_init (sem_t *sem, int pshared, unsigned value) return 0; } -weak_alias (__sem_init, sem_init); +strong_alias (__sem_init, sem_init); diff --git a/sysdeps/generic/sem-open.c b/sysdeps/generic/sem-open.c index 426cbdb..9eb13aa 100644 --- a/sysdeps/generic/sem-open.c +++ b/sysdeps/generic/sem-open.c @@ -29,4 +29,4 @@ __sem_open (const char *name, int open_flags, ...) return SEM_FAILED; } -weak_alias (__sem_open, sem_open); +strong_alias (__sem_open, sem_open); diff --git a/sysdeps/generic/sem-post.c b/sysdeps/generic/sem-post.c index c283784..0e20ea7 100644 --- a/sysdeps/generic/sem-post.c +++ b/sysdeps/generic/sem-post.c @@ -59,4 +59,4 @@ __sem_post (sem_t *sem) return 0; } -weak_alias (__sem_post, sem_post); +strong_alias (__sem_post, sem_post); diff --git a/sysdeps/generic/sem-timedwait.c b/sysdeps/generic/sem-timedwait.c index 0c52111..d01bfdb 100644 --- a/sysdeps/generic/sem-timedwait.c +++ b/sysdeps/generic/sem-timedwait.c @@ -89,4 +89,4 @@ __sem_timedwait (sem_t *restrict sem, return __sem_timedwait_internal (sem, timeout); } -weak_alias (__sem_timedwait, sem_timedwait); +strong_alias (__sem_timedwait, sem_timedwait); diff --git a/sysdeps/generic/sem-trywait.c b/sysdeps/generic/sem-trywait.c index e47d559..199f317 100644 --- a/sysdeps/generic/sem-trywait.c +++ b/sysdeps/generic/sem-trywait.c @@ -39,4 +39,4 @@ __sem_trywait (sem_t *sem) return -1; } -weak_alias (__sem_trywait, sem_trywait); +strong_alias (__sem_trywait, sem_trywait); diff --git a/sysdeps/generic/sem-unlink.c b/sysdeps/generic/sem-unlink.c index 95b63ed..519f4f7 100644 --- a/sysdeps/generic/sem-unlink.c +++ b/sysdeps/generic/sem-unlink.c @@ -29,4 +29,4 @@ __sem_unlink (const char *name) return -1; } -weak_alias (__sem_unlink, sem_unlink); +strong_alias (__sem_unlink, sem_unlink); diff --git a/sysdeps/generic/sem-wait.c b/sysdeps/generic/sem-wait.c index 46c7baf..50752f3 100644 --- a/sysdeps/generic/sem-wait.c +++ b/sysdeps/generic/sem-wait.c @@ -29,4 +29,4 @@ __sem_wait (sem_t *sem) return __sem_timedwait_internal (sem, 0); } -weak_alias (__sem_wait, sem_wait); +strong_alias (__sem_wait, sem_wait); -- cgit v1.2.3