* 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.
(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
#include "globals.h"
#include "validate.h"
-#ifdef FOREIGN_FUNCTION_CALL_FLAG
+#ifndef LISP_FEATURE_SB_THREAD
int foreign_function_call_active;
#endif
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);
#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;
# define POINTERSIZE 4
# endif
-#ifdef FOREIGN_FUNCTION_CALL_FLAG
+#ifndef LISP_FEATURE_SB_THREAD
EXTERN(foreign_function_call_active, 4)
#endif
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
}
/* 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);
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);
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);
}
(*handler.c)(signal, info, context);
}
-#ifdef FOREIGN_FUNCTION_CALL_FLAG
if (were_in_lisp)
-#endif
{
undo_fake_foreign_function_call(context); /* block signals again */
}
* 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);
}
/* 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);
#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
;;; 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"