0.6.10.13:
[sbcl.git] / src / runtime / interrupt.c
index fdf1ab2..94b2de8 100644 (file)
  * files for more information.
  */
 
-/*
- * $Header$
- */
-
 #include <stdio.h>
 
 #include <signal.h>
@@ -80,11 +76,12 @@ os_context_t *lisp_interrupt_contexts[MAX_INTERRUPTS];
  * However, some signals need special handling, e.g. the SIGSEGV (for
  * Linux) or SIGBUS (for FreeBSD) used by the garbage collector to
  * detect violations of write protection, because some cases of such
- * signals are handled at C level and never passed on to Lisp. For
- * such signals, we still store any Lisp-level handler in
- * interrupt_handlers[..], but for the outermost handle we use the
- * value from interrupt_low_level_handlers[..], instead of the
- * ordinary interrupt_handle_now(..) or interrupt_handle_later(..).
+ * signals (e.g. GC-related violations of write protection) are
+ * handled at C level and never passed on to Lisp. For such signals,
+ * we still store any Lisp-level handler in interrupt_handlers[..],
+ * but for the outermost handle we use the value from
+ * interrupt_low_level_handlers[..], instead of the ordinary
+ * interrupt_handle_now(..) or interrupt_handle_later(..).
  *
  * -- WHN 20000728 */
 void (*interrupt_low_level_handlers[NSIG]) (int, siginfo_t*, void*) = {0};
@@ -113,11 +110,11 @@ fake_foreign_function_call(os_context_t *context)
 
     /* Get current Lisp state from context. */
 #ifdef reg_ALLOC
-    current_dynamic_space_free_pointer =
+    dynamic_space_free_pointer =
        (lispobj *)(*os_context_register_addr(context, reg_ALLOC));
 #ifdef alpha
-    if ((long)current_dynamic_space_free_pointer & 1) {
-      lose("dead in fake_foreign_function_call, context = %x", context);
+    if ((long)dynamic_space_free_pointer & 1) {
+       lose("dead in fake_foreign_function_call, context = %x", context);
     }
 #endif
 #endif
@@ -152,12 +149,13 @@ fake_foreign_function_call(os_context_t *context)
             oldcont = (lispobj)(*os_context_register_addr(context, reg_OCFP));
         }
     }
-    /* ### We can't tell if we are still in the caller if it had to
-     * reg_ALLOCate the stack frame due to stack arguments. */
+    /* ### We can't tell whether we are still in the caller if it had
+     * to reg_ALLOCate the stack frame due to stack arguments. */
     /* ### Can anything strange happen during return? */
-    else
+    else {
         /* normal case */
         oldcont = (lispobj)(*os_context_register_addr(context, reg_CFP));
+    }
 
     current_control_stack_pointer = current_control_frame_pointer + 8;
 
@@ -212,7 +210,7 @@ undo_fake_foreign_function_call(os_context_t *context)
 #ifdef reg_ALLOC
     /* Put the dynamic space free pointer back into the context. */
     *os_context_register_addr(context, reg_ALLOC) =
-        (unsigned long) current_dynamic_space_free_pointer;
+        (unsigned long) dynamic_space_free_pointer;
 #endif
 }
 
@@ -222,7 +220,7 @@ void
 interrupt_internal_error(int signal, siginfo_t *info, os_context_t *context,
                         boolean continuable)
 {
-    lispobj context_sap;
+    lispobj context_sap = 0;
 
     fake_foreign_function_call(context);
 
@@ -259,7 +257,9 @@ interrupt_internal_error(int signal, siginfo_t *info, os_context_t *context,
 void
 interrupt_handle_pending(os_context_t *context)
 {
+#ifndef __i386__
     boolean were_in_lisp = !foreign_function_call_active;
+#endif
 
     SetSymbolValue(INTERRUPT_PENDING, NIL);
 
@@ -304,12 +304,27 @@ void
 interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
 {
     os_context_t *context = (os_context_t*)void_context;
-    int were_in_lisp;
+#ifndef __i386__
+    boolean were_in_lisp;
+#endif
     union interrupt_handler handler;
 
-#ifdef __linux__
-    SET_FPU_CONTROL_WORD(context->__fpregs_mem.cw);
-#endif
+    /* FIXME: The CMU CL we forked off of had this Linux-only
+     * operation here. Newer CMU CLs (e.g. 18c) have hairier
+     * Linux/i386-only logic here. SBCL seems to be more reliable
+     * without anything here. However, if we start supporting code
+     * which sets the rounding mode, then we may want to do something
+     * special to force the rounding mode back to some standard value
+     * here, so that ISRs can have a standard environment. (OTOH, if
+     * rounding modes are under user control, then perhaps we should
+     * leave this up to the user.)
+     *
+     * In the absence of a test case to show that this is really a
+     * problem, we just suppress this code completely (just like the
+     * parallel code in maybe_now_maybe_later).
+     * #ifdef __linux__
+     *    SET_FPU_CONTROL_WORD(context->__fpregs_mem.cw);
+     * #endif */
 
     handler = interrupt_handlers[signal];
 
@@ -317,8 +332,8 @@ interrupt_handle_now(int signal, siginfo_t *info, void *void_context)
        return;
     }
 
-    were_in_lisp = !foreign_function_call_active;
 #ifndef __i386__
+    were_in_lisp = !foreign_function_call_active;
     if (were_in_lisp)
 #endif
     {
@@ -383,14 +398,14 @@ maybe_now_maybe_later(int signal, siginfo_t *info, void *void_context)
 
     /* FIXME: See Debian cmucl 2.4.17, and mail from DTC on the CMU CL
      * mailing list 23 Oct 1999, for changes in FPU handling at
-     * interrupt time which should be ported into SBCL. 
+     * interrupt time which should be ported into SBCL. Also see the
+     * analogous logic at the head of interrupt_handle_now for
+     * more related FIXME stuff. 
      *
-     * (Is this related to the way that it seems that if we do decide
-     * to handle the interrupt later, we've now screwed up the FPU
-     * control word?) */
-#ifdef __linux__
-    SET_FPU_CONTROL_WORD(context->__fpregs_mem.cw);
-#endif
+     * For now, we just suppress this code completely.
+     * #ifdef __linux__
+     *    SET_FPU_CONTROL_WORD(context->__fpregs_mem.cw);
+     * #endif */
 
     if (SymbolValue(INTERRUPTS_ENABLED) == NIL) {
 
@@ -447,7 +462,7 @@ gc_trigger_hit(int signal, siginfo_t *info, os_context_t *context)
                                                      context);
 
        return (badaddr >= current_auto_gc_trigger &&
-               badaddr < current_dynamic_space + DYNAMIC_SPACE_SIZE);
+               badaddr < DYNAMIC_SPACE_START + DYNAMIC_SPACE_SIZE);
     }
 }
 #endif