summaryrefslogtreecommitdiffstats
path: root/lib/libkse
diff options
context:
space:
mode:
authordt <dt@FreeBSD.org>1998-11-06 21:04:02 +0000
committerdt <dt@FreeBSD.org>1998-11-06 21:04:02 +0000
commitf2ceee99496bf97c1d2ffff9c8e7fd6a79474f2e (patch)
tree6ebb72631905f7babbc2c4322668d6e1046751e0 /lib/libkse
parent815c9a8514a77f11624b9867601c27e08feb846a (diff)
downloadFreeBSD-src-f2ceee99496bf97c1d2ffff9c8e7fd6a79474f2e.zip
FreeBSD-src-f2ceee99496bf97c1d2ffff9c8e7fd6a79474f2e.tar.gz
Don't call pthread_mutex_lock with _SPINLOCK held.
Made pthread_cond_wait() more similar to pthread_cond_timedwait(). PR: 8375
Diffstat (limited to 'lib/libkse')
-rw-r--r--lib/libkse/thread/thr_cond.c51
1 files changed, 30 insertions, 21 deletions
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: */
OpenPOWER on IntegriCloud