X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;ds=inline;f=src%2Fruntime%2Finterrupt.c;h=94b2de85dac4fd03f2148c25b0124c346a7f4bbf;hb=4fc9d21ae1d8a6a2f8ff70f589d5da103203de13;hp=fdf1ab253b415aacc09c49609be7264875a334ab;hpb=a530bbe337109d898d5b4a001fc8f1afa3b5dc39;p=sbcl.git diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index fdf1ab2..94b2de8 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -13,10 +13,6 @@ * files for more information. */ -/* - * $Header$ - */ - #include #include @@ -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