From 495f7dfb9c4ce0ba965f3297a4c94f6c75691b70 Mon Sep 17 00:00:00 2001 From: Gabor Melis Date: Tue, 11 Oct 2005 14:26:31 +0000 Subject: [PATCH] 0.9.5.36: nop * (ALIEN-FUNCALL ... (GET-LISP-OBJ-ADDRESS OBJ)) is racy with non-conservative gcs. Add a few WITH-PINNED-OBJECTS to the threading code in anticipation of exact gcs. --- src/code/target-alieneval.lisp | 1 + src/code/target-thread.lisp | 39 ++++++++++++++++++++++++--------------- src/compiler/x86/macros.lisp | 8 ++++++-- version.lisp-expr | 2 +- 4 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/code/target-alieneval.lisp b/src/code/target-alieneval.lisp index c670384..d6cb2be 100644 --- a/src/code/target-alieneval.lisp +++ b/src/code/target-alieneval.lisp @@ -792,6 +792,7 @@ ENTER-ALIEN-CALLBACK pulls the corresponsing trampoline out and calls it.") (argument-names arguments) (argument-specs (cddr specifier))) `(lambda (args-pointer result-pointer function) + ;; FIXME: the saps are not gc safe (let ((args-sap (int-sap (sb!kernel:get-lisp-obj-address args-pointer))) (res-sap (int-sap diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index 5df9968..7ca853f 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -11,6 +11,12 @@ (in-package "SB!THREAD") +;;; Of the WITH-PINNED-OBJECTS in this file, not every single one is +;;; necessary because threads are only supported with the conservative +;;; gencgc and numbers on the stack (returned by GET-LISP-OBJ-ADDRESS) +;;; are treated as references. In fact, I think there isn't one that's +;;; truly important as of now. + ;;; set the doc here because in early-thread FDOCUMENTATION is not ;;; available, yet #!+sb-doc @@ -204,8 +210,9 @@ until it is available" (setf old (sb!vm::%instance-set-conditional mutex 2 nil new-value)) (return t)) (unless wait-p (return nil)) - (futex-wait (mutex-value-address mutex) - (sb!kernel:get-lisp-obj-address old))))) + (with-pinned-objects (mutex old) + (futex-wait (mutex-value-address mutex) + (sb!kernel:get-lisp-obj-address old)))))) (defun release-mutex (mutex) #!+sb-doc @@ -264,8 +271,9 @@ time we reacquire MUTEX and return to the caller." ;; this comment, it will change queue->data, and so ;; futex-wait returns immediately instead of sleeping. ;; Ergo, no lost wakeup - (futex-wait (waitqueue-data-address queue) - (sb!kernel:get-lisp-obj-address me))) + (with-pinned-objects (queue me) + (futex-wait (waitqueue-data-address queue) + (sb!kernel:get-lisp-obj-address me)))) ;; If we are interrupted while waiting, we should do these things ;; before returning. Ideally, in the case of an unhandled signal, ;; we should do them before entering the debugger, but this is @@ -287,7 +295,8 @@ time we reacquire MUTEX and return to the caller." ;; XXX we should do something to ensure that the result of this setf ;; is visible to all CPUs (setf (waitqueue-data queue) me) - (futex-wake (waitqueue-data-address queue) n))) + (with-pinned-objects (queue) + (futex-wake (waitqueue-data-address queue) n)))) (defun condition-broadcast (queue) #!+sb-doc @@ -540,17 +549,17 @@ returns the thread exits." ;; reference to this thread (handle-thread-exit thread))))))) (values)))) - (with-pinned-objects (initial-function) - (let ((os-thread - ;; don't let the child inherit *CURRENT-THREAD* because that - ;; can prevent gc'ing this thread while the child runs - (let ((*current-thread* nil)) + (let ((os-thread + ;; don't let the child inherit *CURRENT-THREAD* because that + ;; can prevent gc'ing this thread while the child runs + (let ((*current-thread* nil)) + (with-pinned-objects (initial-function) (%create-thread - (sb!kernel:get-lisp-obj-address initial-function))))) - (when (zerop os-thread) - (error "Can't create a new thread")) - (wait-on-semaphore setup-sem) - thread)))) + (sb!kernel:get-lisp-obj-address initial-function)))))) + (when (zerop os-thread) + (error "Can't create a new thread")) + (wait-on-semaphore setup-sem) + thread))) (defun destroy-thread (thread) #!+sb-doc diff --git a/src/compiler/x86/macros.lisp b/src/compiler/x86/macros.lisp index b0f685f..e61732b 100644 --- a/src/compiler/x86/macros.lisp +++ b/src/compiler/x86/macros.lisp @@ -455,8 +455,12 @@ garbage collection" `(multiple-value-prog1 (progn ,@(loop for p in objects - collect `(push-word-on-c-stack - (int-sap (sb!kernel:get-lisp-obj-address ,p)))) + collect + ;; There is no race here wrt to gc, because at every + ;; point during the execution there is a reference to + ;; P on the stack or in a register. + `(push-word-on-c-stack + (int-sap (sb!kernel:get-lisp-obj-address ,p)))) ,@body) ;; If the body returned normally, we should restore the stack pointer ;; for the benefit of any following code in the same function. If diff --git a/version.lisp-expr b/version.lisp-expr index d96a66f..ddc1c29 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".) -"0.9.5.35" +"0.9.5.36" -- 1.7.10.4