X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fruntime%2Ffuncall.c;h=c3724eb8c0cdfa426c9081a53c1ab8600a73be04;hb=534ad97e08a9725fb4c9618f47602d7e83583600;hp=815268ad33d9bce430c2e5f5eb2c2e76ff5b07e2;hpb=5f4fe75b7ee2b33e263097415240d198b6275de3;p=sbcl.git diff --git a/src/runtime/funcall.c b/src/runtime/funcall.c index 815268a..c3724eb 100644 --- a/src/runtime/funcall.c +++ b/src/runtime/funcall.c @@ -17,10 +17,24 @@ #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); +static inline lispobj +safe_call_into_lisp(lispobj fun, lispobj *args, int nargs) +{ + /* 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); + 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. * Since this is C we can know nothing about the calling environment. @@ -37,14 +51,14 @@ funcall0(lispobj function) 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 @@ -53,7 +67,7 @@ funcall2(lispobj function, lispobj arg0, lispobj arg1) 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 @@ -63,7 +77,7 @@ funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) 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 @@ -71,44 +85,52 @@ funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2) 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