-(let ((start-time (get-universal-time)))
- (make-thread (lambda () (sleep 1) (sb-ext:gc :full t)))
- (sleep 5)
- (assert (>= (get-universal-time) (+ 5 start-time))))
-
-
-(let ((queue (make-waitqueue :name "queue"))
- (lock (make-mutex :name "lock"))
- (n 0))
- (labels ((in-new-thread ()
- (with-mutex (lock)
- (assert (eql (mutex-value lock) *current-thread*))
- (format t "~A got mutex~%" *current-thread*)
- ;; now drop it and sleep
- (condition-wait queue lock)
- ;; after waking we should have the lock again
- (assert (eql (mutex-value lock) *current-thread*))
- (assert (eql n 1))
- (decf n))))
- (make-thread #'in-new-thread)
- (sleep 2) ; give it a chance to start
- ;; check the lock is free while it's asleep
- (format t "parent thread ~A~%" *current-thread*)
- (assert (eql (mutex-value lock) nil))
- (with-mutex (lock)
- (incf n)
- (condition-notify queue))
- (sleep 1)))
-
-(let ((queue (make-waitqueue :name "queue"))
- (lock (make-mutex :name "lock")))
- (labels ((ours-p (value)
- (eq *current-thread* value))
- (in-new-thread ()
- (with-recursive-lock (lock)
- (assert (ours-p (mutex-value lock)))
- (format t "~A got mutex~%" (mutex-value lock))
- ;; now drop it and sleep
- (condition-wait queue lock)
- ;; after waking we should have the lock again
- (format t "woken, ~A got mutex~%" (mutex-value lock))
- (assert (ours-p (mutex-value lock))))))
- (make-thread #'in-new-thread)
- (sleep 2) ; give it a chance to start
- ;; check the lock is free while it's asleep
- (format t "parent thread ~A~%" *current-thread*)
- (assert (eql (mutex-value lock) nil))
- (with-recursive-lock (lock)
- (condition-notify queue))
- (sleep 1)))
-
-(let ((mutex (make-mutex :name "contended")))
- (labels ((run ()
- (let ((me *current-thread*))
- (dotimes (i 100)
- (with-mutex (mutex)
- (sleep .03)
- (assert (eql (mutex-value mutex) me)))
- (assert (not (eql (mutex-value mutex) me))))
- (format t "done ~A~%" *current-thread*))))
- (let ((kid1 (make-thread #'run))
- (kid2 (make-thread #'run)))
- (format t "contention ~A ~A~%" kid1 kid2)
- (wait-for-threads (list kid1 kid2)))))
+(with-test (:name (:sleep :continue-sleeping-after-interrupt))
+ (let ((start-time (get-universal-time)))
+ (make-thread (lambda () (sleep 1) (sb-ext:gc :full t)))
+ (sleep 5)
+ (assert (>= (get-universal-time) (+ 5 start-time)))))
+
+
+(with-test (:name (:condition-wait :basics-1))
+ (let ((queue (make-waitqueue :name "queue"))
+ (lock (make-mutex :name "lock"))
+ (n 0))
+ (labels ((in-new-thread ()
+ (with-mutex (lock)
+ (assert (eql (mutex-value lock) *current-thread*))
+ (format t "~A got mutex~%" *current-thread*)
+ ;; now drop it and sleep
+ (condition-wait queue lock)
+ ;; after waking we should have the lock again
+ (assert (eql (mutex-value lock) *current-thread*))
+ (assert (eql n 1))
+ (decf n))))
+ (make-thread #'in-new-thread)
+ (sleep 2) ; give it a chance to start
+ ;; check the lock is free while it's asleep
+ (format t "parent thread ~A~%" *current-thread*)
+ (assert (eql (mutex-value lock) nil))
+ (with-mutex (lock)
+ (incf n)
+ (condition-notify queue))
+ (sleep 1))))
+
+(with-test (:name (:condition-wait :basics-2))
+ (let ((queue (make-waitqueue :name "queue"))
+ (lock (make-mutex :name "lock")))
+ (labels ((ours-p (value)
+ (eq *current-thread* value))
+ (in-new-thread ()
+ (with-recursive-lock (lock)
+ (assert (ours-p (mutex-value lock)))
+ (format t "~A got mutex~%" (mutex-value lock))
+ ;; now drop it and sleep
+ (condition-wait queue lock)
+ ;; after waking we should have the lock again
+ (format t "woken, ~A got mutex~%" (mutex-value lock))
+ (assert (ours-p (mutex-value lock))))))
+ (make-thread #'in-new-thread)
+ (sleep 2) ; give it a chance to start
+ ;; check the lock is free while it's asleep
+ (format t "parent thread ~A~%" *current-thread*)
+ (assert (eql (mutex-value lock) nil))
+ (with-recursive-lock (lock)
+ (condition-notify queue))
+ (sleep 1))))
+
+(with-test (:name (:mutex :contention))
+ (let ((mutex (make-mutex :name "contended")))
+ (labels ((run ()
+ (let ((me *current-thread*))
+ (dotimes (i 100)
+ (with-mutex (mutex)
+ (sleep .03)
+ (assert (eql (mutex-value mutex) me)))
+ (assert (not (eql (mutex-value mutex) me))))
+ (format t "done ~A~%" *current-thread*))))
+ (let ((kid1 (make-thread #'run))
+ (kid2 (make-thread #'run)))
+ (format t "contention ~A ~A~%" kid1 kid2)
+ (wait-for-threads (list kid1 kid2))))))