diff --git a/include/pthread.h b/include/pthread.h index 191bbf4e8bf15..39972b91912a4 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -269,7 +269,8 @@ struct pthread_cond_s { sem_t sem; clockid_t clockid; - uint16_t wait_count; + unsigned int wait_count; + mutex_t mutex; }; #ifndef __PTHREAD_COND_T_DEFINED diff --git a/libs/libc/pthread/pthread_conddestroy.c b/libs/libc/pthread/pthread_conddestroy.c index e127729a327da..d754eb14ece89 100644 --- a/libs/libc/pthread/pthread_conddestroy.c +++ b/libs/libc/pthread/pthread_conddestroy.c @@ -74,16 +74,17 @@ int pthread_cond_destroy(FAR pthread_cond_t *cond) { ret = get_errno(); } + else if (sval < 0) + { + ret = EBUSY; + } + else if (sem_destroy(&cond->sem) != OK) + { + ret = get_errno(); + } else { - if (sval < 0) - { - ret = EBUSY; - } - else if (sem_destroy(&cond->sem) != OK) - { - ret = get_errno(); - } + nxmutex_destroy(&cond->mutex); } } diff --git a/libs/libc/pthread/pthread_condinit.c b/libs/libc/pthread/pthread_condinit.c index c174f98bb6e5e..f25cee885a3e5 100644 --- a/libs/libc/pthread/pthread_condinit.c +++ b/libs/libc/pthread/pthread_condinit.c @@ -75,6 +75,7 @@ int pthread_cond_init(FAR pthread_cond_t *cond, { cond->clockid = attr ? attr->clockid : CLOCK_REALTIME; cond->wait_count = 0; + nxmutex_init(&cond->mutex); } sinfo("Returning %d\n", ret); diff --git a/sched/pthread/pthread_condbroadcast.c b/sched/pthread/pthread_condbroadcast.c index 581666548710f..254f02e334b3e 100644 --- a/sched/pthread/pthread_condbroadcast.c +++ b/sched/pthread/pthread_condbroadcast.c @@ -42,10 +42,7 @@ * * Description: * A thread broadcast on a condition variable. - * pthread_cond_broadcast shall unblock all threads currently blocked on a - * specified condition variable cond. We need own the mutex that threads - * calling pthread_cond_wait or pthread_cond_timedwait have associated - * with the condition variable during their wait. + * * Input Parameters: * None * @@ -68,9 +65,11 @@ int pthread_cond_broadcast(FAR pthread_cond_t *cond) } else { + nxmutex_lock(&cond->mutex); + /* Loop until all of the waiting threads have been restarted. */ - while (cond->wait_count > 0) + while (atomic_read(&cond->wait_count) > 0) { /* If the value is less than zero (meaning that one or more * thread is waiting), then post the condition semaphore. @@ -83,8 +82,10 @@ int pthread_cond_broadcast(FAR pthread_cond_t *cond) * above post). */ - cond->wait_count--; + atomic_fetch_sub(&cond->wait_count, 1); } + + nxmutex_unlock(&cond->mutex); } sinfo("Returning %d\n", ret); diff --git a/sched/pthread/pthread_condclockwait.c b/sched/pthread/pthread_condclockwait.c index 77a62101f9adc..ab5e7e9435078 100644 --- a/sched/pthread/pthread_condclockwait.c +++ b/sched/pthread/pthread_condclockwait.c @@ -113,7 +113,7 @@ int pthread_cond_clockwait(FAR pthread_cond_t *cond, sinfo("Give up mutex...\n"); - cond->wait_count++; + atomic_fetch_add(&cond->wait_count, 1); /* Give up the mutex */ diff --git a/sched/pthread/pthread_condsignal.c b/sched/pthread/pthread_condsignal.c index 4e9055f773d97..1ff6aa9e97fc9 100644 --- a/sched/pthread/pthread_condsignal.c +++ b/sched/pthread/pthread_condsignal.c @@ -41,10 +41,6 @@ * * Description: * A thread can signal on a condition variable. - * pthread_cond_signal shall unblock a thread currently blocked on a - * specified condition variable cond. We need own the mutex that threads - * calling pthread_cond_wait or pthread_cond_timedwait have associated - * with the condition variable during their wait. * * Input Parameters: * None @@ -68,12 +64,16 @@ int pthread_cond_signal(FAR pthread_cond_t *cond) } else { - if (cond->wait_count > 0) + nxmutex_lock(&cond->mutex); + + if (atomic_read(&cond->wait_count) > 0) { sinfo("Signalling...\n"); - cond->wait_count--; + atomic_fetch_sub(&cond->wait_count, 1); ret = -nxsem_post(&cond->sem); } + + nxmutex_unlock(&cond->mutex); } sinfo("Returning %d\n", ret); diff --git a/sched/pthread/pthread_condwait.c b/sched/pthread/pthread_condwait.c index ca8f05511e407..4296b16c72f73 100644 --- a/sched/pthread/pthread_condwait.c +++ b/sched/pthread/pthread_condwait.c @@ -88,7 +88,7 @@ int pthread_cond_wait(FAR pthread_cond_t *cond, FAR pthread_mutex_t *mutex) sinfo("Give up mutex / take cond\n"); - cond->wait_count++; + atomic_fetch_add(&cond->wait_count, 1); ret = pthread_mutex_breaklock(mutex, &nlocks); status = -nxsem_wait_uninterruptible(&cond->sem);