(in-package "SB!THREAD")
+(def!type thread-name ()
+ 'simple-string)
+
(def!struct (thread (:constructor %make-thread))
#!+sb-doc
"Thread type. Do not rely on threads being structs as it may change
in future versions."
- name
- %alive-p
- os-thread
- interruptions
- (interruptions-lock (make-mutex :name "thread interruptions lock"))
- result
- (result-lock (make-mutex :name "thread result lock")))
+ (name nil :type (or thread-name null))
+ (%alive-p nil :type boolean)
+ (os-thread nil :type (or integer null))
+ (interruptions nil :type list)
+ (result nil :type list)
+ (interruptions-lock
+ (make-mutex :name "thread interruptions lock")
+ :type mutex)
+ (result-lock
+ (make-mutex :name "thread result lock")
+ :type mutex)
+ waiting-for)
(def!struct mutex
#!+sb-doc
"Mutex type."
- (name nil :type (or null simple-string))
+ (name nil :type (or null thread-name))
(%owner nil :type (or null thread))
- #!+(and (not sb-lutex) sb-thread)
- (state 0 :type fixnum)
- #!+(and sb-lutex sb-thread)
- (lutex (make-lutex)))
+ #!+(and sb-thread sb-futex)
+ (state 0 :type fixnum))
(defun mutex-value (mutex)
"Current owner of the mutex, NIL if the mutex is free. May return a
(def!struct spinlock
#!+sb-doc
"Spinlock type."
- (name nil :type (or null simple-string))
+ (name nil :type (or null thread-name))
(value nil))
+(sb!xc:defmacro without-thread-waiting-for ((&key already-without-interrupts) &body body)
+ (with-unique-names (thread prev)
+ (let ((without (if already-without-interrupts
+ 'progn
+ 'without-interrupts))
+ (with (if already-without-interrupts
+ 'progn
+ 'with-local-interrupts)))
+ `(let* ((,thread *current-thread*)
+ (,prev (thread-waiting-for ,thread)))
+ (flet ((exec () ,@body))
+ (if ,prev
+ (,without
+ (unwind-protect
+ (progn
+ (setf (thread-waiting-for ,thread) nil)
+ (,with (exec)))
+ (setf (thread-waiting-for ,thread) ,prev)))
+ (exec)))))))
+
(sb!xc:defmacro with-mutex ((mutex &key (value '*current-thread*) (wait-p t))
&body body)
#!+sb-doc
- "Acquire MUTEX for the dynamic scope of BODY, setting it to
-NEW-VALUE or some suitable default value if NIL. If WAIT-P is non-NIL
-and the mutex is in use, sleep until it is available"
+ "Acquire MUTEX for the dynamic scope of BODY, setting it to VALUE or
+some suitable default value if NIL. If WAIT-P is non-NIL and the mutex
+is in use, sleep until it is available"
`(dx-flet ((with-mutex-thunk () ,@body))
(call-with-mutex
#'with-mutex-thunk