1.0.25.26: less interrupt handling leftovers
authorGabor Melis <mega@hotpop.com>
Mon, 16 Feb 2009 21:39:59 +0000 (21:39 +0000)
committerGabor Melis <mega@hotpop.com>
Mon, 16 Feb 2009 21:39:59 +0000 (21:39 +0000)
- 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

src/code/interr.lisp
src/code/target-signal.lisp
src/code/target-thread.lisp
src/code/toplevel.lisp
src/runtime/alloc.c
src/runtime/dynbind.c
src/runtime/interrupt.c
src/runtime/interrupt.h
version.lisp-expr

index 232f1a6..8ac4f7a 100644 (file)
          (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*))
index a341207..53344e1 100644 (file)
       ;; 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)
 
 \f
 ;;;; C routines that actually do all the work of establishing signal handlers
   (ignore-interrupt sigpipe)
   (enable-interrupt sigalrm #'sigalrm-handler)
   #!+hpux (ignore-interrupt sigxcpu)
-  (sb!unix::reset-signal-mask)
+  (unblock-deferrable-signals)
+  (unblock-gc-signals)
   (values))
 \f
 ;;;; etc.
index ca74663..d4a90a5 100644 (file)
@@ -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
index bbebd5b..f938244 100644 (file)
@@ -620,7 +620,6 @@ that provides the REPL for the system. Assumes that *STANDARD-INPUT* and
                (with-simple-restart
                    (abort "~@<Exit debugger, returning to top level.~@:>")
                  (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.
index 19518e4..f42be24 100644 (file)
@@ -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
index 1c84e5b..bb964bf 100644 (file)
@@ -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) {
index 405217f..2d28c7d 100644 (file)
@@ -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);
index 579eeb6..210579b 100644 (file)
@@ -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:
index 1629827..c58fd81 100644 (file)
@@ -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"