From: Alastair Bridgewater Date: Sat, 7 Aug 2010 13:42:40 +0000 (+0000) Subject: 1.0.41.17: runtime: Make foreign_function_call_active work with threaded targets. X-Git-Url: http://repo.macrolet.net/gitweb/?a=commitdiff_plain;h=716153dd41af2df6ad91939fb3dcf0ba99cd72cf;p=sbcl.git 1.0.41.17: runtime: Make foreign_function_call_active work with threaded targets. * Add a slot to the thread structure for the active flag. * Make the existing global variable only show up on unithread targets. * Introduce a wrapper macro to portably access the right slot on both theaded and unithread targets. * KLUDGE things up to maintain the old behavior on x86oids until someone gets around to fixing x86{,-64}-assem.S to set foreign_function_call_active properly. --- diff --git a/src/compiler/generic/objdef.lisp b/src/compiler/generic/objdef.lisp index d768bca..7863096 100644 --- a/src/compiler/generic/objdef.lisp +++ b/src/compiler/generic/objdef.lisp @@ -414,6 +414,12 @@ (interrupt-data :c-type "struct interrupt_data *" :length #!+alpha 2 #!-alpha 1) (stepping) + ;; For various reasons related to pseudo-atomic and interrupt + ;; handling, we need to know if the machine context is in Lisp code + ;; or not. On non-threaded targets, this is a global variable in + ;; the runtime, but it's clearly a per-thread value. + #!+sb-thread + (foreign-function-call-active :c-type "boolean") ;; KLUDGE: On alpha, until STEPPING we have been lucky and the 32 ;; bit slots came in pairs. However the C compiler will align ;; interrupt_contexts on a double word boundary. This logic should diff --git a/src/runtime/globals.c b/src/runtime/globals.c index 099acd2..5e84af0 100644 --- a/src/runtime/globals.c +++ b/src/runtime/globals.c @@ -22,7 +22,7 @@ #include "globals.h" #include "validate.h" -#ifdef FOREIGN_FUNCTION_CALL_FLAG +#ifndef LISP_FEATURE_SB_THREAD int foreign_function_call_active; #endif @@ -63,9 +63,18 @@ void globals_init(void) current_auto_gc_trigger = NULL; #endif -#ifdef FOREIGN_FUNCTION_CALL_FLAG +#ifndef LISP_FEATURE_SB_THREAD +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) + /* KLUDGE: x86oids always think they're in lisp code. See the + * comment at the bottom of + * interrupt.c/fake_foreign_function_call() and the lack of any + * access to foreign_function_call_active or the corresponding + * thread slot in x86{,-64}-assem.S. */ + foreign_function_call_active = 0; +#else foreign_function_call_active = 1; #endif +#endif #if defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_GCC_TLS) pthread_key_create(&specials,0); diff --git a/src/runtime/globals.h b/src/runtime/globals.h index 679e626..a51964c 100644 --- a/src/runtime/globals.h +++ b/src/runtime/globals.h @@ -20,16 +20,15 @@ #include "sbcl.h" -/* Currently threads live only on x86oid platforms, but this thing - * cannot ever work with threads, so... */ -#if !defined(LISP_FEATURE_SB_THREAD) && !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) -#define FOREIGN_FUNCTION_CALL_FLAG -#endif - #ifndef LANGUAGE_ASSEMBLY -#ifdef FOREIGN_FUNCTION_CALL_FLAG +#ifdef LISP_FEATURE_SB_THREAD +#define foreign_function_call_active_p(thread) \ + (thread->foreign_function_call_active) +#else extern int foreign_function_call_active; +#define foreign_function_call_active_p(thread) \ + foreign_function_call_active #endif extern size_t dynamic_space_size; @@ -115,7 +114,7 @@ extern void globals_init(void); # define POINTERSIZE 4 # endif -#ifdef FOREIGN_FUNCTION_CALL_FLAG +#ifndef LISP_FEATURE_SB_THREAD EXTERN(foreign_function_call_active, 4) #endif diff --git a/src/runtime/interrupt.c b/src/runtime/interrupt.c index 123a576..9a02e7f 100644 --- a/src/runtime/interrupt.c +++ b/src/runtime/interrupt.c @@ -705,8 +705,11 @@ fake_foreign_function_call(os_context_t *context) thread->interrupt_contexts[context_index] = context; -#ifdef FOREIGN_FUNCTION_CALL_FLAG - foreign_function_call_active = 1; +#if !defined(LISP_FEATURE_X86) && !defined(LISP_FEATURE_X86_64) + /* x86oid targets don't maintain the foreign function call flag at + * all, so leave them to believe that they are never in foreign + * code. */ + foreign_function_call_active_p(thread) = 1; #endif } @@ -720,9 +723,7 @@ undo_fake_foreign_function_call(os_context_t *context) /* Block all blockable signals. */ block_blockable_signals(0, 0); -#ifdef FOREIGN_FUNCTION_CALL_FLAG - foreign_function_call_active = 0; -#endif + foreign_function_call_active_p(thread) = 0; /* Undo dynamic binding of FREE_INTERRUPT_CONTEXT_INDEX */ unbind(thread); @@ -954,9 +955,7 @@ interrupt_handle_pending(os_context_t *context) void interrupt_handle_now(int signal, siginfo_t *info, os_context_t *context) { -#ifdef FOREIGN_FUNCTION_CALL_FLAG boolean were_in_lisp; -#endif union interrupt_handler handler; check_blockables_blocked_or_lose(0); @@ -972,10 +971,8 @@ interrupt_handle_now(int signal, siginfo_t *info, os_context_t *context) return; } -#ifdef FOREIGN_FUNCTION_CALL_FLAG - were_in_lisp = !foreign_function_call_active; + were_in_lisp = !foreign_function_call_active_p(arch_os_get_current_thread()); if (were_in_lisp) -#endif { fake_foreign_function_call(context); } @@ -1032,9 +1029,7 @@ interrupt_handle_now(int signal, siginfo_t *info, os_context_t *context) (*handler.c)(signal, info, context); } -#ifdef FOREIGN_FUNCTION_CALL_FLAG if (were_in_lisp) -#endif { undo_fake_foreign_function_call(context); /* block signals again */ } diff --git a/src/runtime/ppc-arch.c b/src/runtime/ppc-arch.c index 4c8da5f..bdd1a40 100644 --- a/src/runtime/ppc-arch.c +++ b/src/runtime/ppc-arch.c @@ -99,7 +99,7 @@ arch_pseudo_atomic_atomic(os_context_t *context) * The foreign_function_call_active used to live at each call-site * to arch_pseudo_atomic_atomic, but this seems clearer. * --NS 2007-05-15 */ - return (!foreign_function_call_active) + return (!foreign_function_call_active_p(arch_os_get_current_thread())) && ((*os_context_register_addr(context,reg_ALLOC)) & 4); } @@ -318,7 +318,7 @@ handle_allocation_trap(os_context_t * context) /* I don't think it's possible for us NOT to be in lisp when we get * here. Remove this later? */ - were_in_lisp = !foreign_function_call_active; + were_in_lisp = !foreign_function_call_active_p(arch_os_get_current_thread()); if (were_in_lisp) { fake_foreign_function_call(context); diff --git a/src/runtime/thread.c b/src/runtime/thread.c index 2e61302..7ee7d2f 100644 --- a/src/runtime/thread.c +++ b/src/runtime/thread.c @@ -445,6 +445,16 @@ create_thread_struct(lispobj initial_function) { #ifdef LISP_FEATURE_GENCGC gc_set_region_empty(&th->alloc_region); #endif +#ifdef LISP_FEATURE_SB_THREAD + /* This parallels the same logic in globals.c for the + * single-threaded foreign_function_call_active, KLUDGE and + * all. */ +#if defined(LISP_FEATURE_X86) || defined(LISP_FEATURE_X86_64) + th->foreign_function_call_active = 0; +#else + th->foreign_function_call_active = 1; +#endif +#endif #ifndef LISP_FEATURE_SB_THREAD /* the tls-points-into-struct-thread trick is only good for threaded diff --git a/version.lisp-expr b/version.lisp-expr index 130c545..c3d9faf 100644 --- a/version.lisp-expr +++ b/version.lisp-expr @@ -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.41.16" +"1.0.41.17"