1.0.25.44: INTERRUPT-THREAD and timer improvements
[sbcl.git] / src / runtime / interrupt.c
index 78f34fb..3c6f716 100644 (file)
@@ -104,10 +104,6 @@ sigaddset_deferrable(sigset_t *s)
     sigaddset(s, SIGVTALRM);
     sigaddset(s, SIGPROF);
     sigaddset(s, SIGWINCH);
-
-#ifdef LISP_FEATURE_SB_THREAD
-    sigaddset(s, SIG_INTERRUPT_THREAD);
-#endif
 }
 
 void
@@ -129,10 +125,6 @@ sigdelset_deferrable(sigset_t *s)
     sigdelset(s, SIGVTALRM);
     sigdelset(s, SIGPROF);
     sigdelset(s, SIGWINCH);
-
-#ifdef LISP_FEATURE_SB_THREAD
-    sigdelset(s, SIG_INTERRUPT_THREAD);
-#endif
 }
 
 void
@@ -164,6 +156,19 @@ sigset_t blockable_sigset;
 sigset_t gc_sigset;
 #endif
 
+boolean
+deferrables_blocked_in_sigset_p(sigset_t *sigset)
+{
+#if !defined(LISP_FEATURE_WIN32)
+    int i;
+    for(i = 1; i < NSIG; i++) {
+        if (sigismember(&deferrable_sigset, i) && sigismember(sigset, i))
+            return 1;
+    }
+#endif
+    return 0;
+}
+
 void
 check_deferrables_unblocked_in_sigset_or_lose(sigset_t *sigset)
 {
@@ -189,6 +194,16 @@ check_deferrables_blocked_in_sigset_or_lose(sigset_t *sigset)
 }
 
 void
+check_deferrables_unblocked_or_lose(void)
+{
+#if !defined(LISP_FEATURE_WIN32)
+    sigset_t current;
+    fill_current_sigmask(&current);
+    check_deferrables_unblocked_in_sigset_or_lose(&current);
+#endif
+}
+
+void
 check_deferrables_blocked_or_lose(void)
 {
 #if !defined(LISP_FEATURE_WIN32)
@@ -669,24 +684,24 @@ interrupt_handle_pending(os_context_t *context)
 
     check_blockables_blocked_or_lose();
 
-    /* If GC/SIG_STOP_FOR_GC stroke during PA and there was no pending
+    /* If GC/SIG_STOP_FOR_GC struck during PA and there was no pending
      * handler, then the pending mask was saved and
      * gc_blocked_deferrables set. Hence, there can be no pending
      * handler and it's safe to restore the pending mask.
      *
      * Note, that if gc_blocked_deferrables is false we may still have
-     * to GC. In this case, we are coming out of a WITHOUT-GCING. */
+     * to GC. In this case, we are coming out of a WITHOUT-GCING or a
+     * pseudo atomic was interrupt be a deferrable first. */
     if (data->gc_blocked_deferrables) {
         if (data->pending_handler)
             lose("GC blocked deferrables but still got a pending handler.");
         if (SymbolValue(GC_INHIBIT,thread)!=NIL)
             lose("GC blocked deferrables while GC is inhibited.");
-        /* restore the saved signal mask from the original signal
-         * (the one that interrupted us during the critical
-         * section) into the os_context for the signal we're
-         * currently in the handler for. This should ensure that
-         * when we return from the handler the blocked signals are
-         * unblocked */
+        /* Restore the saved signal mask from the original signal (the
+         * one that interrupted us during the critical section) into
+         * the os_context for the signal we're currently in the
+         * handler for. This should ensure that when we return from
+         * the handler the blocked signals are unblocked. */
         sigcopyset(os_context_sigmask_addr(context), &data->pending_mask);
         data->gc_blocked_deferrables = 0;
     }
@@ -706,6 +721,7 @@ interrupt_handle_pending(os_context_t *context)
           * is used in SUB-GC as part of the mechanism to supress
           * recursive gcs.*/
         if (SymbolValue(GC_PENDING,thread) == T) {
+
             /* Two reasons for doing this. First, if there is a
              * pending handler we don't want to run. Second, we are
              * going to clear pseudo atomic interrupted to avoid
@@ -722,7 +738,11 @@ interrupt_handle_pending(os_context_t *context)
 
             /* GC_PENDING is cleared in SUB-GC, or if another thread
              * is doing a gc already we will get a SIG_STOP_FOR_GC and
-             * that will clear it. */
+             * that will clear it.
+             *
+             * If there is a pending handler or gc was triggerred in a
+             * signal handler then maybe_gc won't run POST_GC and will
+             * return normally. */
             if (!maybe_gc(context))
                 lose("GC not inhibited but maybe_gc did not GC.");
 
@@ -1312,26 +1332,6 @@ arrange_return_to_lisp_function(os_context_t *context, lispobj function)
            (long)function));
 }
 
-#ifdef LISP_FEATURE_SB_THREAD
-
-/* FIXME: this function can go away when all lisp handlers are invoked
- * via arrange_return_to_lisp_function. */
-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);
-
-    FSHOW_SIGNAL((stderr,"/interrupt_thread_handler\n"));
-    check_blockables_blocked_or_lose();
-
-    /* let the handler enable interrupts again when it sees fit */
-    sigaddset_deferrable(os_context_sigmask_addr(context));
-    arrange_return_to_lisp_function(context,
-                                    StaticSymbolFunction(RUN_INTERRUPTION));
-}
-
-#endif
-
 /* KLUDGE: Theoretically the approach we use for undefined alien
  * variables should work for functions as well, but on PPC/Darwin
  * we get bus error at bogus addresses instead, hence this workaround,
@@ -1512,11 +1512,7 @@ undoably_install_low_level_interrupt_handler (int signal,
     sa.sa_flags = SA_SIGINFO | SA_RESTART
         | (sigaction_nodefer_works ? SA_NODEFER : 0);
 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
-    if((signal==SIG_MEMORY_FAULT)
-#ifdef SIG_INTERRUPT_THREAD
-       || (signal==SIG_INTERRUPT_THREAD)
-#endif
-       )
+    if((signal==SIG_MEMORY_FAULT))
         sa.sa_flags |= SA_ONSTACK;
 #endif