summaryrefslogtreecommitdiffstats
path: root/lib/libkse
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2002-02-09 19:58:41 +0000
committerdeischen <deischen@FreeBSD.org>2002-02-09 19:58:41 +0000
commit4ed9f7fd062cd8c757f7325cad3bc2ea2c340e84 (patch)
treedc39d813fe8f056c1b1cfa1a5216fba9998c6103 /lib/libkse
parent04de78234927ede2f34f9b1286fb8344dafa63fc (diff)
downloadFreeBSD-src-4ed9f7fd062cd8c757f7325cad3bc2ea2c340e84.zip
FreeBSD-src-4ed9f7fd062cd8c757f7325cad3bc2ea2c340e84.tar.gz
This has been sitting in my local tree long enough. Remove the use
of an alternate signal stack for handling signals. Let the kernel send signals on the stack of the current thread and teach the threads signal handler how to deliver signals to the current thread if it needs to. Also, always store a threads context as a jmp_buf. Eventually this will change to be a ucontext_t or mcontext_t. Other small nits. Use struct pthread * instead of pthread_t in internal library routines. The threads code wants struct pthread *, and pthread_t doesn't necessarily have to be the same. Reviewed by: jasone
Diffstat (limited to 'lib/libkse')
-rw-r--r--lib/libkse/thread/thr_create.c8
-rw-r--r--lib/libkse/thread/thr_init.c12
-rw-r--r--lib/libkse/thread/thr_kern.c138
-rw-r--r--lib/libkse/thread/thr_private.h55
-rw-r--r--lib/libkse/thread/thr_sig.c222
5 files changed, 167 insertions, 268 deletions
diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c
index 7c52b4b..70227ea 100644
--- a/lib/libkse/thread/thr_create.c
+++ b/lib/libkse/thread/thr_create.c
@@ -50,16 +50,11 @@ int _thread_next_offset = OFF(tle.tqe_next);
int _thread_uniqueid_offset = OFF(uniqueid);
int _thread_state_offset = OFF(state);
int _thread_name_offset = OFF(name);
-int _thread_ctxtype_offset = OFF(ctxtype);
int _thread_ctx_offset = OFF(ctx);
#undef OFF
int _thread_PS_RUNNING_value = PS_RUNNING;
int _thread_PS_DEAD_value = PS_DEAD;
-int _thread_CTX_JB_NOSIG_value = CTX_JB_NOSIG;
-int _thread_CTX_JB_value = CTX_JB;
-int _thread_CTX_SJB_value = CTX_SJB;
-int _thread_CTX_UC_value = CTX_UC;
__weak_reference(_pthread_create, pthread_create);
@@ -148,9 +143,6 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
(long)new_thread->stack + pattr->stacksize_attr
- sizeof(double));
- /* Initialize the rest of the frame: */
- new_thread->ctxtype = CTX_JB_NOSIG;
-
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
diff --git a/lib/libkse/thread/thr_init.c b/lib/libkse/thread/thr_init.c
index cac38dc..689e85b 100644
--- a/lib/libkse/thread/thr_init.c
+++ b/lib/libkse/thread/thr_init.c
@@ -334,7 +334,6 @@ _thread_init(void)
/* Initialize the initial context: */
_thread_initial->curframe = NULL;
- _thread_initial->ctxtype = CTX_JB_NOSIG;
/* Initialise the rest of the fields: */
_thread_initial->poll_data.nfds = 0;
@@ -360,17 +359,6 @@ _thread_init(void)
/* Clear the signal queue: */
memset(_thread_sigq, 0, sizeof(_thread_sigq));
- /*
- * Create and install an alternate signal stack of
- * the recommended size:
- */
- _thread_sigstack.ss_sp = malloc(SIGSTKSZ);
- _thread_sigstack.ss_size = SIGSTKSZ;
- _thread_sigstack.ss_flags = 0;
- if ((_thread_sigstack.ss_sp == NULL) ||
- (__sys_sigaltstack(&_thread_sigstack, NULL) != 0))
- PANIC("Unable to install alternate signal stack");
-
/* Enter a loop to get the existing signal status: */
for (i = 1; i < NSIG; i++) {
/* Check for signals which cannot be trapped: */
diff --git a/lib/libkse/thread/thr_kern.c b/lib/libkse/thread/thr_kern.c
index ec4c233..a4cc3c3 100644
--- a/lib/libkse/thread/thr_kern.c
+++ b/lib/libkse/thread/thr_kern.c
@@ -100,7 +100,7 @@ _thread_kern_sched_frame(struct pthread_signal_frame *psf)
void
-_thread_kern_sched(ucontext_t *scp)
+_thread_kern_sched(ucontext_t *ucp)
{
struct pthread *curthread = _get_curthread();
@@ -112,50 +112,61 @@ _thread_kern_sched(ucontext_t *scp)
_thread_kern_in_sched = 1;
/* Check if this function was called from the signal handler: */
- if (scp != NULL) {
+ if (ucp != NULL) {
+ /* XXX - Save FP registers? */
+ FP_SAVE_UC(ucp);
called_from_handler = 1;
DBG_MSG("Entering scheduler due to signal\n");
- } else {
- /* Save the state of the current thread: */
- if (_setjmp(curthread->ctx.jb) == 0) {
- /* Flag the jump buffer was the last state saved: */
- curthread->ctxtype = CTX_JB_NOSIG;
- curthread->longjmp_val = 1;
- } else {
- DBG_MSG("Returned from ___longjmp, thread %p\n",
- curthread);
- /*
- * This point is reached when a longjmp() is called
- * to restore the state of a thread.
- *
- * This is the normal way out of the scheduler.
- */
- _thread_kern_in_sched = 0;
+ }
- if (curthread->sig_defer_count == 0) {
- if (((curthread->cancelflags &
- PTHREAD_AT_CANCEL_POINT) == 0) &&
- ((curthread->cancelflags &
- PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
- /*
- * Cancellations override signals.
- *
- * Stick a cancellation point at the
- * start of each async-cancellable
- * thread's resumption.
- *
- * We allow threads woken at cancel
- * points to do their own checks.
- */
- pthread_testcancel();
- }
+ /* Save the state of the current thread: */
+ if (_setjmp(curthread->ctx.jb) != 0) {
+ DBG_MSG("Returned from ___longjmp, thread %p\n",
+ curthread);
+ /*
+ * This point is reached when a longjmp() is called
+ * to restore the state of a thread.
+ *
+ * This is the normal way out of the scheduler.
+ */
+ _thread_kern_in_sched = 0;
- if (_sched_switch_hook != NULL) {
- /* Run the installed switch hook: */
- thread_run_switch_hook(_last_user_thread,
- curthread);
- }
+ if (curthread->sig_defer_count == 0) {
+ if (((curthread->cancelflags &
+ PTHREAD_AT_CANCEL_POINT) == 0) &&
+ ((curthread->cancelflags &
+ PTHREAD_CANCEL_ASYNCHRONOUS) != 0))
+ /*
+ * Cancellations override signals.
+ *
+ * Stick a cancellation point at the
+ * start of each async-cancellable
+ * thread's resumption.
+ *
+ * We allow threads woken at cancel
+ * points to do their own checks.
+ */
+ pthread_testcancel();
+ }
+
+ if (_sched_switch_hook != NULL) {
+ /* Run the installed switch hook: */
+ thread_run_switch_hook(_last_user_thread, curthread);
+ }
+ if (ucp == NULL)
return;
+ else {
+ /* XXX - Restore FP registers? */
+ FP_RESTORE_UC(ucp);
+
+ /*
+ * Set the process signal mask in the context; it
+ * could have changed by the handler.
+ */
+ ucp->uc_sigmask = _process_sigmask;
+
+ /* Resume the interrupted thread: */
+ __sys_sigreturn(ucp);
}
}
/* Switch to the thread scheduler: */
@@ -190,20 +201,12 @@ _thread_kern_scheduler(void)
called_from_handler = 0;
/*
- * The signal handler should have saved the state of
- * the current thread. Restore the process signal
- * mask.
+ * We were called from a signal handler; restore the process
+ * signal mask.
*/
if (__sys_sigprocmask(SIG_SETMASK,
&_process_sigmask, NULL) != 0)
PANIC("Unable to restore process mask after signal");
-
- /*
- * Since the signal handler didn't return normally, we
- * have to tell the kernel to reuse the signal stack.
- */
- if (__sys_sigaltstack(&_thread_sigstack, NULL) != 0)
- PANIC("Unable to restore alternate signal stack");
}
/*
@@ -581,42 +584,11 @@ _thread_kern_scheduler(void)
/*
* Continue the thread at its current frame:
*/
- switch(curthread->ctxtype) {
- case CTX_JB_NOSIG:
- ___longjmp(curthread->ctx.jb,
- curthread->longjmp_val);
- break;
- case CTX_JB:
- __longjmp(curthread->ctx.jb,
- curthread->longjmp_val);
- break;
- case CTX_SJB:
- __siglongjmp(curthread->ctx.sigjb,
- curthread->longjmp_val);
- break;
- case CTX_UC:
- /* XXX - Restore FP regsisters? */
- FP_RESTORE_UC(&curthread->ctx.uc);
-
- /*
- * Do a sigreturn to restart the thread that
- * was interrupted by a signal:
- */
- _thread_kern_in_sched = 0;
-
#if NOT_YET
- _setcontext(&curthread->ctx.uc);
+ _setcontext(&curthread->ctx.uc);
#else
- /*
- * Ensure the process signal mask is set
- * correctly:
- */
- curthread->ctx.uc.uc_sigmask =
- _process_sigmask;
- __sys_sigreturn(&curthread->ctx.uc);
+ ___longjmp(curthread->ctx.jb, 1);
#endif
- break;
- }
/* This point should not be reached. */
PANIC("Thread has returned from sigreturn or longjmp");
}
diff --git a/lib/libkse/thread/thr_private.h b/lib/libkse/thread/thr_private.h
index 65661f7..c294693 100644
--- a/lib/libkse/thread/thr_private.h
+++ b/lib/libkse/thread/thr_private.h
@@ -603,38 +603,13 @@ struct pthread_state_data {
struct join_status {
struct pthread *thread;
- int ret;
+ void *ret;
int error;
};
/*
- * Normally thread contexts are stored as jmp_bufs via _setjmp()/_longjmp(),
- * but they may also be sigjmp_buf and ucontext_t. When a thread is
- * interrupted by a signal, it's context is saved as a ucontext_t. An
- * application is also free to use [_]longjmp()/[_]siglongjmp() to jump
- * between contexts within the same thread. Future support will also
- * include setcontext()/getcontext().
- *
- * Define an enumerated type that can identify the 4 different context
- * types.
- */
-typedef enum {
- CTX_JB_NOSIG, /* context is jmp_buf without saved sigset */
- CTX_JB, /* context is jmp_buf (with saved sigset) */
- CTX_SJB, /* context is sigjmp_buf (with saved sigset) */
- CTX_UC /* context is ucontext_t (with saved sigset) */
-} thread_context_t;
-
-/*
- * There are 2 basic contexts that a frame may contain at any
- * one time:
- *
- * o ctx - The context that the thread should return to after normal
- * completion of the signal handler.
- * o sig_jb - The context just before the signal handler is invoked.
- * Attempts at abnormal returns from user supplied signal handlers
- * will return back to the signal context to perform any necessary
- * cleanup.
+ * The frame that is added to the top of a threads stack when setting up
+ * up the thread to run a signal handler.
*/
struct pthread_signal_frame {
/*
@@ -643,19 +618,12 @@ struct pthread_signal_frame {
struct pthread_state_data saved_state;
/*
- * Threads return context; ctxtype identifies the type of context.
- * For signal frame 0, these point to the context storage area
- * within the pthread structure. When handling signals (frame > 0),
- * these point to a context storage area that is allocated off the
- * threads stack.
+ * Threads return context; we use only jmp_buf's for now.
*/
union {
jmp_buf jb;
- sigjmp_buf sigjb;
ucontext_t uc;
} ctx;
- thread_context_t ctxtype;
- int longjmp_val;
int signo; /* signal, arg 1 to sighandler */
int sig_has_args; /* use signal args if true */
ucontext_t uc;
@@ -696,15 +664,12 @@ struct pthread {
struct pthread_attr attr;
/*
- * Threads return context; ctxtype identifies the type of context.
+ * Threads return context; we use only jmp_buf's for now.
*/
union {
jmp_buf jb;
- sigjmp_buf sigjb;
ucontext_t uc;
} ctx;
- thread_context_t ctxtype;
- int longjmp_val;
/*
* Used for tracking delivery of signal handlers.
@@ -1145,9 +1110,6 @@ SCLASS volatile int _sigq_check_reqd
#endif
;
-/* The signal stack. */
-SCLASS struct sigaltstack _thread_sigstack;
-
/* Thread switch hook. */
SCLASS pthread_switch_routine_t _sched_switch_hook
#ifdef GLOBAL_PTHREAD_PRIVATE
@@ -1257,11 +1219,12 @@ void _thread_kern_set_timeout(const struct timespec *);
void _thread_kern_sig_defer(void);
void _thread_kern_sig_undefer(void);
void _thread_sig_handler(int, siginfo_t *, ucontext_t *);
-void _thread_sig_check_pending(pthread_t pthread);
+void _thread_sig_check_pending(struct pthread *pthread);
void _thread_sig_handle_pending(void);
-void _thread_sig_send(pthread_t pthread, int sig);
+void _thread_sig_send(struct pthread *pthread, int sig);
void _thread_sig_wrapper(void);
-void _thread_sigframe_restore(pthread_t thread, struct pthread_signal_frame *psf);
+void _thread_sigframe_restore(struct pthread *thread,
+ struct pthread_signal_frame *psf);
void _thread_start(void);
void _thread_seterrno(pthread_t, int);
int _thread_fd_table_init(int fd);
diff --git a/lib/libkse/thread/thr_sig.c b/lib/libkse/thread/thr_sig.c
index a05f914..1bd93b7 100644
--- a/lib/libkse/thread/thr_sig.c
+++ b/lib/libkse/thread/thr_sig.c
@@ -43,13 +43,16 @@
#include "pthread_private.h"
/* Prototypes: */
-static void thread_sig_add(pthread_t pthread, int sig, int has_args);
-static void thread_sig_check_state(pthread_t pthread, int sig);
-static pthread_t thread_sig_find(int sig);
+static void thread_sig_add(struct pthread *pthread, int sig, int has_args);
+static void thread_sig_check_state(struct pthread *pthread, int sig);
+static struct pthread *thread_sig_find(int sig);
static void thread_sig_handle_special(int sig);
-static void thread_sig_savecontext(pthread_t pthread, ucontext_t *ucp);
-static void thread_sigframe_add(pthread_t thread, int sig, int has_args);
-static void thread_sigframe_save(pthread_t thread, struct pthread_signal_frame *psf);
+static void thread_sigframe_add(struct pthread *thread, int sig,
+ int has_args);
+static void thread_sigframe_save(struct pthread *thread,
+ struct pthread_signal_frame *psf);
+static void thread_sig_invoke_handler(int sig, siginfo_t *info,
+ ucontext_t *ucp);
/* #define DEBUG_SIGNAL */
#ifdef DEBUG_SIGNAL
@@ -70,23 +73,14 @@ void
_thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
{
struct pthread *curthread = _get_curthread();
- pthread_t pthread, pthread_h;
- void *stackp;
- int in_sched = 0;
+ struct pthread *pthread, *pthread_h;
+ int in_sched = _thread_kern_in_sched;
char c;
if (ucp == NULL)
PANIC("Thread signal handler received null context");
DBG_MSG("Got signal %d, current thread %p\n", sig, curthread);
- if (_thread_kern_in_sched != 0)
- in_sched = 1;
- else {
- stackp = (void *)GET_STACK_UC(ucp);
- if ((stackp >= _thread_kern_sched_stack) &&
- (stackp <= _thread_kern_sched_stack + SCHED_STACK_SIZE))
- in_sched = 1;
- }
/* Check if an interval timer signal: */
if (sig == _SCHED_SIGNAL) {
/* Update the scheduling clock: */
@@ -107,16 +101,7 @@ _thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
else if (curthread->sig_defer_count > 0)
curthread->yield_on_sig_undefer = 1;
else {
- /*
- * Save the context of the currently running thread:
- */
- thread_sig_savecontext(curthread, ucp);
-
- /*
- * Schedule the next thread. This function is not
- * expected to return because it will do a longjmp
- * instead.
- */
+ /* Schedule the next thread: */
_thread_kern_sched(ucp);
/*
@@ -210,18 +195,30 @@ _thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
thread_sig_handle_special(sig);
pthread_h = NULL;
- if ((pthread = thread_sig_find(sig)) != NULL) {
- DBG_MSG("Got signal %d, adding frame to thread %p\n",
- sig, pthread);
+ if ((pthread = thread_sig_find(sig)) == NULL)
+ DBG_MSG("No thread to handle signal %d\n", sig);
+ else if (pthread == curthread) {
/*
- * A thread was found that can handle the signal.
- * Save the context of the currently running thread
- * so that we can switch to another thread without
- * losing track of where the current thread left off.
- * This also applies if the current thread is the
- * thread to be signaled.
+ * Unblock the signal and restore the process signal
+ * mask in case we don't return from the handler:
*/
- thread_sig_savecontext(curthread, ucp);
+ _thread_sigq[sig - 1].blocked = 0;
+ __sys_sigprocmask(SIG_SETMASK, &_process_sigmask, NULL);
+
+ /* Call the signal handler for the current thread: */
+ thread_sig_invoke_handler(sig, info, ucp);
+
+ /*
+ * Set the process signal mask in the context; it
+ * could have changed by the handler.
+ */
+ ucp->uc_sigmask = _process_sigmask;
+
+ /* Resume the interrupted thread: */
+ __sys_sigreturn(ucp);
+ } else {
+ DBG_MSG("Got signal %d, adding frame to thread %p\n",
+ sig, pthread);
/* Setup the target thread to receive the signal: */
thread_sig_add(pthread, sig, /*has_args*/ 1);
@@ -231,8 +228,6 @@ _thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
DBG_MSG("Finished adding frame, head of prio list %p\n",
pthread_h);
}
- else
- DBG_MSG("No thread to handle signal %d\n", sig);
SIG_SET_INACTIVE();
/*
@@ -241,8 +236,8 @@ _thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
* signal and the currently running thread is not in a
* signal handler.
*/
- if ((pthread == curthread) || ((pthread_h != NULL) &&
- (pthread_h->active_priority > curthread->active_priority))) {
+ if ((pthread_h != NULL) &&
+ (pthread_h->active_priority > curthread->active_priority)) {
/* Enter the kernel scheduler: */
_thread_kern_sched(ucp);
}
@@ -255,27 +250,57 @@ _thread_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
}
static void
-thread_sig_savecontext(pthread_t pthread, ucontext_t *ucp)
-{
- memcpy(&pthread->ctx.uc, ucp, sizeof(*ucp));
-
- /* XXX - Save FP registers too? */
- FP_SAVE_UC(&pthread->ctx.uc);
+thread_sig_invoke_handler(int sig, siginfo_t *info, ucontext_t *ucp)
+ {
+ struct pthread *curthread = _get_curthread();
+ void (*sigfunc)(int, siginfo_t *, void *);
+ int saved_seqno;
+ sigset_t saved_sigmask;
- /* Mark the context saved as a ucontext: */
- pthread->ctxtype = CTX_UC;
+ /* Invoke the signal handler without going through the scheduler:
+ */
+ DBG_MSG("Got signal %d, calling handler for current thread %p\n",
+ sig, curthread);
+
+ /* Save the threads signal mask: */
+ saved_sigmask = curthread->sigmask;
+ saved_seqno = curthread->sigmask_seqno;
+
+ /* Setup the threads signal mask: */
+ SIGSETOR(curthread->sigmask, _thread_sigact[sig - 1].sa_mask);
+ sigaddset(&curthread->sigmask, sig);
+
+ /*
+ * Check that a custom handler is installed and if
+ * the signal is not blocked:
+ */
+ sigfunc = _thread_sigact[sig - 1].sa_sigaction;
+ if (((__sighandler_t *)sigfunc != SIG_DFL) &&
+ ((__sighandler_t *)sigfunc != SIG_IGN)) {
+ if (((_thread_sigact[sig - 1].sa_flags & SA_SIGINFO) != 0) ||
+ (info == NULL))
+ (*(sigfunc))(sig, info, ucp);
+ else
+ (*(sigfunc))(sig, (siginfo_t *)info->si_code, ucp);
+ }
+ /*
+ * Only restore the signal mask if it hasn't been changed by the
+ * application during invocation of the signal handler:
+ */
+ if (curthread->sigmask_seqno == saved_seqno)
+ curthread->sigmask = saved_sigmask;
}
/*
* Find a thread that can handle the signal.
*/
-pthread_t
+struct pthread *
thread_sig_find(int sig)
{
struct pthread *curthread = _get_curthread();
int handler_installed;
- pthread_t pthread, pthread_next;
- pthread_t suspended_thread, signaled_thread;
+ struct pthread *pthread, *pthread_next;
+ struct pthread *suspended_thread, *signaled_thread;
DBG_MSG("Looking for thread to handle signal %d\n", sig);
/* Check if the signal requires a dump of thread information: */
@@ -416,7 +441,7 @@ thread_sig_find(int sig)
}
void
-_thread_sig_check_pending(pthread_t pthread)
+_thread_sig_check_pending(struct pthread *pthread)
{
sigset_t sigset;
int i;
@@ -452,7 +477,7 @@ _thread_sig_check_pending(pthread_t pthread)
void
_thread_sig_handle_pending(void)
{
- pthread_t pthread;
+ struct pthread *pthread;
int i, sig;
PTHREAD_ASSERT(_thread_kern_in_sched != 0,
@@ -493,7 +518,7 @@ _thread_sig_handle_pending(void)
static void
thread_sig_handle_special(int sig)
{
- pthread_t pthread, pthread_next;
+ struct pthread *pthread, *pthread_next;
int i;
switch (sig) {
@@ -567,7 +592,7 @@ thread_sig_handle_special(int sig)
* unmasked.
*/
static void
-thread_sig_add(pthread_t pthread, int sig, int has_args)
+thread_sig_add(struct pthread *pthread, int sig, int has_args)
{
int restart;
int suppress_handler = 0;
@@ -775,7 +800,7 @@ thread_sig_add(pthread_t pthread, int sig, int has_args)
}
static void
-thread_sig_check_state(pthread_t pthread, int sig)
+thread_sig_check_state(struct pthread *pthread, int sig)
{
/*
* Process according to thread state:
@@ -865,7 +890,7 @@ thread_sig_check_state(pthread_t pthread, int sig)
* Send a signal to a specific thread (ala pthread_kill):
*/
void
-_thread_sig_send(pthread_t pthread, int sig)
+_thread_sig_send(struct pthread *pthread, int sig)
{
struct pthread *curthread = _get_curthread();
@@ -898,17 +923,13 @@ _thread_sig_send(pthread_t pthread, int sig)
/* Return the signal number: */
pthread->signo = sig;
- } else if (pthread == curthread) {
+ } else if (sigismember(&pthread->sigmask, sig))
/* Add the signal to the pending set: */
sigaddset(&pthread->sigpend, sig);
- if (!sigismember(&pthread->sigmask, sig)) {
- /*
- * Call the kernel scheduler which will safely
- * install a signal frame for this thread:
- */
- _thread_kern_sched_sig();
- }
- } else if (!sigismember(&pthread->sigmask, sig)) {
+ else if (pthread == curthread)
+ /* Call the signal handler for the current thread: */
+ thread_sig_invoke_handler(sig, NULL, NULL);
+ else {
/* Protect the scheduling queues: */
_thread_kern_sig_defer();
/*
@@ -918,9 +939,6 @@ _thread_sig_send(pthread_t pthread, int sig)
thread_sig_add(pthread, sig, /* has args */ 0);
/* Unprotect the scheduling queues: */
_thread_kern_sig_undefer();
- } else {
- /* Increment the pending signal count. */
- sigaddset(&pthread->sigpend,sig);
}
}
}
@@ -933,7 +951,6 @@ _thread_sig_send(pthread_t pthread, int sig)
void
_thread_sig_wrapper(void)
{
- void (*sigfunc)(int, siginfo_t *, void *);
struct pthread_signal_frame *psf;
struct pthread *thread = _get_curthread();
@@ -994,27 +1011,13 @@ _thread_sig_wrapper(void)
thread->sig_defer_count = 0;
/*
- * Check that a custom handler is installed and if the signal
- * is not blocked:
+ * Dispatch the signal via the custom signal handler:
*/
- sigfunc = _thread_sigact[psf->signo - 1].sa_sigaction;
- if (((__sighandler_t *)sigfunc != SIG_DFL) &&
- ((__sighandler_t *)sigfunc != SIG_IGN)) {
- DBG_MSG("_thread_sig_wrapper: Calling signal handler for "
- "thread 0x%p\n", thread);
- /*
- * Dispatch the signal via the custom signal
- * handler:
- */
- if (psf->sig_has_args == 0)
- (*(sigfunc))(psf->signo, NULL, NULL);
- else if ((_thread_sigact[psf->signo - 1].sa_flags &
- SA_SIGINFO) != 0)
- (*(sigfunc))(psf->signo, &psf->siginfo, &psf->uc);
- else
- (*(sigfunc))(psf->signo,
- (siginfo_t *)psf->siginfo.si_code, &psf->uc);
- }
+ if (psf->sig_has_args == 0)
+ thread_sig_invoke_handler(psf->signo, NULL, NULL);
+ else
+ thread_sig_invoke_handler(psf->signo, &psf->siginfo, &psf->uc);
+
/*
* Call the kernel scheduler to safely restore the frame and
* schedule the next thread:
@@ -1023,27 +1026,13 @@ _thread_sig_wrapper(void)
}
static void
-thread_sigframe_add(pthread_t thread, int sig, int has_args)
+thread_sigframe_add(struct pthread *thread, int sig, int has_args)
{
struct pthread_signal_frame *psf = NULL;
- unsigned long stackp = 0;
+ unsigned long stackp;
- /* Get the top of the threads stack: */
- switch (thread->ctxtype) {
- case CTX_JB:
- case CTX_JB_NOSIG:
- stackp = GET_STACK_JB(thread->ctx.jb);
- break;
- case CTX_SJB:
- stackp = GET_STACK_SJB(thread->ctx.sigjb);
- break;
- case CTX_UC:
- stackp = GET_STACK_UC(&thread->ctx.uc);
- break;
- default:
- PANIC("Invalid thread context type");
- break;
- }
+ /* Get the top of the threads stack: */
+ stackp = GET_STACK_JB(thread->ctx.jb);
/*
* Leave a little space on the stack and round down to the
@@ -1077,8 +1066,6 @@ thread_sigframe_add(pthread_t thread, int sig, int has_args)
/* Set up the new frame: */
thread->curframe = psf;
- thread->ctxtype = CTX_JB_NOSIG;
- thread->longjmp_val = 1;
thread->flags &= PTHREAD_FLAGS_PRIVATE | PTHREAD_FLAGS_TRACE |
PTHREAD_FLAGS_IN_SYNCQ;
/*
@@ -1091,10 +1078,10 @@ thread_sigframe_add(pthread_t thread, int sig, int has_args)
}
void
-_thread_sigframe_restore(pthread_t thread, struct pthread_signal_frame *psf)
+_thread_sigframe_restore(struct pthread *thread,
+ struct pthread_signal_frame *psf)
{
- thread->ctxtype = psf->ctxtype;
- memcpy(&thread->ctx.uc, &psf->ctx.uc, sizeof(thread->ctx.uc));
+ memcpy(&thread->ctx, &psf->ctx, sizeof(thread->ctx));
/*
* Only restore the signal mask if it hasn't been changed
* by the application during invocation of the signal handler:
@@ -1107,16 +1094,14 @@ _thread_sigframe_restore(pthread_t thread, struct pthread_signal_frame *psf)
thread->state = psf->saved_state.psd_state;
thread->flags = psf->saved_state.psd_flags;
thread->interrupted = psf->saved_state.psd_interrupted;
- thread->longjmp_val = psf->saved_state.psd_longjmp_val;
thread->signo = psf->saved_state.psd_signo;
thread->sig_defer_count = psf->saved_state.psd_sig_defer_count;
}
static void
-thread_sigframe_save(pthread_t thread, struct pthread_signal_frame *psf)
+thread_sigframe_save(struct pthread *thread, struct pthread_signal_frame *psf)
{
- psf->ctxtype = thread->ctxtype;
- memcpy(&psf->ctx.uc, &thread->ctx.uc, sizeof(thread->ctx.uc));
+ memcpy(&psf->ctx, &thread->ctx, sizeof(thread->ctx));
psf->saved_state.psd_sigmask = thread->sigmask;
psf->saved_state.psd_curframe = thread->curframe;
psf->saved_state.psd_wakeup_time = thread->wakeup_time;
@@ -1125,7 +1110,6 @@ thread_sigframe_save(pthread_t thread, struct pthread_signal_frame *psf)
psf->saved_state.psd_flags = thread->flags &
(PTHREAD_FLAGS_PRIVATE | PTHREAD_FLAGS_TRACE);
psf->saved_state.psd_interrupted = thread->interrupted;
- psf->saved_state.psd_longjmp_val = thread->longjmp_val;
psf->saved_state.psd_sigmask_seqno = thread->sigmask_seqno;
psf->saved_state.psd_signo = thread->signo;
psf->saved_state.psd_sig_defer_count = thread->sig_defer_count;
OpenPOWER on IntegriCloud