mirror of
git://git.code.sf.net/p/sbcl/sbcl
synced 2026-09-10 07:26:40 -04:00
Fix post-GC crash in enter-foreign-callback
Resulting from change 338c975d
This commit is contained in:
parent
8e275cc17c
commit
8614c726b6
|
|
@ -254,8 +254,12 @@ statistics are appended to it."
|
|||
;;
|
||||
;; KLUDGE: Don't run the hooks in GC's if:
|
||||
;;
|
||||
;; A) this thread is dying, so that user-code never runs with
|
||||
;; (thread-alive-p *current-thread*) => nil
|
||||
;; A) this thread is dying or just born, so that user-code never runs with
|
||||
;; (thread-alive-p *current-thread*) => nil.
|
||||
;; The just-born case can happen with foreign threads that are unlucky
|
||||
;; enough to be elected to perform GC just as they begin executing
|
||||
;; ENTER-FOREIGN-CALLBACK. This definitely seems to happen with sb-safepoint.
|
||||
;; I'm not sure whether it can happen without sb-safepoint.
|
||||
;;
|
||||
;; B) interrupts are disabled somewhere up the call chain since we
|
||||
;; don't want to run user code in such a case.
|
||||
|
|
@ -266,7 +270,10 @@ statistics are appended to it."
|
|||
;; but it's not permissible to invoke CONDITION-NOTIFY from a
|
||||
;; dying thread, so we still need the guard for that, but not
|
||||
;; the guard for whether interupts are enabled.
|
||||
(when (sb-thread:thread-alive-p sb-thread:*current-thread*)
|
||||
(when (and
|
||||
#+sb-thread (/= 0 (sap-int (sb-vm::current-thread-offset-sap
|
||||
sb-vm::thread-lisp-thread-slot)))
|
||||
(sb-thread:thread-alive-p sb-thread:*current-thread*))
|
||||
#+sb-thread (alien-funcall (extern-alien "empty_thread_recyclebin" (function void)))
|
||||
(let ((threadp #+sb-thread (%instancep sb-impl::*finalizer-thread*)))
|
||||
(when threadp
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
# include <handleapi.h>
|
||||
# include <process.h>
|
||||
# include <processthreadsapi.h>
|
||||
# include <synchapi.h> // for WaitForSingleObject
|
||||
#else
|
||||
|
|
@ -22,7 +23,39 @@ char *salutations[8] = {
|
|||
int sharedvar;
|
||||
|
||||
#ifdef _WIN32
|
||||
long unsigned int doThatThing(void* void_arg)
|
||||
__stdcall unsigned int perftest_thread(LPVOID void_arg)
|
||||
#else
|
||||
void* perftest_thread(void* void_arg)
|
||||
#endif
|
||||
{
|
||||
struct thread_arg* arg = void_arg;
|
||||
int (*lispfun)() = arg->funkyfun;
|
||||
int ncalls = arg->n_calls;
|
||||
int i;
|
||||
for (i=0; i<ncalls; ++i) lispfun();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int minimal_perftest(void* ptr, int n_calls)
|
||||
{
|
||||
struct thread_arg arg;
|
||||
arg.funkyfun = ptr;
|
||||
arg.n_calls = n_calls;
|
||||
#ifdef _WIN32
|
||||
HANDLE thr;
|
||||
thr = (HANDLE)_beginthreadex(NULL, 0, perftest_thread, &arg, 0, NULL);
|
||||
WaitForSingleObject(thr,0xffffffff);
|
||||
CloseHandle(thr);
|
||||
#else
|
||||
pthread_t thr;
|
||||
pthread_create(&thr, 0, perftest_thread, &arg);
|
||||
pthread_join(thr,0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
__stdcall unsigned int doThatThing(void* void_arg)
|
||||
#else
|
||||
void* doThatThing(void* void_arg)
|
||||
#endif
|
||||
|
|
@ -63,7 +96,7 @@ int call_thing_from_threads(void* ptr, int n_threads, int n_calls)
|
|||
threads[i].arg.index = i + 1;
|
||||
threads[i].arg.n_calls = n_calls;
|
||||
#ifdef _WIN32
|
||||
threads[i].handle = CreateThread(NULL, 0, doThatThing, &threads[i].arg, 0, NULL);
|
||||
threads[i].handle = (HANDLE)_beginthreadex(NULL, 0, doThatThing, &threads[i].arg, 0, NULL);
|
||||
#else
|
||||
pthread_create(&threads[i].pthread_id, 0, doThatThing, &threads[i].arg);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -38,6 +38,14 @@
|
|||
:output t :error :output)
|
||||
(sb-alien:load-shared-object solib)))
|
||||
|
||||
;;;; Just exercise a ton of calls from 1 thread
|
||||
(sb-alien::define-alien-callback perftestcb int () 0)
|
||||
(defun trivial-call-test (n)
|
||||
(with-alien ((testfun (function int system-area-pointer int) :extern "minimal_perftest"))
|
||||
(alien-funcall testfun (alien-sap perftestcb) n)))
|
||||
(time (trivial-call-test 200000))
|
||||
|
||||
;;;;
|
||||
(defglobal *counter* 0)
|
||||
(declaim (fixnum *counter*))
|
||||
(defglobal *ok* (list t))
|
||||
|
|
|
|||
Loading…
Reference in a new issue