diff options
Diffstat (limited to 'lib/libpthread/thread')
| -rw-r--r-- | lib/libpthread/thread/thr_cond.c | 10 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_init.c | 4 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_kern.c | 58 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_mutex.c | 46 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_nanosleep.c | 4 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_private.h | 1 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_pspinlock.c | 7 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_rtld.c | 12 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_sem.c | 1 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_sig.c | 41 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_sigsuspend.c | 7 | ||||
| -rw-r--r-- | lib/libpthread/thread/thr_symbols.c | 1 |
12 files changed, 110 insertions, 82 deletions
diff --git a/lib/libpthread/thread/thr_cond.c b/lib/libpthread/thread/thr_cond.c index cd719d424140..a50a690b182e 100644 --- a/lib/libpthread/thread/thr_cond.c +++ b/lib/libpthread/thread/thr_cond.c @@ -421,11 +421,6 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, /* Return invalid argument error: */ rval = EINVAL; } else { - /* Set the wakeup time: */ - curthread->wakeup_time.tv_sec = abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - /* Reset the timeout and interrupted flags: */ curthread->timeout = 0; curthread->interrupted = 0; @@ -464,6 +459,11 @@ _pthread_cond_timedwait(pthread_cond_t * cond, pthread_mutex_t * mutex, * set the state. */ THR_SCHED_LOCK(curthread, curthread); + /* Set the wakeup time: */ + curthread->wakeup_time.tv_sec = + abstime->tv_sec; + curthread->wakeup_time.tv_nsec = + abstime->tv_nsec; THR_SET_STATE(curthread, PS_COND_WAIT); /* Remember the CV: */ diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c index c14362732b03..9fe1ee7225f6 100644 --- a/lib/libpthread/thread/thr_init.c +++ b/lib/libpthread/thread/thr_init.c @@ -437,6 +437,7 @@ init_private(void) } _pthread_attr_default.guardsize_attr = _thr_guard_default; _pthread_attr_default.stacksize_attr = _thr_stack_default; + TAILQ_INIT(&_thr_atfork_list); init_once = 1; /* Don't do this again. */ } else { /* @@ -453,7 +454,6 @@ init_private(void) /* Initialize everything else. */ TAILQ_INIT(&_thread_list); TAILQ_INIT(&_thread_gc_list); - TAILQ_INIT(&_thr_atfork_list); _pthread_mutex_init(&_thr_atfork_mutex, NULL); /* @@ -487,6 +487,8 @@ init_private(void) else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL) _thread_scope_system = -1; #endif + if (getenv("LIBPTHREAD_DEBUG") != NULL) + _thr_debug_flags |= DBG_INFO_DUMP; /* * _thread_list_lock and _kse_count are initialized diff --git a/lib/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c index aec254122a50..f1b28c0e38ca 100644 --- a/lib/libpthread/thread/thr_kern.c +++ b/lib/libpthread/thread/thr_kern.c @@ -55,6 +55,9 @@ __FBSDID("$FreeBSD$"); #include "atomic_ops.h" #include "thr_private.h" #include "libc_private.h" +#ifdef NOTYET +#include "spinlock.h" +#endif /* #define DEBUG_THREAD_KERN */ #ifdef DEBUG_THREAD_KERN @@ -210,9 +213,9 @@ _kse_single_thread(struct pthread *curthread) struct kse *kse; struct kse_group *kseg; struct pthread *thread; - kse_critical_t crit; - int i; + _thr_spinlock_init(); + *__malloc_lock = (spinlock_t)_SPINLOCK_INITIALIZER; if (__isthreaded) { _thr_rtld_fini(); _thr_signal_deinit(); @@ -222,7 +225,7 @@ _kse_single_thread(struct pthread *curthread) * Restore signal mask early, so any memory problems could * dump core. */ - sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); + __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); _thread_active_threads = 1; /* @@ -250,11 +253,8 @@ _kse_single_thread(struct pthread *curthread) curthread->joiner = NULL; /* no joining threads yet */ curthread->refcount = 0; SIGEMPTYSET(curthread->sigpend); /* clear pending signals */ - if (curthread->specific != NULL) { - free(curthread->specific); - curthread->specific = NULL; - curthread->specific_data_count = 0; - } + + /* Don't free thread-specific data as the caller may require it */ /* Free the free KSEs: */ while ((kse = TAILQ_FIRST(&free_kseq)) != NULL) { @@ -317,6 +317,9 @@ _kse_single_thread(struct pthread *curthread) curthread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; curthread->attr.flags |= PTHREAD_SCOPE_PROCESS; + /* We're no longer part of any lists */ + curthread->tlflags = 0; + /* * After a fork, we are still operating on the thread's original * stack. Don't clear the THR_FLAGS_USER from the thread's @@ -1334,6 +1337,7 @@ kseg_gc(struct pthread *curthread) if (free_kseg_count <= MAX_CACHED_KSEGS) return; + TAILQ_INIT(&worklist); crit = _kse_critical_enter(); KSE_LOCK_ACQUIRE(curthread->kse, &kse_lock); while (free_kseg_count > MAX_CACHED_KSEGS) { @@ -2365,6 +2369,11 @@ _thr_alloc(struct pthread *curthread) if ((thread == NULL) && ((thread = malloc(sizeof(struct pthread))) != NULL)) { bzero(thread, sizeof(struct pthread)); + thread->siginfo = calloc(_SIG_MAXSIG, sizeof(siginfo_t)); + if (thread->siginfo == NULL) { + free(thread); + return (NULL); + } if (curthread) { _pthread_mutex_lock(&_tcb_mutex); thread->tcb = _tcb_ctor(thread, 0 /* not initial tls */); @@ -2373,25 +2382,22 @@ _thr_alloc(struct pthread *curthread) thread->tcb = _tcb_ctor(thread, 1 /* initial tls */); } if (thread->tcb == NULL) { + free(thread->siginfo); free(thread); - thread = NULL; - } else { - thread->siginfo = calloc(_SIG_MAXSIG, - sizeof(siginfo_t)); - /* - * Initialize thread locking. - * Lock initializing needs malloc, so don't - * enter critical region before doing this! - */ - if (_lock_init(&thread->lock, LCK_ADAPTIVE, - _thr_lock_wait, _thr_lock_wakeup) != 0) - PANIC("Cannot initialize thread lock"); - for (i = 0; i < MAX_THR_LOCKLEVEL; i++) { - _lockuser_init(&thread->lockusers[i], - (void *)thread); - _LCK_SET_PRIVATE2(&thread->lockusers[i], - (void *)thread); - } + return (NULL); + } + /* + * Initialize thread locking. + * Lock initializing needs malloc, so don't + * enter critical region before doing this! + */ + if (_lock_init(&thread->lock, LCK_ADAPTIVE, + _thr_lock_wait, _thr_lock_wakeup) != 0) + PANIC("Cannot initialize thread lock"); + for (i = 0; i < MAX_THR_LOCKLEVEL; i++) { + _lockuser_init(&thread->lockusers[i], (void *)thread); + _LCK_SET_PRIVATE2(&thread->lockusers[i], + (void *)thread); } } return (thread); diff --git a/lib/libpthread/thread/thr_mutex.c b/lib/libpthread/thread/thr_mutex.c index b502c15af818..99599f120366 100644 --- a/lib/libpthread/thread/thr_mutex.c +++ b/lib/libpthread/thread/thr_mutex.c @@ -551,14 +551,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } else { - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - /* * Join the queue of threads waiting to lock * the mutex and save a pointer to the mutex. @@ -572,6 +564,14 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, * be able to safely set the state. */ THR_SCHED_LOCK(curthread, curthread); + /* Set the wakeup time: */ + if (abstime) { + curthread->wakeup_time.tv_sec = + abstime->tv_sec; + curthread->wakeup_time.tv_nsec = + abstime->tv_nsec; + } + THR_SET_STATE(curthread, PS_MUTEX_WAIT); THR_SCHED_UNLOCK(curthread, curthread); @@ -633,14 +633,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } else { - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - /* * Join the queue of threads waiting to lock * the mutex and save a pointer to the mutex. @@ -659,6 +651,13 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, mutex_priority_adjust(curthread, *m); THR_SCHED_LOCK(curthread, curthread); + /* Set the wakeup time: */ + if (abstime) { + curthread->wakeup_time.tv_sec = + abstime->tv_sec; + curthread->wakeup_time.tv_nsec = + abstime->tv_nsec; + } THR_SET_STATE(curthread, PS_MUTEX_WAIT); THR_SCHED_UNLOCK(curthread, curthread); @@ -730,14 +729,6 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, /* Unlock the mutex structure: */ THR_LOCK_RELEASE(curthread, &(*m)->m_lock); } else { - /* Set the wakeup time: */ - if (abstime) { - curthread->wakeup_time.tv_sec = - abstime->tv_sec; - curthread->wakeup_time.tv_nsec = - abstime->tv_nsec; - } - /* * Join the queue of threads waiting to lock * the mutex and save a pointer to the mutex. @@ -756,6 +747,13 @@ mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m, */ THR_SCHED_LOCK(curthread, curthread); + /* Set the wakeup time: */ + if (abstime) { + curthread->wakeup_time.tv_sec = + abstime->tv_sec; + curthread->wakeup_time.tv_nsec = + abstime->tv_nsec; + } THR_SET_STATE(curthread, PS_MUTEX_WAIT); THR_SCHED_UNLOCK(curthread, curthread); diff --git a/lib/libpthread/thread/thr_nanosleep.c b/lib/libpthread/thread/thr_nanosleep.c index e8baa844a1d0..5eba37db98bf 100644 --- a/lib/libpthread/thread/thr_nanosleep.c +++ b/lib/libpthread/thread/thr_nanosleep.c @@ -46,6 +46,7 @@ _nanosleep(const struct timespec *time_to_sleep, int ret = 0; struct timespec ts, ts1; struct timespec remaining_time; + struct timespec wakeup_time; /* Check if the time to sleep is legal: */ if ((time_to_sleep == NULL) || (time_to_sleep->tv_sec < 0) || @@ -61,10 +62,11 @@ _nanosleep(const struct timespec *time_to_sleep, KSE_GET_TOD(curthread->kse, &ts); /* Calculate the time for the current thread to wake up: */ - TIMESPEC_ADD(&curthread->wakeup_time, &ts, time_to_sleep); + TIMESPEC_ADD(&wakeup_time, &ts, time_to_sleep); THR_LOCK_SWITCH(curthread); curthread->interrupted = 0; + curthread->wakeup_time = wakeup_time; THR_SET_STATE(curthread, PS_SLEEP_WAIT); /* Reschedule the current thread to sleep: */ diff --git a/lib/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h index e2055bc1da64..9d8ee632fd00 100644 --- a/lib/libpthread/thread/thr_private.h +++ b/lib/libpthread/thread/thr_private.h @@ -82,6 +82,7 @@ #define DBG_MUTEX 0x0001 #define DBG_SIG 0x0002 +#define DBG_INFO_DUMP 0x0004 #ifdef _PTHREADS_INVARIANTS #define THR_ASSERT(cond, msg) do { \ diff --git a/lib/libpthread/thread/thr_pspinlock.c b/lib/libpthread/thread/thr_pspinlock.c index b58d7120d4ea..de555bfc796d 100644 --- a/lib/libpthread/thread/thr_pspinlock.c +++ b/lib/libpthread/thread/thr_pspinlock.c @@ -26,10 +26,13 @@ * $FreeBSD$ */ +#include <sys/types.h> #include <errno.h> -#include <stdlib.h> #include <pthread.h> -#include <atomic_ops.h> +#include <stdint.h> +#include <stdlib.h> + +#include "atomic_ops.h" #include "thr_private.h" #define SPIN_COUNT 10000 diff --git a/lib/libpthread/thread/thr_rtld.c b/lib/libpthread/thread/thr_rtld.c index 9528593fbde4..e8130735fb4d 100644 --- a/lib/libpthread/thread/thr_rtld.c +++ b/lib/libpthread/thread/thr_rtld.c @@ -160,11 +160,13 @@ _thr_rtld_lock_create(void) { struct rtld_kse_lock *l; - l = malloc(sizeof(struct rtld_kse_lock)); - _lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait, _kse_lock_wakeup); - l->owner = NULL; - l->count = 0; - l->write = 0; + if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) { + _lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait, + _kse_lock_wakeup); + l->owner = NULL; + l->count = 0; + l->write = 0; + } return (l); } diff --git a/lib/libpthread/thread/thr_sem.c b/lib/libpthread/thread/thr_sem.c index 027960e0c859..8312a870a870 100644 --- a/lib/libpthread/thread/thr_sem.c +++ b/lib/libpthread/thread/thr_sem.c @@ -30,6 +30,7 @@ */ #include "namespace.h" +#include <sys/types.h> #include <sys/queue.h> #include <errno.h> #include <fcntl.h> diff --git a/lib/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c index ec6ebd51eadd..f53b87f08b17 100644 --- a/lib/libpthread/thread/thr_sig.c +++ b/lib/libpthread/thread/thr_sig.c @@ -98,6 +98,12 @@ static int sigproptbl[NSIG] = { #define DBG_MSG(x...) #endif +static __inline int +_thr_dump_enabled(void) +{ + return ((_thr_debug_flags & DBG_INFO_DUMP) != 0); +} + /* * Signal setup and delivery. * @@ -253,7 +259,7 @@ _thr_sig_dispatch(struct kse *curkse, int sig, siginfo_t *info) DBG_MSG(">>> _thr_sig_dispatch(%d)\n", sig); /* Check if the signal requires a dump of thread information: */ - if (sig == SIGINFO) { + if (_thr_dump_enabled() && (sig == SIGINFO)) { /* Dump thread information to file: */ _thread_dump_info(); } @@ -347,7 +353,7 @@ _thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp) } /* Check if the signal requires a dump of thread information: */ - if (sig == SIGINFO) { + if (_thr_dump_enabled() && (sig == SIGINFO)) { /* Dump thread information to file: */ _thread_dump_info(); } @@ -521,7 +527,7 @@ handle_signal(struct pthread *curthread, struct sighandle_info *shi) _kse_critical_leave(&curthread->tcb->tcb_tmbx); /* Check if the signal requires a dump of thread information: */ - if (shi->sig == SIGINFO) { + if (_thr_dump_enabled() && (shi->sig == SIGINFO)) { /* Dump thread information to file: */ _thread_dump_info(); } @@ -1200,21 +1206,24 @@ _thr_signal_init(void) __sys_sigaction(i, &act, NULL); } } - /* - * Install the signal handler for SIGINFO. It isn't - * really needed, but it is nice to have for debugging - * purposes. - */ - _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; - SIGEMPTYSET(act.sa_mask); - act.sa_flags = SA_SIGINFO | SA_RESTART; - act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; - if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { - __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); + if (_thr_dump_enabled()) { /* - * Abort this process if signal initialisation fails: + * Install the signal handler for SIGINFO. It isn't + * really needed, but it is nice to have for debugging + * purposes. */ - PANIC("Cannot initialize signal handler"); + _thread_sigact[SIGINFO - 1].sa_flags = SA_SIGINFO | SA_RESTART; + SIGEMPTYSET(act.sa_mask); + act.sa_flags = SA_SIGINFO | SA_RESTART; + act.sa_sigaction = (__siginfohandler_t *)&_thr_sig_handler; + if (__sys_sigaction(SIGINFO, &act, NULL) != 0) { + __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, + NULL); + /* + * Abort this process if signal initialisation fails: + */ + PANIC("Cannot initialize signal handler"); + } } __sys_sigprocmask(SIG_SETMASK, &_thr_initial->sigmask, NULL); __sys_sigaltstack(NULL, &_thr_initial->sigstk); diff --git a/lib/libpthread/thread/thr_sigsuspend.c b/lib/libpthread/thread/thr_sigsuspend.c index b8e14e354fea..6452af150d43 100644 --- a/lib/libpthread/thread/thr_sigsuspend.c +++ b/lib/libpthread/thread/thr_sigsuspend.c @@ -31,11 +31,14 @@ * * $FreeBSD$ */ -#include <signal.h> + +#include <sys/types.h> +#include <sys/signalvar.h> #include <errno.h> #include <pthread.h> +#include <signal.h> #include <string.h> -#include <sys/signalvar.h> + #include "thr_private.h" __weak_reference(__sigsuspend, sigsuspend); diff --git a/lib/libpthread/thread/thr_symbols.c b/lib/libpthread/thread/thr_symbols.c index 5091a9517c66..10e9402a6032 100644 --- a/lib/libpthread/thread/thr_symbols.c +++ b/lib/libpthread/thread/thr_symbols.c @@ -32,6 +32,7 @@ * $FreeBSD$ */ +#include <sys/types.h> #include <stddef.h> #include <pthread.h> #include <rtld.h> |
