X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-thread.lisp;h=61ea1af1e7680405c26c5f54f06318d10546413b;hb=5423b2e0f7e7643001ed3ef2f66681c0114a72a6;hp=e2a6cfce7bb3e46e9591ba7e9195e5f31ab77821;hpb=068cf4b55af3f8f8acf2c7c06869441612261cd4;p=sbcl.git diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index e2a6cfc..61ea1af 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -39,14 +39,22 @@ in future versions." "The name of the thread. Setfable.") (def!method print-object ((thread thread) stream) - (if (thread-name thread) - (print-unreadable-object (thread stream :type t :identity t) - (prin1 (thread-name thread) stream)) - (print-unreadable-object (thread stream :type t :identity t) - ;; body is empty => there is only one space between type and - ;; identity - )) - thread) + (print-unreadable-object (thread stream :type t :identity t) + (let* ((cookie (list thread)) + (info (if (thread-alive-p thread) + :running + (multiple-value-list (join-thread thread :default cookie)))) + (state (if (eq :running info) + info + (if (eq cookie (car info)) + :aborted + :finished))) + (values (when (eq :finished state) info))) + (format stream "~@[~S ~]~:[~A~;~A~:[ no values~; values: ~:*~{~S~^, ~}~]~]" + (thread-name thread) + (eq :finished state) + state + values)))) (defun thread-alive-p (thread) #!+sb-doc @@ -59,6 +67,8 @@ in future versions." (defvar *all-threads* ()) (defvar *all-threads-lock* (make-mutex :name "all threads lock")) +(defvar *default-alloc-signal* nil) + (defmacro with-all-threads-lock (&body body) `(with-system-mutex (*all-threads-lock*) ,@body)) @@ -73,8 +83,8 @@ in future versions." (defun current-thread-sap () (sb!vm::current-thread-offset-sap sb!vm::thread-this-slot)) -(declaim (inline current-thread-sap-id)) -(defun current-thread-sap-id () +(declaim (inline current-thread-os-thread)) +(defun current-thread-os-thread () (sap-int (sb!vm::current-thread-offset-sap sb!vm::thread-os-thread-slot))) @@ -82,7 +92,7 @@ in future versions." (/show0 "Entering INIT-INITIAL-THREAD") (let ((initial-thread (%make-thread :name "initial thread" :%alive-p t - :os-thread (current-thread-sap-id)))) + :os-thread (current-thread-os-thread)))) (setq *current-thread* initial-thread) ;; Either *all-threads* is empty or it contains exactly one thread ;; in case we are in reinit since saving core with multiple @@ -704,7 +714,9 @@ around and can be retrieved by JOIN-THREAD." (sb!impl::*zap-array-data-temp* empty) (sb!impl::*internal-symbol-output-fun* nil) (sb!impl::*descriptor-handlers* nil)) ; serve-event - (setf (thread-os-thread thread) (current-thread-sap-id)) + ;; Binding from C + (setf sb!vm:*alloc-signal* *default-alloc-signal*) + (setf (thread-os-thread thread) (current-thread-os-thread)) (with-mutex ((thread-result-lock thread)) (with-all-threads-lock (push thread *all-threads*)) @@ -840,37 +852,61 @@ won't like the effect." SB-EXT:QUIT - the usual cleanup forms will be evaluated" (interrupt-thread thread 'sb!ext:quit)) -;;; internal use only. If you think you need to use this, either you -;;; are an SBCL developer, are doing something that you should discuss -;;; with an SBCL developer first, or are doing something that you -;;; should probably discuss with a professional psychiatrist first -#!+sb-thread -(defun thread-sap-for-id (id) - (let ((thread-sap (alien-sap (extern-alien "all_threads" (* t))))) - (loop - (when (sap= thread-sap (int-sap 0)) (return nil)) - (let ((os-thread (sap-ref-word thread-sap - (* sb!vm:n-word-bytes - sb!vm::thread-os-thread-slot)))) - (when (= os-thread id) (return thread-sap)) - (setf thread-sap - (sap-ref-sap thread-sap (* sb!vm:n-word-bytes - sb!vm::thread-next-slot))))))) - (define-alien-routine "thread_yield" int) #!+sb-doc (setf (fdocumentation 'thread-yield 'function) "Yield the processor to other threads.") +;;; internal use only. If you think you need to use these, either you +;;; are an SBCL developer, are doing something that you should discuss +;;; with an SBCL developer first, or are doing something that you +;;; should probably discuss with a professional psychiatrist first #!+sb-thread -(defun symbol-value-in-thread (symbol thread-sap) - (let* ((index (sb!vm::symbol-tls-index symbol)) - (tl-val (sap-ref-word thread-sap - (* sb!vm:n-word-bytes index)))) - (if (eql tl-val sb!vm::no-tls-value-marker-widetag) - (sb!vm::symbol-global-value symbol) - (make-lisp-obj tl-val)))) +(progn + (defun %thread-sap (thread) + (let ((thread-sap (alien-sap (extern-alien "all_threads" (* t)))) + (target (thread-os-thread thread))) + (loop + (when (sap= thread-sap (int-sap 0)) (return nil)) + (let ((os-thread (sap-ref-word thread-sap + (* sb!vm:n-word-bytes + sb!vm::thread-os-thread-slot)))) + (when (= os-thread target) (return thread-sap)) + (setf thread-sap + (sap-ref-sap thread-sap (* sb!vm:n-word-bytes + sb!vm::thread-next-slot))))))) + + (defun %symbol-value-in-thread (symbol thread) + (tagbody + ;; Prevent the dead from dying completely while we look for the TLS area... + (with-all-threads-lock + (if (thread-alive-p thread) + (let* ((offset (* sb!vm:n-word-bytes (sb!vm::symbol-tls-index symbol))) + (tl-val (sap-ref-word (%thread-sap thread) offset))) + (if (eql tl-val sb!vm::no-tls-value-marker-widetag) + (go :unbound) + (return-from %symbol-value-in-thread (values (make-lisp-obj tl-val) t)))) + (return-from %symbol-value-in-thread (values nil nil)))) + :unbound + (error "Cannot read thread-local symbol value: ~S unbound in ~S" symbol thread))) + + (defun %set-symbol-value-in-thread (symbol thread value) + (tagbody + (with-pinned-objects (value) + ;; Prevent the dead from dying completely while we look for the TLS area... + (with-all-threads-lock + (if (thread-alive-p thread) + (let* ((offset (* sb!vm:n-word-bytes (sb!vm::symbol-tls-index symbol))) + (sap (%thread-sap thread)) + (tl-val (sap-ref-word sap offset))) + (if (eql tl-val sb!vm::no-tls-value-marker-widetag) + (go :unbound) + (setf (sap-ref-word sap offset) (get-lisp-obj-address value))) + (return-from %set-symbol-value-in-thread (values value t))) + (return-from %set-symbol-value-in-thread (values nil nil))))) + :unbound + (error "Cannot set thread-local symbol value: ~S unbound in ~S" symbol thread)))) (defun sb!vm::locked-symbol-global-value-add (symbol-name delta) (sb!vm::locked-symbol-global-value-add symbol-name delta))