diff options
author | davidxu <davidxu@FreeBSD.org> | 2005-04-02 01:20:00 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2005-04-02 01:20:00 +0000 |
commit | f066519e91e2290cb79ef12fe7c958ee462cda6c (patch) | |
tree | 6aaef5f553a6539306bd6f5679d039ed3c2abcce /lib/libthr/thread/thr_kern.c | |
parent | 3cc412b7837a105c757df856c422eb5f497bad67 (diff) | |
download | FreeBSD-src-f066519e91e2290cb79ef12fe7c958ee462cda6c.zip FreeBSD-src-f066519e91e2290cb79ef12fe7c958ee462cda6c.tar.gz |
Import my recent 1:1 threading working. some features improved includes:
1. fast simple type mutex.
2. __thread tls works.
3. asynchronous cancellation works ( using signal ).
4. thread synchronization is fully based on umtx, mainly, condition
variable and other synchronization objects were rewritten by using
umtx directly. those objects can be shared between processes via
shared memory, it has to change ABI which does not happen yet.
5. default stack size is increased to 1M on 32 bits platform, 2M for
64 bits platform.
As the result, some mysql super-smack benchmarks show performance is
improved massivly.
Okayed by: jeff, mtm, rwatson, scottl
Diffstat (limited to 'lib/libthr/thread/thr_kern.c')
-rw-r--r-- | lib/libthr/thread/thr_kern.c | 141 |
1 files changed, 48 insertions, 93 deletions
diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c index 0f0305e..4c451f1 100644 --- a/lib/libthr/thread/thr_kern.c +++ b/lib/libthr/thread/thr_kern.c @@ -1,5 +1,6 @@ /* - * Copyright (c) 2003 Jeffrey Roberson <jeff@freebsd.org> + * Copyright (c) 2005 David Xu <davidxu@freebsd.org> + * Copyright (C) 2003 Daniel M. Eischen <deischen@freebsd.org> * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,120 +27,74 @@ * $FreeBSD$ */ -#include <sys/cdefs.h> #include <sys/types.h> #include <sys/signalvar.h> -#include <sys/time.h> -#include <sys/timespec.h> #include <pthread.h> -#include <signal.h> -#include <stdlib.h> -#include <errno.h> -#include <unistd.h> #include "thr_private.h" -/* XXX Why can't I get this from time.h? :-( */ -#define timespecsub(vvp, uvp) \ - do { \ - (vvp)->tv_sec -= (uvp)->tv_sec; \ - (vvp)->tv_nsec -= (uvp)->tv_nsec; \ - if ((vvp)->tv_nsec < 0) { \ - (vvp)->tv_sec--; \ - (vvp)->tv_nsec += 1000000000; \ - } \ - } while (0) +/*#define DEBUG_THREAD_KERN */ +#ifdef DEBUG_THREAD_KERN +#define DBG_MSG stdout_debug +#else +#define DBG_MSG(x...) +#endif -void -_thread_critical_enter(pthread_t pthread) -{ - _thread_sigblock(); - UMTX_LOCK(&pthread->lock); -} - -void -_thread_critical_exit(pthread_t pthread) +/* + * This is called when the first thread (other than the initial + * thread) is created. + */ +int +_thr_setthreaded(int threaded) { - UMTX_UNLOCK(&pthread->lock); - _thread_sigunblock(); + if (((threaded == 0) ^ (__isthreaded == 0)) == 0) + return (0); + + __isthreaded = threaded; +#if 0 + if (threaded != 0) { + _thr_rtld_init(); + } else { + _thr_rtld_fini(); + } +#endif + return (0); } void -_thread_sigblock() +_thr_signal_block(struct pthread *curthread) { sigset_t set; - sigset_t sav; - - /* - * Block all signals. - */ - SIGFILLSET(set); - SIGDELSET(set, SIGTRAP); - - /* If we have already blocked signals, just up the refcount */ - if (++curthread->signest > 1) + + if (curthread->sigblock > 0) { + curthread->sigblock++; return; - PTHREAD_ASSERT(curthread->signest == 1, - ("Blocked signal nesting level must be 1!")); - - if (__sys_sigprocmask(SIG_SETMASK, &set, &sav)) { - _thread_printf(STDERR_FILENO, "Critical Enter: sig err %d\n", - errno); - abort(); } - curthread->savedsig = sav; + SIGFILLSET(set); + SIGDELSET(set, SIGBUS); + SIGDELSET(set, SIGILL); + SIGDELSET(set, SIGFPE); + SIGDELSET(set, SIGSEGV); + SIGDELSET(set, SIGTRAP); + __sys_sigprocmask(SIG_BLOCK, &set, &curthread->sigmask); + curthread->sigblock++; } void -_thread_sigunblock() +_thr_signal_unblock(struct pthread *curthread) { - sigset_t set; - - /* We might be in a nested 'blocked signal' section */ - if (--curthread->signest > 0) - return; - PTHREAD_ASSERT(curthread->signest == 0, - ("Non-Zero blocked signal nesting level.")); - - /* - * Restore signals. - */ - set = curthread->savedsig; - if (__sys_sigprocmask(SIG_SETMASK, &set, NULL)) { - _thread_printf(STDERR_FILENO, "Critical Exit: sig err %d\n", - errno); - abort(); - } + if (--curthread->sigblock == 0) + __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); } int -_thread_suspend(pthread_t pthread, const struct timespec *abstime) +_thr_send_sig(struct pthread *thread, int sig) { - struct timespec remaining; - struct timespec *ts; - int error; - - /* - * Compute the remainder of the run time. - */ - if (abstime) { - struct timespec now; - struct timeval tv; - - GET_CURRENT_TOD(tv); - TIMEVAL_TO_TIMESPEC(&tv, &now); - - remaining = *abstime; - timespecsub(&remaining, &now); - ts = &remaining; + return thr_kill(thread->tid, sig); +} - /* - * NOTE: timespecsub() makes sure the tv_nsec member >= 0. - */ - if (ts->tv_sec < 0) - return (ETIMEDOUT); - } else - ts = NULL; - error = thr_suspend(ts); - return (error == -1 ? errno : error); +void +_thr_assert_lock_level() +{ + PANIC("locklevel <= 0"); } |