From: Nikodemus S. <de...@us...> - 2007-03-26 10:30:37
|
Update of /cvsroot/sbcl/sbcl/src/runtime In directory sc8-pr-cvs8.sourceforge.net:/tmp/cvs-serv4605/src/runtime Modified Files: interrupt.c Log Message: 1.0.4.3: interrupt and GC issues * Add WITHOUT-INTERRUPTS to WITHOUT-GCING. * Warn if WITH-INTERRUPTS nested in WITHOUT-GCING. * Make sure that SIG_STOP_FOR_GC and SIG_RESUME_FROM_GC are enabled on threaded builds before calling into SUB-GC from the runtime. * Better WITHOUT-GCING, WITHOUT-INTERRUPTS, and WITH-INTERRUPTS documentation. * Internals documentation about POSIX signal safety rules. Index: interrupt.c =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/interrupt.c,v retrieving revision 1.121 retrieving revision 1.122 diff -u -d -r1.121 -r1.122 --- interrupt.c 3 Mar 2007 00:42:02 -0000 1.121 +++ interrupt.c 26 Mar 2007 10:30:30 -0000 1.122 @@ -123,7 +123,7 @@ #endif void -check_blockables_blocked_or_lose() +check_blockables_blocked_or_lose(void) { #if !defined(LISP_FEATURE_WIN32) /* Get the current sigmask, by blocking the empty set. */ @@ -138,6 +138,41 @@ #endif } +void +check_gc_signals_unblocked_or_lose(void) +{ +#ifdef LISP_FEATURE_SB_THREAD +# if !defined(LISP_FEATURE_WIN32) + /* Get the current sigmask, by blocking the empty set. */ + sigset_t empty,current; + sigemptyset(&empty); + thread_sigmask(SIG_BLOCK, &empty, ¤t); + if (sigismember(¤t, SIG_STOP_FOR_GC)) + lose("SIG_STOP_FOR_GC blocked in thread %p at a bad place\n", + arch_os_get_current_thread()); +# if defined(SIG_RESUME_FROM_GC) + if (sigismember(¤t, SIG_RESUME_FROM_GC)) + lose("SIG_RESUME_FROM_GC blocked in thread %p at a bad place\n", + arch_os_get_current_thread()); +# endif +# endif +#endif +} + +void +unblock_gc_signals(void) +{ +#ifdef LISP_FEATURE_SB_THREAD + sigset_t new; + sigemptyset(&new); +#if defined(SIG_RESUME_FROM_GC) + sigaddset(&new,SIG_RESUME_FROM_GC); +#endif + sigaddset(&new,SIG_STOP_FOR_GC); + thread_sigmask(SIG_UNBLOCK,&new,0); +#endif +} + inline static void check_interrupts_enabled_or_lose(os_context_t *context) { @@ -1147,22 +1182,14 @@ * outer context. */ #ifndef LISP_FEATURE_WIN32 - if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) + if(SymbolValue(INTERRUPTS_ENABLED,thread)!=NIL) { thread_sigmask(SIG_SETMASK, os_context_sigmask_addr(context), 0); -#ifdef LISP_FEATURE_SB_THREAD - else { - sigset_t new; - sigemptyset(&new); -#if defined(SIG_RESUME_FROM_GC) - sigaddset(&new,SIG_RESUME_FROM_GC); -#endif - sigaddset(&new,SIG_STOP_FOR_GC); - thread_sigmask(SIG_UNBLOCK,&new,0); + check_gc_signals_unblocked_or_lose(); } -#endif + else + unblock_gc_signals(); #endif funcall0(SymbolFunction(SUB_GC)); - undo_fake_foreign_function_call(context); return 1; } |