aboutsummaryrefslogtreecommitdiff
path: root/nptl/old_pthread_cond_wait.c
diff options
context:
space:
mode:
Diffstat (limited to 'nptl/old_pthread_cond_wait.c')
-rw-r--r--nptl/old_pthread_cond_wait.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/nptl/old_pthread_cond_wait.c b/nptl/old_pthread_cond_wait.c
index 493f00a3eb..b124b260d4 100644
--- a/nptl/old_pthread_cond_wait.c
+++ b/nptl/old_pthread_cond_wait.c
@@ -20,6 +20,7 @@
#include <errno.h>
#include <stdlib.h>
#include "pthreadP.h"
+#include <atomic.h>
#include <shlib-compat.h>
@@ -31,18 +32,19 @@ __pthread_cond_wait_2_0 (cond, mutex)
{
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_wait (cond->cond, mutex);