diff options
| author | ad <ad@NetBSD.org> | 2007-03-24 18:51:59 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2007-03-24 18:51:59 +0000 |
| commit | a5070151ae31367fdb4fd5e62c0bde28d360a085 (patch) | |
| tree | 4e9f2b6f9b7cdc849db9a96afd750c93b64d6956 /lib/libpthread | |
| parent | 8a0e56297d2f90626a6c5af126e38c11406e616d (diff) | |
- Test+branch is usually cheaper than making an indirect function call,
so avoid making them.
- When parking an LWP on a condition variable, point the hint argument at
the mutex's waiters queue. Chances are we will be awoken from that later.
Diffstat (limited to 'lib/libpthread')
| -rw-r--r-- | lib/libpthread/pthread.c | 9 | ||||
| -rw-r--r-- | lib/libpthread/pthread_barrier.c | 7 | ||||
| -rw-r--r-- | lib/libpthread/pthread_cond.c | 8 | ||||
| -rw-r--r-- | lib/libpthread/pthread_int.h | 16 | ||||
| -rw-r--r-- | lib/libpthread/pthread_lock.c | 86 | ||||
| -rw-r--r-- | lib/libpthread/pthread_mutex.c | 6 | ||||
| -rw-r--r-- | lib/libpthread/pthread_rwlock.c | 14 | ||||
| -rw-r--r-- | lib/libpthread/sem.c | 6 |
8 files changed, 63 insertions, 89 deletions
diff --git a/lib/libpthread/pthread.c b/lib/libpthread/pthread.c index f3feab8fb69..5ab952d5333 100644 --- a/lib/libpthread/pthread.c +++ b/lib/libpthread/pthread.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.67 2007/03/14 23:33:42 ad Exp $ */ +/* $NetBSD: pthread.c,v 1.68 2007/03/24 18:51:59 ad Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.67 2007/03/14 23:33:42 ad Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.68 2007/03/24 18:51:59 ad Exp $"); #include <err.h> #include <errno.h> @@ -964,7 +964,8 @@ pthread__errorfunc(const char *file, int line, const char *function, int pthread__park(pthread_t self, pthread_spin_t *lock, struct pthread_queue_t *queue, - const struct timespec *abstime, int cancelpt) + const struct timespec *abstime, int cancelpt, + const void *hint) { int rv; @@ -978,7 +979,7 @@ pthread__park(pthread_t self, pthread_spin_t *lock, rv = 0; do { pthread_spinunlock(self, lock); - if (_lwp_park(abstime, NULL, queue) != 0) { + if (_lwp_park(abstime, NULL, hint) != 0) { switch (rv = errno) { case EINTR: case EALREADY: diff --git a/lib/libpthread/pthread_barrier.c b/lib/libpthread/pthread_barrier.c index 6aacfe2d460..2562339bc20 100644 --- a/lib/libpthread/pthread_barrier.c +++ b/lib/libpthread/pthread_barrier.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_barrier.c,v 1.11 2007/03/05 23:56:17 ad Exp $ */ +/* $NetBSD: pthread_barrier.c,v 1.12 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2001, 2003, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_barrier.c,v 1.11 2007/03/05 23:56:17 ad Exp $"); +__RCSID("$NetBSD: pthread_barrier.c,v 1.12 2007/03/24 18:52:00 ad Exp $"); #include <errno.h> @@ -181,7 +181,8 @@ pthread_barrier_wait(pthread_barrier_t *barrier) self->pt_sleeponq = 1; self->pt_sleepobj = &barrier->ptb_waiters; (void)pthread__park(self, &barrier->ptb_lock, - &barrier->ptb_waiters, NULL, 0); + &barrier->ptb_waiters, NULL, 0, + &barrier->ptb_waiters); SDPRINTF(("(barrier wait %p) Woke up on %p\n", self, barrier)); } diff --git a/lib/libpthread/pthread_cond.c b/lib/libpthread/pthread_cond.c index 1e772f2e8fd..88f17d87cc8 100644 --- a/lib/libpthread/pthread_cond.c +++ b/lib/libpthread/pthread_cond.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_cond.c,v 1.29 2007/03/21 19:08:18 ad Exp $ */ +/* $NetBSD: pthread_cond.c,v 1.30 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_cond.c,v 1.29 2007/03/21 19:08:18 ad Exp $"); +__RCSID("$NetBSD: pthread_cond.c,v 1.30 2007/03/24 18:52:00 ad Exp $"); #include <errno.h> #include <sys/time.h> @@ -135,7 +135,7 @@ pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) self->pt_sleepobj = &cond->ptc_waiters; pthread_mutex_unlock(mutex); (void)pthread__park(self, &cond->ptc_lock, &cond->ptc_waiters, - NULL, 1); + NULL, 1, &mutex->ptm_blocked); if (PTQ_EMPTY(&cond->ptc_waiters)) cond->ptc_mutex = NULL; pthread_spinunlock(self, &cond->ptc_lock); @@ -194,7 +194,7 @@ pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, self->pt_sleepobj = &cond->ptc_waiters; pthread_mutex_unlock(mutex); retval = pthread__park(self, &cond->ptc_lock, &cond->ptc_waiters, - abstime, 1); + abstime, 1, &mutex->ptm_blocked); if (PTQ_EMPTY(&cond->ptc_waiters)) cond->ptc_mutex = NULL; pthread_spinunlock(self, &cond->ptc_lock); diff --git a/lib/libpthread/pthread_int.h b/lib/libpthread/pthread_int.h index d82ee50d4c9..e979e508f6a 100644 --- a/lib/libpthread/pthread_int.h +++ b/lib/libpthread/pthread_int.h @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_int.h,v 1.40 2007/03/20 23:33:10 ad Exp $ */ +/* $NetBSD: pthread_int.h,v 1.41 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2001, 2002, 2003, 2006, 2007 The NetBSD Foundation, Inc. @@ -118,12 +118,6 @@ struct __pthread_st { void* pt_specific[PTHREAD_KEYS_MAX]; }; -struct pthread_lock_ops { - void (*plo_init)(__cpu_simple_lock_t *); - int (*plo_try)(__cpu_simple_lock_t *); - void (*plo_unlock)(__cpu_simple_lock_t *); -}; - /* Thread states */ #define PT_STATE_RUNNING 1 #define PT_STATE_ZOMBIE 5 @@ -186,7 +180,7 @@ void pthread__unpark(pthread_t self, pthread_spin_t *lock, int pthread__park(pthread_t self, pthread_spin_t *lock, struct pthread_queue_t *threadq, const struct timespec *abs_timeout, - int cancelpt); + int cancelpt, const void *hint); int pthread__stackalloc(pthread_t *t); void pthread__initmain(pthread_t *t); @@ -200,9 +194,9 @@ void pthread_spinunlock(pthread_t thread, pthread_spin_t *lock); extern const struct pthread_lock_ops *pthread__lock_ops; -#define pthread__simple_lock_init(alp) (*pthread__lock_ops->plo_init)(alp) -#define pthread__simple_lock_try(alp) (*pthread__lock_ops->plo_try)(alp) -#define pthread__simple_unlock(alp) (*pthread__lock_ops->plo_unlock)(alp) +void pthread__simple_lock_init(__cpu_simple_lock_t *); +int pthread__simple_lock_try(__cpu_simple_lock_t *); +void pthread__simple_unlock(__cpu_simple_lock_t *); #ifndef _getcontext_u int _getcontext_u(ucontext_t *); diff --git a/lib/libpthread/pthread_lock.c b/lib/libpthread/pthread_lock.c index c5b99e82e11..2232e0eb441 100644 --- a/lib/libpthread/pthread_lock.c +++ b/lib/libpthread/pthread_lock.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_lock.c,v 1.19 2007/03/05 23:30:17 ad Exp $ */ +/* $NetBSD: pthread_lock.c,v 1.20 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2001, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_lock.c,v 1.19 2007/03/05 23:30:17 ad Exp $"); +__RCSID("$NetBSD: pthread_lock.c,v 1.20 2007/03/24 18:52:00 ad Exp $"); #include <sys/types.h> #include <sys/lock.h> @@ -64,77 +64,50 @@ __RCSID("$NetBSD: pthread_lock.c,v 1.19 2007/03/05 23:30:17 ad Exp $"); #endif extern int pthread__nspins; +static int pthread__atomic; RAS_DECL(pthread__lock); -static void -pthread__ras_simple_lock_init(__cpu_simple_lock_t *alp) +void +pthread__simple_lock_init(__cpu_simple_lock_t *alp) { + if (pthread__atomic) { + __cpu_simple_lock_init(alp); + return; + } + *alp = __SIMPLELOCK_UNLOCKED; } -static int -pthread__ras_simple_lock_try(__cpu_simple_lock_t *alp) +int +pthread__simple_lock_try(__cpu_simple_lock_t *alp) { __cpu_simple_lock_t old; + if (pthread__atomic) + return __cpu_simple_lock_try(alp); + RAS_START(pthread__lock); old = *alp; *alp = __SIMPLELOCK_LOCKED; RAS_END(pthread__lock); - return (old == __SIMPLELOCK_UNLOCKED); -} - -static void -pthread__ras_simple_unlock(__cpu_simple_lock_t *alp) -{ - - *alp = __SIMPLELOCK_UNLOCKED; -} - -static const struct pthread_lock_ops pthread__lock_ops_ras = { - pthread__ras_simple_lock_init, - pthread__ras_simple_lock_try, - pthread__ras_simple_unlock, -}; - -static void -pthread__atomic_simple_lock_init(__cpu_simple_lock_t *alp) -{ - - __cpu_simple_lock_init(alp); + return old == __SIMPLELOCK_UNLOCKED; } -static int -pthread__atomic_simple_lock_try(__cpu_simple_lock_t *alp) +inline void +pthread__simple_unlock(__cpu_simple_lock_t *alp) { - return (__cpu_simple_lock_try(alp)); -} - -static void -pthread__atomic_simple_unlock(__cpu_simple_lock_t *alp) -{ + if (pthread__atomic) { + __cpu_simple_unlock(alp); + return; + } - __cpu_simple_unlock(alp); + *alp = __SIMPLELOCK_UNLOCKED; } -static const struct pthread_lock_ops pthread__lock_ops_atomic = { - pthread__atomic_simple_lock_init, - pthread__atomic_simple_lock_try, - pthread__atomic_simple_unlock, -}; - -/* - * We default to pointing to the RAS primitives; we might need to use - * locks early, but before main() starts. This is safe, since no other - * threads will be active for the process, so atomicity will not be - * required. - */ -const struct pthread_lock_ops *pthread__lock_ops = &pthread__lock_ops_ras; - /* * Initialize the locking primitives. On uniprocessors, we always * use Restartable Atomic Sequences if they are available. Otherwise, @@ -143,14 +116,17 @@ const struct pthread_lock_ops *pthread__lock_ops = &pthread__lock_ops_ras; void pthread__lockprim_init(int ncpu) { - - if (ncpu == 1 && rasctl(RAS_ADDR(pthread__lock), - RAS_SIZE(pthread__lock), RAS_INSTALL) == 0) { - pthread__lock_ops = &pthread__lock_ops_ras; + + if (ncpu != 1) { + pthread__atomic = 1; return; } - pthread__lock_ops = &pthread__lock_ops_atomic; + if (rasctl(RAS_ADDR(pthread__lock), RAS_SIZE(pthread__lock), + RAS_INSTALL) != 0) { + pthread__atomic = 1; + return; + } } void diff --git a/lib/libpthread/pthread_mutex.c b/lib/libpthread/pthread_mutex.c index 2b89b573d0b..ee1c6304614 100644 --- a/lib/libpthread/pthread_mutex.c +++ b/lib/libpthread/pthread_mutex.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_mutex.c,v 1.27 2007/03/20 23:33:10 ad Exp $ */ +/* $NetBSD: pthread_mutex.c,v 1.28 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2001, 2003, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_mutex.c,v 1.27 2007/03/20 23:33:10 ad Exp $"); +__RCSID("$NetBSD: pthread_mutex.c,v 1.28 2007/03/24 18:52:00 ad Exp $"); #include <errno.h> #include <limits.h> @@ -267,7 +267,7 @@ pthread_mutex_lock_slow(pthread_t self, pthread_mutex_t *mutex) self->pt_sleeponq = 1; self->pt_sleepobj = &mutex->ptm_blocked; (void)pthread__park(self, &mutex->ptm_interlock, - &mutex->ptm_blocked, NULL, 0); + &mutex->ptm_blocked, NULL, 0, &mutex->ptm_blocked); pthread_spinunlock(self, &mutex->ptm_interlock); } else { PTQ_REMOVE(&mutex->ptm_blocked, self, pt_sleep); diff --git a/lib/libpthread/pthread_rwlock.c b/lib/libpthread/pthread_rwlock.c index 87ca3ddf59c..405fceaaaa6 100644 --- a/lib/libpthread/pthread_rwlock.c +++ b/lib/libpthread/pthread_rwlock.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_rwlock.c,v 1.17 2007/03/05 23:56:18 ad Exp $ */ +/* $NetBSD: pthread_rwlock.c,v 1.18 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2002, 2006, 2007 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread_rwlock.c,v 1.17 2007/03/05 23:56:18 ad Exp $"); +__RCSID("$NetBSD: pthread_rwlock.c,v 1.18 2007/03/24 18:52:00 ad Exp $"); #include <errno.h> @@ -118,7 +118,7 @@ pthread_rwlock_rdlock(pthread_rwlock_t *rwlock) self->pt_sleeponq = 1; self->pt_sleepobj = &rwlock->ptr_rblocked; (void)pthread__park(self, &rwlock->ptr_interlock, - &rwlock->ptr_rblocked, NULL, 0); + &rwlock->ptr_rblocked, NULL, 0, &rwlock->ptr_rblocked); } rwlock->ptr_nreaders++; @@ -191,7 +191,7 @@ pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) self->pt_sleeponq = 1; self->pt_sleepobj = &rwlock->ptr_wblocked; (void)pthread__park(self, &rwlock->ptr_interlock, - &rwlock->ptr_wblocked, NULL, 0); + &rwlock->ptr_wblocked, NULL, 0, &rwlock->ptr_wblocked); } rwlock->ptr_writer = self; @@ -272,7 +272,8 @@ pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, self->pt_sleeponq = 1; self->pt_sleepobj = &rwlock->ptr_rblocked; retval = pthread__park(self, &rwlock->ptr_interlock, - &rwlock->ptr_rblocked, abs_timeout, 0); + &rwlock->ptr_rblocked, abs_timeout, 0, + &rwlock->ptr_rblocked); } /* One last chance to get the lock, in case it was released between @@ -333,7 +334,8 @@ pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, self->pt_sleeponq = 1; self->pt_sleepobj = &rwlock->ptr_wblocked; retval = pthread__park(self, &rwlock->ptr_interlock, - &rwlock->ptr_wblocked, abs_timeout, 0); + &rwlock->ptr_wblocked, abs_timeout, 0, + &rwlock->ptr_wblocked); } if ((rwlock->ptr_nreaders == 0) && (rwlock->ptr_writer == NULL)) { diff --git a/lib/libpthread/sem.c b/lib/libpthread/sem.c index 22a1df84348..44fe2940102 100644 --- a/lib/libpthread/sem.c +++ b/lib/libpthread/sem.c @@ -1,4 +1,4 @@ -/* $NetBSD: sem.c,v 1.13 2007/03/05 23:56:44 ad Exp $ */ +/* $NetBSD: sem.c,v 1.14 2007/03/24 18:52:00 ad Exp $ */ /*- * Copyright (c) 2003, 2006, 2007 The NetBSD Foundation, Inc. @@ -66,7 +66,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: sem.c,v 1.13 2007/03/05 23:56:44 ad Exp $"); +__RCSID("$NetBSD: sem.c,v 1.14 2007/03/24 18:52:00 ad Exp $"); #include <sys/types.h> #include <sys/ksem.h> @@ -334,7 +334,7 @@ sem_wait(sem_t *sem) self->pt_sleeponq = 1; self->pt_sleepobj = queue, (void)pthread__park(self, &(*sem)->usem_interlock, - queue, NULL, 1); + queue, NULL, 1, queue); } (*sem)->usem_count--; pthread_spinunlock(self, &(*sem)->usem_interlock); |
