summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/thread')
-rw-r--r--lib/libpthread/thread/thr_create.c8
-rw-r--r--lib/libpthread/thread/thr_init.c12
-rw-r--r--lib/libpthread/thread/thr_kern.c138
-rw-r--r--lib/libpthread/thread/thr_private.h55
-rw-r--r--lib/libpthread/thread/thr_sig.c222
5 files changed, 167 insertions, 268 deletions
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
index 7c52b4b..70227ea 100644
--- a/lib/libpthread/thread/thr_create.c
+++ b/lib/libpthread/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/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c
index cac38dc..689e85b 100644
--- a/lib/libpthread/thread/thr_init.c
+++ b/lib/libpthread/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/libpthread/thread/thr_kern.c b/lib/libpthread/thread/thr_kern.c
index ec4c233..a4cc3c3 100644
--- a/lib/libpthread/thread/thr_kern.c
+++ b/lib/libpthread/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/libpthread/thread/thr_private.h b/lib/libpthread/thread/thr_private.h
index 65661f7..c294693 100644
--- a/lib/libpthread/thread/thr_private.h
+++ b/lib/libpthread/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/libpthread/thread/thr_sig.c b/lib/libpthread/thread/thr_sig.c
index a05f914..1bd93b7 100644
--- a/lib/libpthread/thread/thr_sig.c
+++ b/lib/libpthread/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