summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2006-02-23 21:34:08 +0000
committerdeischen <deischen@FreeBSD.org>2006-02-23 21:34:08 +0000
commit4dd473489ef973f5d3a1b52dd87370ef00097810 (patch)
tree8d8078ef7abffc1a5ffc129a3fdf7c191a662be1 /lib/libpthread/thread
parent2460d0002143524f8e136a911d7eece91b451d90 (diff)
downloadFreeBSD-src-4dd473489ef973f5d3a1b52dd87370ef00097810.zip
FreeBSD-src-4dd473489ef973f5d3a1b52dd87370ef00097810.tar.gz
Eliminate a race condition in timed waits (cv, mutex, and sleeps).
MFC Candidate. PR: 93592
Diffstat (limited to 'lib/libpthread/thread')
-rw-r--r--lib/libpthread/thread/thr_cond.c10
-rw-r--r--lib/libpthread/thread/thr_mutex.c46
-rw-r--r--lib/libpthread/thread/thr_nanosleep.c4
3 files changed, 30 insertions, 30 deletions
diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c
index cd719d4..a50a690 100644
--- a/lib/libpthread/thread/thr_cond.c
+++ b/lib/libpthread/thread/thr_cond.c
@@ -421,11 +421,6 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
/* Return invalid argument error: */
rval = EINVAL;
} else {
- /* Set the wakeup time: */
- curthread->wakeup_time.tv_sec = abstime->tv_sec;
- curthread->wakeup_time.tv_nsec =
- abstime->tv_nsec;
-
/* Reset the timeout and interrupted flags: */
curthread->timeout = 0;
curthread->interrupted = 0;
@@ -464,6 +459,11 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex,
* set the state.
*/
THR_SCHED_LOCK(curthread, curthread);
+ /* Set the wakeup time: */
+ curthread->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ curthread->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
THR_SET_STATE(curthread, PS_COND_WAIT);
/* Remember the CV: */
diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c
index e095ac5..0f56069 100644
--- a/lib/libpthread/thread/thr_mutex.c
+++ b/lib/libpthread/thread/thr_mutex.c
@@ -551,14 +551,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
/* Unlock the mutex structure: */
THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
} else {
- /* Set the wakeup time: */
- if (abstime) {
- curthread->wakeup_time.tv_sec =
- abstime->tv_sec;
- curthread->wakeup_time.tv_nsec =
- abstime->tv_nsec;
- }
-
/*
* Join the queue of threads waiting to lock
* the mutex and save a pointer to the mutex.
@@ -572,6 +564,14 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
* be able to safely set the state.
*/
THR_SCHED_LOCK(curthread, curthread);
+ /* Set the wakeup time: */
+ if (abstime) {
+ curthread->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ curthread->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+ }
+
THR_SET_STATE(curthread, PS_MUTEX_WAIT);
THR_SCHED_UNLOCK(curthread, curthread);
@@ -633,14 +633,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
/* Unlock the mutex structure: */
THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
} else {
- /* Set the wakeup time: */
- if (abstime) {
- curthread->wakeup_time.tv_sec =
- abstime->tv_sec;
- curthread->wakeup_time.tv_nsec =
- abstime->tv_nsec;
- }
-
/*
* Join the queue of threads waiting to lock
* the mutex and save a pointer to the mutex.
@@ -659,6 +651,13 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
mutex_priority_adjust(curthread, *m);
THR_SCHED_LOCK(curthread, curthread);
+ /* Set the wakeup time: */
+ if (abstime) {
+ curthread->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ curthread->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+ }
THR_SET_STATE(curthread, PS_MUTEX_WAIT);
THR_SCHED_UNLOCK(curthread, curthread);
@@ -730,14 +729,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
/* Unlock the mutex structure: */
THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
} else {
- /* Set the wakeup time: */
- if (abstime) {
- curthread->wakeup_time.tv_sec =
- abstime->tv_sec;
- curthread->wakeup_time.tv_nsec =
- abstime->tv_nsec;
- }
-
/*
* Join the queue of threads waiting to lock
* the mutex and save a pointer to the mutex.
@@ -756,6 +747,13 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
*/
THR_SCHED_LOCK(curthread, curthread);
+ /* Set the wakeup time: */
+ if (abstime) {
+ curthread->wakeup_time.tv_sec =
+ abstime->tv_sec;
+ curthread->wakeup_time.tv_nsec =
+ abstime->tv_nsec;
+ }
THR_SET_STATE(curthread, PS_MUTEX_WAIT);
THR_SCHED_UNLOCK(curthread, curthread);
diff --git a/lib/libpthread/thread/thr_nanosleep.c b/lib/libpthread/thread/thr_nanosleep.c
index e8baa84..5eba37d 100644
--- a/lib/libpthread/thread/thr_nanosleep.c
+++ b/lib/libpthread/thread/thr_nanosleep.c
@@ -46,6 +46,7 @@ _nanosleep(const struct timespec *time_to_sleep,
int ret = 0;
struct timespec ts, ts1;
struct timespec remaining_time;
+ struct timespec wakeup_time;
/* Check if the time to sleep is legal: */
if ((time_to_sleep == NULL) || (time_to_sleep->tv_sec < 0) ||
@@ -61,10 +62,11 @@ _nanosleep(const struct timespec *time_to_sleep,
KSE_GET_TOD(curthread->kse, &ts);
/* Calculate the time for the current thread to wake up: */
- TIMESPEC_ADD(&curthread->wakeup_time, &ts, time_to_sleep);
+ TIMESPEC_ADD(&wakeup_time, &ts, time_to_sleep);
THR_LOCK_SWITCH(curthread);
curthread->interrupted = 0;
+ curthread->wakeup_time = wakeup_time;
THR_SET_STATE(curthread, PS_SLEEP_WAIT);
/* Reschedule the current thread to sleep: */
OpenPOWER on IntegriCloud