X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-thread.lisp;h=3edfb7d5092f71df77df75dc60197b3718946364;hb=48ec282d877900caf5ea4ab42e9d87e566ce6b43;hp=5df996864ae0bf3922ad35586051ec1717bd99a0;hpb=c580293e8550414004697173f7e2c2b6bdf81070;p=sbcl.git diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index 5df9968..3edfb7d 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -11,6 +11,11 @@ (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. + ;;; set the doc here because in early-thread FDOCUMENTATION is not ;;; available, yet #!+sb-doc @@ -112,17 +117,11 @@ in future versions." ;;;; spinlocks -(defstruct spinlock - #!+sb-doc - "Spinlock type." - (name nil :type (or null simple-string)) - (value 0)) - (declaim (inline get-spinlock release-spinlock)) ;;; The bare 2 here and below are offsets of the slots in the struct. ;;; There ought to be some better way to get these numbers -(defun get-spinlock (spinlock new-value) +(defun get-spinlock (spinlock) (declare (optimize (speed 3) (safety 0)) #!-sb-thread (ignore spinlock new-value)) @@ -130,7 +129,7 @@ in future versions." ;; store any value #!+sb-thread (loop until - (eql (sb!vm::%instance-set-conditional spinlock 2 0 new-value) 0))) + (eql (sb!vm::%instance-set-conditional spinlock 2 0 1) 0))) (defun release-spinlock (spinlock) (declare (optimize (speed 3) (safety 0)) @@ -145,19 +144,13 @@ in future versions." (defmacro with-spinlock ((spinlock) &body body) (sb!int:with-unique-names (lock) `(let ((,lock ,spinlock)) - (get-spinlock ,lock *current-thread*) + (get-spinlock ,lock) (unwind-protect (progn ,@body) (release-spinlock ,lock))))) ;;;; mutexes -(defstruct mutex - #!+sb-doc - "Mutex type." - (name nil :type (or null simple-string)) - (value nil)) - #!+sb-doc (setf (sb!kernel:fdocumentation 'make-mutex 'function) "Create a mutex." @@ -204,8 +197,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 +258,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 +282,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,13 +536,12 @@ returns the thread exits." ;; reference to this thread (handle-thread-exit thread))))))) (values)))) + ;; Keep INITIAL-FUNCTION pinned until the child thread is + ;; initialized properly. (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)) - (%create-thread - (sb!kernel:get-lisp-obj-address 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)