1.0.37.6: Add SB-SYS:CANCEL-DEADLINE restart to DEADLINE-TIMEOUTs.
[sbcl.git] / src / code / target-thread.lisp
index 7970945..48417e7 100644 (file)
@@ -524,7 +524,10 @@ IF-NOT-OWNER is :FORCE)."
   #!+sb-doc
   "Atomically release MUTEX and enqueue ourselves on QUEUE.  Another
 thread may subsequently notify us using CONDITION-NOTIFY, at which
-time we reacquire MUTEX and return to the caller."
+time we reacquire MUTEX and return to the caller.
+
+Note that if CONDITION-WAIT unwinds (due to eg. a timeout) instead of
+returning normally, it may do so without holding the mutex."
   #!-sb-thread (declare (ignore queue))
   (assert mutex)
   #!-sb-thread (error "Not supported in unithread builds.")
@@ -680,7 +683,21 @@ negative. Else blocks until the semaphore can be decremented."
                        do (condition-wait (semaphore-queue semaphore)
                                           (semaphore-mutex semaphore)))
                  (setf (semaphore-%count semaphore) (1- count)))
-            (decf (semaphore-waitcount semaphore)))))))
+            ;; Need to use ATOMIC-DECF instead of DECF, as CONDITION-WAIT
+            ;; may unwind without the lock being held due to timeouts.
+            (atomic-decf (semaphore-waitcount semaphore)))))))
+
+(defun try-semaphore (semaphore)
+  #!+sb-doc
+  "Try to decrement the count of SEMAPHORE if the count would not be
+negative. Else return NIL."
+  ;; No need for disabling interrupts; the mutex prevents interleaved
+  ;; modifications, and we don't leave temporarily inconsistent state
+  ;; around.
+  (with-mutex ((semaphore-mutex semaphore))
+    (let ((count (semaphore-%count semaphore)))
+      (when (plusp count)
+        (setf (semaphore-%count semaphore) (1- count))))))
 
 (defun signal-semaphore (semaphore &optional (n 1))
   #!+sb-doc
@@ -901,6 +918,7 @@ around and can be retrieved by JOIN-THREAD."
                    (*handler-clusters* (sb!kernel::initial-handler-clusters))
                    (*condition-restarts* nil)
                    (sb!impl::*deadline* nil)
+                   (sb!impl::*deadline-seconds* nil)
                    (sb!impl::*step-out* nil)
                    ;; internal printer variables
                    (sb!impl::*previous-case* nil)