#include "sbcl.h"
#include "runtime.h"
+#include "globals.h"
+#include "os.h"
+#include "interrupt.h"
/* This is implemented in assembly language and called from C: */
-extern lispobj call_into_lisp(lispobj fun, lispobj *args, int nargs);
+extern lispobj call_into_lisp(lispobj fun, lispobj *args, int nargs)
+#ifdef LISP_FEATURE_X86_64
+ __attribute__((sysv_abi))
+#endif
+ ;
+
+static inline lispobj
+safe_call_into_lisp(lispobj fun, lispobj *args, int nargs)
+{
+#ifndef LISP_FEATURE_SB_SAFEPOINT
+ /* SIG_STOP_FOR_GC needs to be enabled before we can call lisp:
+ * otherwise two threads racing here may deadlock: the other will
+ * wait on the GC lock, and the other cannot stop the first
+ * one... */
+ check_gc_signals_unblocked_or_lose(0);
+#endif
+ return call_into_lisp(fun, args, nargs);
+}
#ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
/* These functions are an interface to the Lisp call-in facility.
lispobj *args = NULL;
FSHOW((stderr, "/entering funcall0(0x%lx)\n", (long)function));
- return call_into_lisp(function, args, 0);
+ return safe_call_into_lisp(function, args, 0);
}
lispobj
funcall1(lispobj function, lispobj arg0)
{
lispobj args[1];
args[0] = arg0;
- return call_into_lisp(function, args, 1);
+ return safe_call_into_lisp(function, args, 1);
}
lispobj
lispobj args[2];
args[0] = arg0;
args[1] = arg1;
- return call_into_lisp(function, args, 2);
+ return safe_call_into_lisp(function, args, 2);
}
lispobj
args[0] = arg0;
args[1] = arg1;
args[2] = arg2;
- return call_into_lisp(function, args, 3);
+ return safe_call_into_lisp(function, args, 3);
}
#else
lispobj
funcall0(lispobj function)
{
- lispobj *args = current_control_stack_pointer;
+ lispobj **stack_pointer
+ = &access_control_stack_pointer(arch_os_get_current_thread());
+ lispobj *args = *stack_pointer;
- return call_into_lisp(function, args, 0);
+ return safe_call_into_lisp(function, args, 0);
}
lispobj
funcall1(lispobj function, lispobj arg0)
{
- lispobj *args = current_control_stack_pointer;
+ lispobj **stack_pointer
+ = &access_control_stack_pointer(arch_os_get_current_thread());
+ lispobj *args = *stack_pointer;
- current_control_stack_pointer += 1;
+ *stack_pointer += 1;
args[0] = arg0;
- return call_into_lisp(function, args, 1);
+ return safe_call_into_lisp(function, args, 1);
}
lispobj
funcall2(lispobj function, lispobj arg0, lispobj arg1)
{
- lispobj *args = current_control_stack_pointer;
+ lispobj **stack_pointer
+ = &access_control_stack_pointer(arch_os_get_current_thread());
+ lispobj *args = *stack_pointer;
- current_control_stack_pointer += 2;
+ *stack_pointer += 2;
args[0] = arg0;
args[1] = arg1;
- return call_into_lisp(function, args, 2);
+ return safe_call_into_lisp(function, args, 2);
}
lispobj
funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
{
- lispobj *args = current_control_stack_pointer;
+ lispobj **stack_pointer
+ = &access_control_stack_pointer(arch_os_get_current_thread());
+ lispobj *args = *stack_pointer;
- current_control_stack_pointer += 3;
+ *stack_pointer += 3;
args[0] = arg0;
args[1] = arg1;
args[2] = arg2;
- return call_into_lisp(function, args, 3);
+ return safe_call_into_lisp(function, args, 3);
}
#endif