summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread/thr_kern.c')
-rw-r--r--lib/libthr/thread/thr_kern.c141
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");
}
OpenPOWER on IntegriCloud