diff options
| author | ad <ad@NetBSD.org> | 2007-08-04 13:37:48 +0000 |
|---|---|---|
| committer | ad <ad@NetBSD.org> | 2007-08-04 13:37:48 +0000 |
| commit | 50fa8db4e44b07accbfd5f2821987476be3bf05c (patch) | |
| tree | 04cfc58059fb658923f9a7b24583dd0b3e4437d1 /lib/libpthread/pthread_lock.c | |
| parent | b108f67c054e0f87f9b653c4d194652a4bfc40cc (diff) | |
Some significant performance improvements, and a fix for a race with pthread
detach/join.
- Make mutex acquire spin for a short time, as done with spinlocks.
- Make the number of spins controllable with the env var PTHREAD_NSPINS.
- Reduce the amount of time that libpthread internal spinlocks are held.
- Rely more on the barrier effects of park/unpark to avoid taking spinlocks.
- Simplify the locking around pthreads and the global queues.
- Align per-thread sync data on a 128 byte boundary.
- Offset thread stacks by a small amount to try and reduce cache thrash.
Diffstat (limited to 'lib/libpthread/pthread_lock.c')
| -rw-r--r-- | lib/libpthread/pthread_lock.c | 31 |
1 files changed, 11 insertions, 20 deletions
diff --git a/lib/libpthread/pthread_lock.c b/lib/libpthread/pthread_lock.c index 2232e0eb441..c5d4b91a8aa 100644 --- a/lib/libpthread/pthread_lock.c +++ b/lib/libpthread/pthread_lock.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_lock.c,v 1.20 2007/03/24 18:52:00 ad Exp $ */ +/* $NetBSD: pthread_lock.c,v 1.21 2007/08/04 13:37:49 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.20 2007/03/24 18:52:00 ad Exp $"); +__RCSID("$NetBSD: pthread_lock.c,v 1.21 2007/08/04 13:37:49 ad Exp $"); #include <sys/types.h> #include <sys/lock.h> @@ -56,14 +56,6 @@ __RCSID("$NetBSD: pthread_lock.c,v 1.20 2007/03/24 18:52:00 ad Exp $"); #define SDPRINTF(x) #endif -/* This does not belong here. */ -#if defined(i386) || defined(__x86_64__) -#define smt_pause() __asm __volatile("rep; nop" ::: "memory") -#else -#define smt_pause() /* nothing */ -#endif - -extern int pthread__nspins; static int pthread__atomic; RAS_DECL(pthread__lock); @@ -139,9 +131,8 @@ pthread_lockinit(pthread_spin_t *lock) void pthread_spinlock(pthread_t thread, pthread_spin_t *lock) { - int count, ret; + int count; - count = pthread__nspins; SDPRINTF(("(pthread_spinlock %p) spinlock %p (count %d)\n", thread, lock, thread->pt_spinlocks)); #ifdef PTHREAD_SPIN_DEBUG @@ -155,14 +146,15 @@ pthread_spinlock(pthread_t thread, pthread_spin_t *lock) } do { - while ((ret = pthread__simple_lock_try(lock)) == 0 && - --count) { - smt_pause(); + count = pthread__nspins; + while (*lock == __SIMPLELOCK_LOCKED && --count > 0) + pthread__smt_pause(); + if (count > 0) { + if (pthread__simple_lock_try(lock)) + break; + continue; } - if (ret == 1) - break; - SDPRINTF(("(pthread_spinlock %p) retrying spinlock %p " "(count %d)\n", thread, lock, thread->pt_spinlocks)); @@ -170,7 +162,6 @@ pthread_spinlock(pthread_t thread, pthread_spin_t *lock) /* XXXLWP far from ideal */ sched_yield(); - count = pthread__nspins; thread->pt_spinlocks++; } while (/*CONSTCOND*/ 1); @@ -260,7 +251,7 @@ pthread_spin_lock(pthread_spinlock_t *lock) #endif while (pthread__simple_lock_try(&lock->pts_spin) == 0) { - smt_pause(); + pthread__smt_pause(); } return 0; |
