summaryrefslogtreecommitdiff
path: root/lib/libpthread
diff options
context:
space:
mode:
authorad <ad@NetBSD.org>2007-03-24 18:51:59 +0000
committerad <ad@NetBSD.org>2007-03-24 18:51:59 +0000
commita5070151ae31367fdb4fd5e62c0bde28d360a085 (patch)
tree4e9f2b6f9b7cdc849db9a96afd750c93b64d6956 /lib/libpthread
parent8a0e56297d2f90626a6c5af126e38c11406e616d (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.c9
-rw-r--r--lib/libpthread/pthread_barrier.c7
-rw-r--r--lib/libpthread/pthread_cond.c8
-rw-r--r--lib/libpthread/pthread_int.h16
-rw-r--r--lib/libpthread/pthread_lock.c86
-rw-r--r--lib/libpthread/pthread_mutex.c6
-rw-r--r--lib/libpthread/pthread_rwlock.c14
-rw-r--r--lib/libpthread/sem.c6
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);