diff options
| author | cl <cl@NetBSD.org> | 2004-03-14 01:19:41 +0000 |
|---|---|---|
| committer | cl <cl@NetBSD.org> | 2004-03-14 01:19:41 +0000 |
| commit | f2f106648cb994804efdc8a9f457a642815d8272 (patch) | |
| tree | 10126518767faefa83c91ddc96be71ebe9be015c /lib/libpthread/pthread.c | |
| parent | ea5ec0212d715373eb56dbdeb218b9504e1139f2 (diff) | |
add libpthread part of concurrency support for SA on MP systems
- enable concurrency according to environment variable PTHREAD_CONCURRENCY
- add idle VP wakeup if there are additional jobs and idle VPs
- make reidlequeue per VP
- enable spinning for locks
- fix race condition in alarm processing
- fix race condition in mutex locking
- make debugging output line buffered and add VP prefix to debug lines
Diffstat (limited to 'lib/libpthread/pthread.c')
| -rw-r--r-- | lib/libpthread/pthread.c | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/lib/libpthread/pthread.c b/lib/libpthread/pthread.c index f7b099e7689..7ac579dcd35 100644 --- a/lib/libpthread/pthread.c +++ b/lib/libpthread/pthread.c @@ -1,4 +1,4 @@ -/* $NetBSD: pthread.c,v 1.32 2003/12/31 16:45:48 cl Exp $ */ +/* $NetBSD: pthread.c,v 1.33 2004/03/14 01:19:41 cl Exp $ */ /*- * Copyright (c) 2001,2002,2003 The NetBSD Foundation, Inc. @@ -37,7 +37,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pthread.c,v 1.32 2003/12/31 16:45:48 cl Exp $"); +__RCSID("$NetBSD: pthread.c,v 1.33 2004/03/14 01:19:41 cl Exp $"); #include <err.h> #include <errno.h> @@ -49,6 +49,8 @@ __RCSID("$NetBSD: pthread.c,v 1.32 2003/12/31 16:45:48 cl Exp $"); #include <syslog.h> #include <ucontext.h> #include <unistd.h> +#include <sys/param.h> +#include <sys/sysctl.h> #include <sched.h> #include "pthread.h" @@ -69,7 +71,7 @@ struct pthread_queue_t pthread__allqueue; pthread_spin_t pthread__deadqueue_lock; struct pthread_queue_t pthread__deadqueue; -struct pthread_queue_t pthread__reidlequeue; +struct pthread_queue_t *pthread__reidlequeue; static int nthreads; static int nextthread; @@ -89,6 +91,8 @@ struct pthread_queue_t pthread__runqueue; struct pthread_queue_t pthread__idlequeue; struct pthread_queue_t pthread__suspqueue; +int pthread__concurrency, pthread__maxconcurrency; + __strong_alias(__libc_thr_self,pthread_self) __strong_alias(__libc_thr_create,pthread_create) __strong_alias(__libc_thr_exit,pthread_exit) @@ -126,18 +130,43 @@ pthread_init(void) { pthread_t first; char *p; + int i, mib[2], ncpu; + size_t len; extern int __isthreaded; + mib[0] = CTL_HW; + mib[1] = HW_NCPU; + + len = sizeof(ncpu); + sysctl(mib, 2, &ncpu, &len, NULL, 0); + /* Initialize locks first; they're needed elsewhere. */ - pthread__lockprim_init(); + pthread__lockprim_init(ncpu); + + /* Find out requested/possible concurrency */ + pthread__maxconcurrency = 1; + p = getenv("PTHREAD_CONCURRENCY"); + if (p) + pthread__maxconcurrency = atoi(p); + if (pthread__maxconcurrency < 1) + pthread__maxconcurrency = 1; + if (pthread__maxconcurrency > ncpu) + pthread__maxconcurrency = ncpu; + + /* Allocate data structures */ + pthread__reidlequeue = (struct pthread_queue_t *)malloc + (pthread__maxconcurrency * sizeof(struct pthread_queue_t)); + if (pthread__reidlequeue == NULL) + err(1, "Couldn't allocate memory for pthread__reidlequeue"); /* Basic data structure setup */ pthread_attr_init(&pthread_default_attr); PTQ_INIT(&pthread__allqueue); PTQ_INIT(&pthread__deadqueue); - PTQ_INIT(&pthread__reidlequeue); PTQ_INIT(&pthread__runqueue); PTQ_INIT(&pthread__idlequeue); + for (i = 0; i < pthread__maxconcurrency; i++) + PTQ_INIT(&pthread__reidlequeue[i]); nthreads = 1; /* Create the thread structure corresponding to main() */ @@ -151,7 +180,7 @@ pthread_init(void) pthread__signal_init(); PTHREAD_MD_INIT #ifdef PTHREAD__DEBUG - pthread__debug_init(); + pthread__debug_init(ncpu); #endif for (p = getenv("PTHREAD_DIAGASSERT"); p && *p; p++) { @@ -215,7 +244,10 @@ pthread__start(void) pthread_atfork(NULL, NULL, pthread__child_callback); - /* Create idle threads */ + /* + * Create idle threads + * XXX need to create more idle threads if concurrency > 3 + */ for (i = 0; i < NIDLETHREADS; i++) { ret = pthread__stackalloc(&idle); if (ret != 0) @@ -468,7 +500,10 @@ pthread__idle(void) * a list somewhere for the thread system to know about us. */ pthread_spinlock(self, &pthread__deadqueue_lock); - PTQ_INSERT_TAIL(&pthread__reidlequeue, self, pt_runq); + PTQ_INSERT_TAIL(&pthread__reidlequeue[self->pt_vpid], self, pt_runq); + pthread__concurrency--; + SDPRINTF(("(yield %p concurrency) now %d\n", self, + pthread__concurrency)); /* Don't need a flag lock; nothing else has a handle on this thread */ self->pt_flags |= PT_FLAG_IDLED; pthread_spinunlock(self, &pthread__deadqueue_lock); |
