summaryrefslogtreecommitdiffstats
path: root/lib/libc_r/uthread/uthread_cond.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc_r/uthread/uthread_cond.c')
-rw-r--r--lib/libc_r/uthread/uthread_cond.c133
1 files changed, 68 insertions, 65 deletions
diff --git a/lib/libc_r/uthread/uthread_cond.c b/lib/libc_r/uthread/uthread_cond.c
index e7fcc62..cb08853 100644
--- a/lib/libc_r/uthread/uthread_cond.c
+++ b/lib/libc_r/uthread/uthread_cond.c
@@ -43,9 +43,9 @@ pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
pthread_cond_t pcond;
int rval = 0;
- if (cond == NULL) {
+ if (cond == NULL)
rval = EINVAL;
- } else {
+ else {
/*
* Check if a pointer to a condition variable attribute
* structure was passed by the caller:
@@ -85,6 +85,7 @@ pthread_cond_init(pthread_cond_t * cond, const pthread_condattr_t * cond_attr)
_thread_queue_init(&pcond->c_queue);
pcond->c_flags |= COND_FLAGS_INITED;
pcond->c_type = type;
+ pcond->access_lock = 0;
*cond = pcond;
}
}
@@ -98,31 +99,23 @@ pthread_cond_destroy(pthread_cond_t * cond)
{
int rval = 0;
- if (cond == NULL || *cond == NULL) {
+ if (cond == NULL || *cond == NULL)
rval = EINVAL;
- } else {
- /* Process according to condition variable type: */
- switch ((*cond)->c_type) {
- /* Fast condition variable: */
- case COND_TYPE_FAST:
- /* Nothing to do here. */
- break;
+ else {
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
- /* Trap invalid condition variable types: */
- default:
- /* Return an invalid argument error: */
- rval = EINVAL;
- break;
- }
+ /*
+ * Free the memory allocated for the condition
+ * variable structure:
+ */
+ free(*cond);
- /* Check for errors: */
- if (rval == 0) {
- /* Destroy the contents of the condition structure: */
- _thread_queue_init(&(*cond)->c_queue);
- (*cond)->c_flags = 0;
- free(*cond);
- *cond = NULL;
- }
+ /*
+ * NULL the caller's pointer now that the condition
+ * variable has been destroyed:
+ */
+ *cond = NULL;
}
/* Return the completion status: */
return (rval);
@@ -143,8 +136,8 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
*/
else if (*cond != NULL ||
(rval = pthread_cond_init(cond,NULL)) == 0) {
- /* Block signals: */
- _thread_kern_sig_block(&status);
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
/* Process according to condition variable type: */
switch ((*cond)->c_type) {
@@ -162,12 +155,15 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
/* Wait forever: */
_thread_run->wakeup_time.tv_sec = -1;
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
+
/* Schedule the next thread: */
_thread_kern_sched_state(PS_COND_WAIT,
__FILE__, __LINE__);
- /* Block signals: */
- _thread_kern_sig_block(NULL);
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
/* Lock the mutex: */
rval = pthread_mutex_lock(mutex);
@@ -180,8 +176,8 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex)
break;
}
- /* Unblock signals: */
- _thread_kern_sig_unblock(status);
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
}
/* Return the completion status: */
@@ -204,8 +200,8 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
*/
else if (*cond != NULL ||
(rval = pthread_cond_init(cond,NULL)) == 0) {
- /* Block signals: */
- _thread_kern_sig_block(&status);
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
/* Process according to condition variable type: */
switch ((*cond)->c_type) {
@@ -233,12 +229,15 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
*/
_thread_queue_deq(&(*cond)->c_queue);
} else {
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
+
/* Schedule the next thread: */
_thread_kern_sched_state(PS_COND_WAIT,
__FILE__, __LINE__);
- /* Block signals: */
- _thread_kern_sig_block(NULL);
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
/* Lock the mutex: */
if ((rval = pthread_mutex_lock(mutex)) != 0) {
@@ -258,8 +257,8 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
break;
}
- /* Unblock signals: */
- _thread_kern_sig_unblock(status);
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
}
/* Return the completion status: */
@@ -273,11 +272,11 @@ pthread_cond_signal(pthread_cond_t * cond)
int status;
pthread_t pthread;
- if (cond == NULL || *cond == NULL) {
+ if (cond == NULL || *cond == NULL)
rval = EINVAL;
- } else {
- /* Block signals: */
- _thread_kern_sig_block(&status);
+ else {
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
/* Process according to condition variable type: */
switch ((*cond)->c_type) {
@@ -297,8 +296,8 @@ pthread_cond_signal(pthread_cond_t * cond)
break;
}
- /* Unblock signals: */
- _thread_kern_sig_unblock(status);
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
}
/* Return the completion status: */
@@ -312,34 +311,38 @@ pthread_cond_broadcast(pthread_cond_t * cond)
int status;
pthread_t pthread;
- /* Block signals: */
- _thread_kern_sig_block(&status);
+ if (cond == NULL || *cond == NULL)
+ rval = EINVAL;
+ else {
+ /* Lock the condition variable structure: */
+ _spinlock(&(*cond)->access_lock);
- /* Process according to condition variable type: */
- switch ((*cond)->c_type) {
- /* Fast condition variable: */
- case COND_TYPE_FAST:
- /*
- * Enter a loop to bring all threads off the
- * condition queue:
- */
- while ((pthread =
- _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
- /* Allow the thread to run: */
- PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ /* Process according to condition variable type: */
+ switch ((*cond)->c_type) {
+ /* Fast condition variable: */
+ case COND_TYPE_FAST:
+ /*
+ * Enter a loop to bring all threads off the
+ * condition queue:
+ */
+ while ((pthread =
+ _thread_queue_deq(&(*cond)->c_queue)) != NULL) {
+ /* Allow the thread to run: */
+ PTHREAD_NEW_STATE(pthread,PS_RUNNING);
+ }
+ break;
+
+ /* Trap invalid condition variable types: */
+ default:
+ /* Return an invalid argument error: */
+ rval = EINVAL;
+ break;
}
- break;
- /* Trap invalid condition variable types: */
- default:
- /* Return an invalid argument error: */
- rval = EINVAL;
- break;
+ /* Unlock the condition variable structure: */
+ _atomic_unlock(&(*cond)->access_lock);
}
- /* Unblock signals: */
- _thread_kern_sig_unblock(status);
-
/* Return the completion status: */
return (rval);
}
OpenPOWER on IntegriCloud