From: Gabor Melis Date: Mon, 16 Feb 2009 21:39:59 +0000 (+0000) Subject: 1.0.25.26: less interrupt handling leftovers X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=053874e1a563956dd86c5c122fbd1df37d7ceb1b;p=sbcl.git 1.0.25.26: less interrupt handling leftovers - less clear_pseudo_atomic_interrupted Remove it from the beginning of the protected sections in the runtime to match what we do in Lisp. - less resetting of signal mask Don't call reset-signal-mask from the toplevel, I don't think it's useful anymore and quite likely it was never more than duct tape. Even when unmasking of signals is called for (in INVOKE-INTERRUPTION), only unblock the deferrable ones: gc signals are unblocked in Lisp anyway. - removed unneeded sigemptyset on pending mask - move MIPS SIGTRAP workaround to the runtime --- diff --git a/src/code/interr.lisp b/src/code/interr.lisp index 232f1a6..8ac4f7a 100644 --- a/src/code/interr.lisp +++ b/src/code/interr.lisp @@ -426,14 +426,6 @@ (multiple-value-bind (name sb!debug:*stack-top-hint*) (find-interrupted-name-and-frame) (/show0 "back from FIND-INTERRUPTED-NAME") - ;; Unblock trap signal here, we unwound the stack and can't return. - ;; FIXME: Should we not reset the _entire_ mask, but just - ;; restore it to the state before we got the condition? - ;; FIXME 2: Signals are currently unblocked in - ;; interrupt.c:internal_error before we do stack unwinding, can this - ;; introduce a race condition? - #!+(and linux mips) - (sb!unix::reset-signal-mask) (let ((fp (int-sap (sb!vm:context-register alien-context sb!vm::cfp-offset))) (handler (and (< -1 error-number (length *internal-errors*)) diff --git a/src/code/target-signal.lisp b/src/code/target-signal.lisp index a341207..53344e1 100644 --- a/src/code/target-signal.lisp +++ b/src/code/target-signal.lisp @@ -36,11 +36,9 @@ ;; deferrable interrupts before arranging return to lisp. This is ;; safe because we can't get a pending interrupt before we unblock ;; signals. - ;; - ;; FIXME: Should we not reset the _entire_ mask, but just - ;; restore it to the state before we got the interrupt? - (reset-signal-mask) - (let ((sb!debug:*stack-top-hint* (nth-value 1 (sb!kernel:find-interrupted-name-and-frame)))) + (unblock-deferrable-signals) + (let ((sb!debug:*stack-top-hint* + (nth-value 1 (sb!kernel:find-interrupted-name-and-frame)))) (allow-with-interrupts (funcall function)))))) (defmacro in-interruption ((&key) &body body) @@ -75,9 +73,8 @@ ;;; doing things the SBCL way and moving this kind of C-level work ;;; down to C wrapper functions.) -;;; When inappropriate build options are used, this also prints messages -;;; listing the signals that were masked -(sb!alien:define-alien-routine "reset_signal_mask" sb!alien:void) +(sb!alien:define-alien-routine "unblock_deferrable_signals" sb!alien:void) +(sb!alien:define-alien-routine "unblock_gc_signals" sb!alien:void) ;;;; C routines that actually do all the work of establishing signal handlers @@ -180,7 +177,8 @@ (ignore-interrupt sigpipe) (enable-interrupt sigalrm #'sigalrm-handler) #!+hpux (ignore-interrupt sigxcpu) - (sb!unix::reset-signal-mask) + (unblock-deferrable-signals) + (unblock-gc-signals) (values)) ;;;; etc. diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index ca74663..d4a90a5 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -823,7 +823,7 @@ around and can be retrieved by JOIN-THREAD." ;; now that most things have a chance to ;; work properly without messing up other ;; threads, it's time to enable signals - (sb!unix::reset-signal-mask) + (sb!unix::unblock-deferrable-signals) (setf (thread-result thread) (cons t (multiple-value-list diff --git a/src/code/toplevel.lisp b/src/code/toplevel.lisp index bbebd5b..f938244 100644 --- a/src/code/toplevel.lisp +++ b/src/code/toplevel.lisp @@ -620,7 +620,6 @@ that provides the REPL for the system. Assumes that *STANDARD-INPUT* and (with-simple-restart (abort "~@") (catch 'toplevel-catcher - #!-win32 (sb!unix::reset-signal-mask) ;; In the event of a control-stack-exhausted-error, we ;; should have unwound enough stack by the time we get ;; here that this is now possible. diff --git a/src/runtime/alloc.c b/src/runtime/alloc.c index 19518e4..f42be24 100644 --- a/src/runtime/alloc.c +++ b/src/runtime/alloc.c @@ -41,7 +41,6 @@ pa_alloc(int bytes, int page_type_flag) struct thread *th = arch_os_get_current_thread(); /* FIXME: OOAO violation: see arch_pseudo_* */ - clear_pseudo_atomic_interrupted(th); set_pseudo_atomic_atomic(th); result = general_alloc(bytes, page_type_flag); #if 0 diff --git a/src/runtime/dynbind.c b/src/runtime/dynbind.c index 1c84e5b..bb964bf 100644 --- a/src/runtime/dynbind.c +++ b/src/runtime/dynbind.c @@ -44,7 +44,6 @@ void bind_variable(lispobj symbol, lispobj value, void *th) if(!sym->tls_index) { lispobj *tls_index_lock= &((struct symbol *)native_pointer(TLS_INDEX_LOCK))->value; - clear_pseudo_atomic_interrupted(th); set_pseudo_atomic_atomic(th); get_spinlock(tls_index_lock,(long)th); if(!sym->tls_index) { diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 405217f..2d28c7d 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -206,33 +206,27 @@ static void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*); #endif union interrupt_handler interrupt_handlers[NSIG]; -/* At the toplevel repl we routinely call this function. The signal - * mask ought to be clear anyway most of the time, but may be non-zero - * if we were interrupted e.g. while waiting for a queue. */ - void -reset_signal_mask(void) +block_blockable_signals(void) { #ifndef LISP_FEATURE_WIN32 - sigset_t new; - sigemptyset(&new); - thread_sigmask(SIG_SETMASK,&new,0); + thread_sigmask(SIG_BLOCK, &blockable_sigset, 0); #endif } void -block_blockable_signals(void) +block_deferrable_signals(void) { #ifndef LISP_FEATURE_WIN32 - thread_sigmask(SIG_BLOCK, &blockable_sigset, 0); + thread_sigmask(SIG_BLOCK, &deferrable_sigset, 0); #endif } void -block_deferrable_signals(void) +unblock_deferrable_signals(void) { #ifndef LISP_FEATURE_WIN32 - thread_sigmask(SIG_BLOCK, &deferrable_sigset, 0); + thread_sigmask(SIG_UNBLOCK, &deferrable_sigset, 0); #endif } @@ -406,6 +400,16 @@ interrupt_internal_error(os_context_t *context, boolean continuable) thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); #endif +#if defined(LISP_FEATURE_LINUX) && defined(LISP_FEATURE_MIPS) + /* Workaround for blocked SIGTRAP. */ + { + sigset_t newset; + sigemptyset(&newset); + sigaddset(&newset, SIGTRAP); + thread_sigmask(SIG_UNBLOCK, &newset, 0); + } +#endif + SHOW("in interrupt_internal_error"); #ifdef QSHOW /* Display some rudimentary debugging information about the @@ -497,7 +501,6 @@ interrupt_handle_pending(os_context_t *context) * blocked signals are unblocked */ sigcopyset(os_context_sigmask_addr(context), &data->pending_mask); - sigemptyset(&data->pending_mask); /* This will break on sparc linux: the deferred handler really wants * to be called with a void_context */ run_deferred_handler(data,(void *)context); diff --git a/src/runtime/interrupt.h b/src/runtime/interrupt.h index 579eeb6..210579b 100644 --- a/src/runtime/interrupt.h +++ b/src/runtime/interrupt.h @@ -119,6 +119,7 @@ extern void sigaddset_deferrable(sigset_t *s); extern void sigaddset_blockable(sigset_t *s); extern void block_blockable_signals(void); +extern void unblock_deferrable_signals(void); /* The void* casting here avoids having to mess with the various types * of function argument lists possible for signal handlers: diff --git a/version.lisp-expr b/version.lisp-expr index 1629827..c58fd81 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -17,4 +17,4 @@ ;;; checkins which aren't released. (And occasionally for internal ;;; versions, especially for internal versions off the main CVS ;;; branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".) -"1.0.25.25" +"1.0.25.26"