diff options
author | Philip Guenthe <guenther@cvs.openbsd.org> | 2009-11-27 19:45:55 +0000 |
---|---|---|
committer | Philip Guenthe <guenther@cvs.openbsd.org> | 2009-11-27 19:45:55 +0000 |
commit | 1a35791f7ddc3e9de92e3c8c0e0f009aef9276d8 (patch) | |
tree | c9578afeaaa7eb6601fbc5a267fad565b61651d5 /lib/librthread | |
parent | e3f7d63389bbfad1413bfd08d7127f0af07be069 (diff) |
Convert thrsleep() to an absolute timeout with clockid to eliminate a
race condition and prep for later support of pthread_condattr_setclock()
"get it in" deraadt@, tedu@, cheers by others
Diffstat (limited to 'lib/librthread')
-rw-r--r-- | lib/librthread/rthread.c | 4 | ||||
-rw-r--r-- | lib/librthread/rthread.h | 9 | ||||
-rw-r--r-- | lib/librthread/rthread_file.c | 4 | ||||
-rw-r--r-- | lib/librthread/rthread_sync.c | 38 |
4 files changed, 21 insertions, 34 deletions
diff --git a/lib/librthread/rthread.c b/lib/librthread/rthread.c index 8b9a4be6648..9c9f4a6a37f 100644 --- a/lib/librthread/rthread.c +++ b/lib/librthread/rthread.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.c,v 1.41 2009/11/27 19:42:24 guenther Exp $ */ +/* $OpenBSD: rthread.c,v 1.42 2009/11/27 19:45:54 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -253,7 +253,7 @@ pthread_join(pthread_t thread, void **retval) else if (thread->flags & THREAD_DETACHED) e = EINVAL; else { - _sem_wait(&thread->donesem, 0, 0); + _sem_wait(&thread->donesem, 0); if (retval) *retval = thread->retval; e = 0; diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h index 21a8c165365..19af1f12eae 100644 --- a/lib/librthread/rthread.h +++ b/lib/librthread/rthread.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread.h,v 1.24 2009/11/27 19:43:55 guenther Exp $ */ +/* $OpenBSD: rthread.h,v 1.25 2009/11/27 19:45:54 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -141,8 +141,8 @@ extern _spinlock_lock_t _thread_lock; void _spinlock(_spinlock_lock_t *); void _spinunlock(_spinlock_lock_t *); -int _sem_wait(sem_t, int, int); -int _sem_waitl(sem_t, int, int); +int _sem_wait(sem_t, int); +int _sem_waitl(sem_t, int, clockid_t, const struct timespec *); int _sem_post(sem_t); int _sem_wakeup(sem_t); int _sem_wakeall(sem_t); @@ -166,7 +166,8 @@ int _atomic_lock(register volatile _spinlock_lock_t *); /* syscalls */ int getthrid(void); void threxit(pid_t *); -int thrsleep(void *, int, void *); +int thrsleep(const volatile void *, clockid_t, const struct timespec *, + volatile void *); int thrwakeup(void *, int n); int sched_yield(void); int thrsigdivert(sigset_t, siginfo_t *, const struct timespec *); diff --git a/lib/librthread/rthread_file.c b/lib/librthread/rthread_file.c index 673d7ad5d9f..95358514d0f 100644 --- a/lib/librthread/rthread_file.c +++ b/lib/librthread/rthread_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_file.c,v 1.1 2009/10/21 16:05:48 guenther Exp $ */ +/* $OpenBSD: rthread_file.c,v 1.2 2009/11/27 19:45:54 guenther Exp $ */ /* * Copyright (c) 1995 John Birrell <jb@cimlogic.com.au>. * All rights reserved. @@ -206,7 +206,7 @@ void */ TAILQ_INSERT_TAIL(&p->lockers,self,waiting); while (p->owner != self) { - thrsleep(self, 0, &hash_lock); + thrsleep(self, 0, NULL, &hash_lock); _spinlock(&hash_lock); } } diff --git a/lib/librthread/rthread_sync.c b/lib/librthread/rthread_sync.c index a724c854d85..56b35d467dc 100644 --- a/lib/librthread/rthread_sync.c +++ b/lib/librthread/rthread_sync.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rthread_sync.c,v 1.21 2009/11/19 03:31:36 guenther Exp $ */ +/* $OpenBSD: rthread_sync.c,v 1.22 2009/11/27 19:45:54 guenther Exp $ */ /* * Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org> * All Rights Reserved. @@ -43,15 +43,16 @@ static _spinlock_lock_t static_init_lock = _SPINLOCK_UNLOCKED; * Internal implementation of semaphores */ int -_sem_wait(sem_t sem, int tryonly, int timo) +_sem_wait(sem_t sem, int tryonly) { _spinlock(&sem->lock); - return (_sem_waitl(sem, tryonly, timo)); + return (_sem_waitl(sem, tryonly, 0, NULL)); } int -_sem_waitl(sem_t sem, int tryonly, int timo) +_sem_waitl(sem_t sem, int tryonly, clockid_t clock_id, + const struct timespec *abstime) { int do_sleep; @@ -69,7 +70,7 @@ again: } if (do_sleep) { - if (thrsleep(sem, timo, &sem->lock) == -1 && + if (thrsleep(sem, clock_id, abstime, &sem->lock) == -1 && errno == EWOULDBLOCK) return (0); _spinlock(&sem->lock); @@ -193,7 +194,7 @@ sem_wait(sem_t *semp) { sem_t sem = *semp; - _sem_wait(sem, 0, 0); + _sem_wait(sem, 0); return (0); } @@ -204,7 +205,7 @@ sem_trywait(sem_t *semp) sem_t sem = *semp; int rv; - rv = _sem_wait(sem, 1, 0); + rv = _sem_wait(sem, 1); if (!rv) { errno = EAGAIN; @@ -278,7 +279,7 @@ _rthread_mutex_lock(pthread_mutex_t *mutexp, int trywait) if (mutex->type == PTHREAD_MUTEX_ERRORCHECK) return (EDEADLK); } - if (!_sem_wait((void *)&mutex->sem, trywait, 0)) + if (!_sem_wait((void *)&mutex->sem, trywait)) return (EBUSY); mutex->owner = thread; mutex->count = 1; @@ -391,29 +392,14 @@ pthread_cond_timedwait(pthread_cond_t *condp, pthread_mutex_t *mutexp, { int error; int rv; - int timo = 0; - struct timeval timenow; - struct timespec tmspec; if (!*condp) if ((error = pthread_cond_init(condp, NULL))) return (error); - if (abstime && gettimeofday(&timenow, NULL) == 0) { - TIMEVAL_TO_TIMESPEC(&timenow, &tmspec); - if (timespeccmp(abstime, &tmspec, <)) { - pthread_mutex_unlock(mutexp); - error = pthread_mutex_lock(mutexp); - return (error ? error : ETIMEDOUT); - } - timespecsub(abstime, &tmspec, &tmspec); - timo = tmspec.tv_sec * 1000 + tmspec.tv_nsec / 1000000; - } - - _spinlock(&(*condp)->sem.lock); pthread_mutex_unlock(mutexp); - rv = _sem_waitl(&(*condp)->sem, 0, timo); + rv = _sem_waitl(&(*condp)->sem, 0, CLOCK_REALTIME, abstime); error = pthread_mutex_lock(mutexp); return (error ? error : rv ? 0 : ETIMEDOUT); @@ -542,7 +528,7 @@ again: _spinlock(&lock->lock); if (lock->writer) { _spinunlock(&lock->lock); - _sem_wait(&lock->sem, 0, 0); + _sem_wait(&lock->sem, 0); goto again; } lock->readers++; @@ -588,7 +574,7 @@ pthread_rwlock_wrlock(pthread_rwlock_t *lockp) lock->writer++; while (lock->readers) { _spinunlock(&lock->lock); - _sem_wait(&lock->sem, 0, 0); + _sem_wait(&lock->sem, 0); _spinlock(&lock->lock); } lock->readers = -pthread_self()->tid; |