From f2ceee99496bf97c1d2ffff9c8e7fd6a79474f2e Mon Sep 17 00:00:00 2001 From: dt Date: Fri, 6 Nov 1998 21:04:02 +0000 Subject: Don't call pthread_mutex_lock with _SPINLOCK held. Made pthread_cond_wait() more similar to pthread_cond_timedwait(). PR: 8375 --- lib/libkse/thread/thr_cond.c | 51 ++++++++++++++++++++++++++------------------ 1 file changed, 30 insertions(+), 21 deletions(-) (limited to 'lib/libkse') diff --git a/lib/libkse/thread/thr_cond.c b/lib/libkse/thread/thr_cond.c index fae12eb..e9b687d 100644 --- a/lib/libkse/thread/thr_cond.c +++ b/lib/libkse/thread/thr_cond.c @@ -144,6 +144,9 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) switch ((*cond)->c_type) { /* Fast condition variable: */ case COND_TYPE_FAST: + /* Wait forever: */ + _thread_run->wakeup_time.tv_sec = -1; + /* * Queue the running thread for the condition * variable: @@ -151,34 +154,39 @@ pthread_cond_wait(pthread_cond_t * cond, pthread_mutex_t * mutex) _thread_queue_enq(&(*cond)->c_queue, _thread_run); /* Unlock the mutex: */ - pthread_mutex_unlock(mutex); - - /* Wait forever: */ - _thread_run->wakeup_time.tv_sec = -1; - - /* Unlock the condition variable structure: */ - _SPINUNLOCK(&(*cond)->lock); + if ((rval = pthread_mutex_unlock(mutex)) != 0) { + /* + * Cannot unlock the mutex, so remove the + * running thread from the condition + * variable queue: + */ + _thread_queue_deq(&(*cond)->c_queue); - /* Schedule the next thread: */ - _thread_kern_sched_state(PS_COND_WAIT, - __FILE__, __LINE__); + /* Unlock the condition variable structure: */ + _SPINUNLOCK(&(*cond)->lock); + } else { + /* Unlock the condition variable structure: */ + _SPINUNLOCK(&(*cond)->lock); - /* Lock the condition variable structure: */ - _SPINLOCK(&(*cond)->lock); + /* Schedule the next thread: */ + _thread_kern_sched_state(PS_COND_WAIT, + __FILE__, __LINE__); - /* Lock the mutex: */ - rval = pthread_mutex_lock(mutex); + /* Lock the mutex: */ + rval = pthread_mutex_lock(mutex); + } break; /* Trap invalid condition variable types: */ default: + /* Unlock the condition variable structure: */ + _SPINUNLOCK(&(*cond)->lock); + /* Return an invalid argument error: */ rval = EINVAL; break; } - /* Unlock the condition variable structure: */ - _SPINUNLOCK(&(*cond)->lock); } /* Return the completion status: */ @@ -229,6 +237,9 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, * variable queue: */ _thread_queue_deq(&(*cond)->c_queue); + + /* Unlock the condition variable structure: */ + _SPINUNLOCK(&(*cond)->lock); } else { /* Unlock the condition variable structure: */ _SPINUNLOCK(&(*cond)->lock); @@ -237,9 +248,6 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, _thread_kern_sched_state(PS_COND_WAIT, __FILE__, __LINE__); - /* Lock the condition variable structure: */ - _SPINLOCK(&(*cond)->lock); - /* Lock the mutex: */ if ((rval = pthread_mutex_lock(mutex)) != 0) { } @@ -253,13 +261,14 @@ pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, /* Trap invalid condition variable types: */ default: + /* Unlock the condition variable structure: */ + _SPINUNLOCK(&(*cond)->lock); + /* Return an invalid argument error: */ rval = EINVAL; break; } - /* Unlock the condition variable structure: */ - _SPINUNLOCK(&(*cond)->lock); } /* Return the completion status: */ -- cgit v1.1