#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
+#include <errno.h>
#include "sbcl.h"
#include "runtime.h"
#include "interr.h"
#include "genesis/fdefn.h"
#include "genesis/simple-fun.h"
+#include "genesis/cons.h"
sigset_t empty,current;
int i;
sigemptyset(&empty);
- sigprocmask(SIG_BLOCK, &empty, ¤t);
+ thread_sigmask(SIG_BLOCK, &empty, ¤t);
for(i=0;i<NSIG;i++) {
if (sigismember(&blockable_sigset, i) && !sigismember(¤t, i))
lose("blockable signal %d not blocked",i);
{
sigset_t new;
sigemptyset(&new);
- sigprocmask(SIG_SETMASK,&new,0);
+ thread_sigmask(SIG_SETMASK,&new,0);
}
sigset_t block;
sigemptyset(&block);
sigaddset_blockable(&block);
- sigprocmask(SIG_BLOCK, &block, 0);
+ thread_sigmask(SIG_BLOCK, &block, 0);
/* going back into Lisp */
foreign_function_call_active = 0;
context_sap = alloc_sap(context);
}
- sigprocmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
if (internal_errors_enabled) {
SHOW("in interrupt_internal_error");
lispobj info_sap,context_sap = alloc_sap(context);
info_sap = alloc_sap(info);
/* Allow signals again. */
- sigprocmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
#ifdef QSHOW_SIGNALS
SHOW("calling Lisp-level handler");
#endif
/* Allow signals again. */
- sigprocmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
(*handler.c)(signal, info, void_context);
}
SetSymbolValue(INTERRUPT_PENDING, T,thread);
#ifdef QSHOW_SIGNALS
FSHOW((stderr,
- "/maybe_defer_handler(%x,%d),thread=%d: deferred\n",
- (unsigned int)handler,signal,thread->pid));
+ "/maybe_defer_handler(%x,%d),thread=%ld: deferred\n",
+ (unsigned int)handler,signal,thread->os_thread));
#endif
return 1;
}
arch_set_pseudo_atomic_interrupted(context);
#ifdef QSHOW_SIGNALS
FSHOW((stderr,
- "/maybe_defer_handler(%x,%d),thread=%d: deferred(PA)\n",
- (unsigned int)handler,signal,thread->pid));
+ "/maybe_defer_handler(%x,%d),thread=%ld: deferred(PA)\n",
+ (unsigned int)handler,signal,thread->os_thread));
#endif
return 1;
}
#ifdef QSHOW_SIGNALS
FSHOW((stderr,
- "/maybe_defer_handler(%x,%d),thread=%d: not deferred\n",
- (unsigned int)handler,signal,thread->pid));
+ "/maybe_defer_handler(%x,%d),thread=%ld: not deferred\n",
+ (unsigned int)handler,signal,thread->os_thread));
#endif
return 0;
}
sigemptyset(&ss);
for(i=1;i<NSIG;i++) sigaddset(&ss,i); /* Block everything. */
- sigprocmask(SIG_BLOCK,&ss,0);
+ thread_sigmask(SIG_BLOCK,&ss,0);
/* The GC can't tell if a thread is a zombie, so this would be a
* good time to let the kernel reap any of our children in that
* awful state, to stop them from being waited for indefinitely.
* Userland reaping is done later when GC is finished */
- mark_dead_threads();
if(thread->state!=STATE_STOPPING) {
lose("sig_stop_for_gc_handler: wrong thread state: %ld\n",
fixnum_value(thread->state));
* user's backtrace makes (as much) sense (as usual) */
/* FIXME: what about restoring fp state? */
+ /* FIXME: what about restoring errno? */
#ifdef LISP_FEATURE_X86
/* Suppose the existence of some function that saved all
* registers, called call_into_lisp, then restored GP registers and
push ebp
mov ebp esp
- pushad
+ pushfl
+ pushal
push $0
push $0
pushl {address of function to call}
call 0x8058db0 <call_into_lisp>
addl $12,%esp
- popa
+ popal
+ popfl
leave
ret
void interrupt_thread_handler(int num, siginfo_t *info, void *v_context)
{
os_context_t *context = (os_context_t*)arch_os_get_context(&v_context);
- arrange_return_to_lisp_function(context,info->si_value.sival_int);
+ /* The order of interrupt execution is peculiar. If thread A
+ * interrupts thread B with I1, I2 and B for some reason recieves
+ * I1 when FUN2 is already on the list, then it is FUN2 that gets
+ * to run first. But when FUN2 is run SIG_INTERRUPT_THREAD is
+ * enabled again and I2 hits pretty soon in FUN2 and run
+ * FUN1. This is of course just one scenario, and the order of
+ * thread interrupt execution is undefined. */
+ struct thread *th=arch_os_get_current_thread();
+ struct cons *c;
+ get_spinlock(&th->interrupt_fun_lock,(long)th);
+ c=((struct cons *)native_pointer(th->interrupt_fun));
+ arrange_return_to_lisp_function(context,c->car);
+ th->interrupt_fun=(lispobj *)(c->cdr);
+ release_spinlock(&th->interrupt_fun_lock);
}
-void thread_exit_handler(int num, siginfo_t *info, void *v_context)
-{ /* called when a child thread exits */
- mark_dead_threads();
-}
-
#endif
/* KLUDGE: Theoretically the approach we use for undefined alien
* protection so the error handler has some headroom, protect the
* previous page so that we can catch returns from the guard page
* and restore it. */
- protect_control_stack_guard_page(th->pid,0);
- protect_control_stack_return_guard_page(th->pid,1);
+ protect_control_stack_guard_page(th->os_thread,0);
+ protect_control_stack_return_guard_page(th->os_thread,1);
arrange_return_to_lisp_function
(context, SymbolFunction(CONTROL_STACK_EXHAUSTED_ERROR));
* unprotect this one. This works even if we somehow missed
* the return-guard-page, and hit it on our way to new
* exhaustion instead. */
- protect_control_stack_guard_page(th->pid,1);
- protect_control_stack_return_guard_page(th->pid,0);
+ protect_control_stack_guard_page(th->os_thread,1);
+ protect_control_stack_return_guard_page(th->os_thread,0);
return 1;
}
else if (addr >= undefined_alien_address &&
/* restore the signal mask from the interrupted context before
* calling into Lisp */
if (context)
- sigprocmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
+ thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0);
funcall0(SymbolFunction(SUB_GC));
sigemptyset(&new);
sigaddset(&new, signal);
- sigprocmask(SIG_BLOCK, &new, &old);
+ thread_sigmask(SIG_BLOCK, &new, &old);
sigemptyset(&new);
sigaddset_blockable(&new);
oldhandler = data->interrupt_handlers[signal];
data->interrupt_handlers[signal].c = handler;
- sigprocmask(SIG_SETMASK, &old, 0);
+ thread_sigmask(SIG_SETMASK, &old, 0);
FSHOW((stderr, "/leaving POSIX install_handler(%d, ..)\n", signal));