diff options
Diffstat (limited to 'nptl/old_pthread_cond_timedwait.c')
-rw-r--r-- | nptl/old_pthread_cond_timedwait.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/nptl/old_pthread_cond_timedwait.c b/nptl/old_pthread_cond_timedwait.c index 7b0faa78d2..ef4db9e6e8 100644 --- a/nptl/old_pthread_cond_timedwait.c +++ b/nptl/old_pthread_cond_timedwait.c @@ -20,6 +20,7 @@ #include <errno.h> #include <stdlib.h> #include "pthreadP.h" +#include <atomic.h> #include <shlib-compat.h> @@ -32,18 +33,19 @@ __pthread_cond_timedwait_2_0 (cond, mutex, abstime) { if (cond->cond == NULL) { - lll_mutex_lock (cond->lock); + pthread_cond_t *newcond; - /* Check whether the condvar is still not allocated. */ - if (cond->cond == NULL) - cond->cond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + newcond = (pthread_cond_t *) malloc (sizeof (pthread_cond_t)); + if (newcond == NULL) + return ENOMEM; - lll_mutex_unlock (cond->lock); + *newcond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; - if (cond->cond == NULL) - return ENOMEM; + atomic_write_barrier (); - *cond->cond = (struct pthread_cond_t) PTHREAD_COND_INITIALIZER; + if (atomic_compare_and_exchange_acq (&cond->cond, newcond, NULL) != 0) + /* Somebody else just initialized the condvar. */ + free (newcond); } return __pthread_cond_timedwait (cond->cond, mutex, abstime); |