;;; Condition-wait should not be interruptible under WITHOUT-INTERRUPTS
-(with-test (:name without-interrupts+condition-wait
+(with-test (:name :without-interrupts+condition-wait
:skipped-on '(not :sb-thread)
:fails-on '(and :win32 :sb-futex))
(let* ((lock (make-mutex))
;;; GRAB-MUTEX should not be interruptible under WITHOUT-INTERRUPTS
-(with-test (:name without-interrupts+grab-mutex :skipped-on '(not :sb-thread))
+(with-test (:name :without-interrupts+grab-mutex :skipped-on '(not :sb-thread))
(let* ((lock (make-mutex))
(bar (progn (grab-mutex lock) nil))
(thread (make-thread (lambda ()
(assert (eq :aborted (join-thread thread :default :aborted)))
(assert bar)))
-(with-test (:name parallel-find-class :skipped-on '(not :sb-thread))
+(with-test (:name :parallel-find-class :skipped-on '(not :sb-thread))
(let* ((oops nil)
(threads (loop repeat 10
collect (make-thread (lambda ()
;;;; SYMBOL-VALUE-IN-THREAD
-(with-test (:name symbol-value-in-thread.1)
+(with-test (:name :symbol-value-in-thread.1)
(let ((* (cons t t)))
(assert (eq * (symbol-value-in-thread '* *current-thread*)))
(setf (symbol-value-in-thread '* *current-thread*) 123)
(assert (= 123 (symbol-value-in-thread '* *current-thread*)))
(assert (= 123 *))))
-(with-test (:name symbol-value-in-thread.2 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.2 :skipped-on '(not :sb-thread))
(let* ((parent *current-thread*)
(semaphore (make-semaphore))
(child (make-thread (lambda ()
;;; Disabled on Darwin due to deadlocks caused by apparent OS specific deadlocks,
;;; wich _appear_ to be caused by malloc() and free() not being thread safe: an
;;; interrupted malloc in one thread can apparently block a free in another.
-(with-test (:name symbol-value-in-thread.3
+(with-test (:name :symbol-value-in-thread.3
:skipped-on '(not :sb-thread))
(let* ((parent *current-thread*)
(semaphore (make-semaphore))
(setf running nil)
(join-thread noise)))
-(with-test (:name symbol-value-in-thread.4 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.4 :skipped-on '(not :sb-thread))
(let* ((parent *current-thread*)
(semaphore (make-semaphore))
(child (make-thread (lambda ()
(signal-semaphore semaphore)
(assert (equal '(nil nil) (multiple-value-list (join-thread child))))))
-(with-test (:name symbol-value-in-thread.5 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.5 :skipped-on '(not :sb-thread))
(let* ((parent *current-thread*)
(semaphore (make-semaphore))
(child (make-thread (lambda ()
(assert (equal (list *current-thread* 'this-is-new (list :read :unbound-in-thread))
(join-thread child)))))
-(with-test (:name symbol-value-in-thread.6 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.6 :skipped-on '(not :sb-thread))
(let* ((parent *current-thread*)
(semaphore (make-semaphore))
(name (gensym))
(unless (equal res want)
(error "wanted ~S, got ~S" want res)))))
-(with-test (:name symbol-value-in-thread.7 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.7 :skipped-on '(not :sb-thread))
(let ((child (make-thread (lambda ())))
(error-occurred nil))
(join-thread child)
(sb-thread::symbol-value-in-thread-error-info e)))))
(assert error-occurred)))
-(with-test (:name symbol-value-in-thread.8 :skipped-on '(not :sb-thread))
+(with-test (:name :symbol-value-in-thread.8 :skipped-on '(not :sb-thread))
(let ((child (make-thread (lambda ())))
(error-occurred nil))
(join-thread child)
(sb-thread::symbol-value-in-thread-error-info e)))))
(assert error-occurred)))
-(with-test (:name deadlock-detection.1 :skipped-on '(not :sb-thread))
+(with-test (:name :deadlock-detection.1 :skipped-on '(not :sb-thread))
(loop
repeat 1000
do (flet ((test (ma mb sa sb)
(assert (or (equal '(:deadlock :ok) res)
(equal '(:ok :deadlock) res))))))))
-(with-test (:name deadlock-detection.2 :skipped-on '(not :sb-thread))
+(with-test (:name :deadlock-detection.2 :skipped-on '(not :sb-thread))
(let* ((m1 (sb-thread:make-mutex :name "M1"))
(m2 (sb-thread:make-mutex :name "M2"))
(s1 (sb-thread:make-semaphore :name "S1"))
(assert (stringp err)))
(assert (eq :ok (sb-thread:join-thread t1)))))
-(with-test (:name deadlock-detection.3 :skipped-on '(not :sb-thread))
+(with-test (:name :deadlock-detection.3 :skipped-on '(not :sb-thread))
(let* ((m1 (sb-thread:make-mutex :name "M1"))
(m2 (sb-thread:make-mutex :name "M2"))
(s1 (sb-thread:make-semaphore :name "S1"))
(thread-error ()
:oops)))))
+;; SB-THREAD:MAKE-THREAD used to lock SB-THREAD:*MAKE-THREAD-LOCK*
+;; before entering WITHOUT-INTERRUPTS. When a thread which was
+;; executing SB-THREAD:MAKE-THREAD was interrupted with code which
+;; also called SB-THREAD:MAKE-THREAD, it could happen that the first
+;; thread already owned SB-THREAD:*MAKE-THREAD-LOCK* and the
+;; interrupting code thus made a recursive lock attempt.
+;;
+;; See (:TIMER :DISPATCH-THREAD :MAKE-THREAD :BUG-1180102) in
+;; timer.impure.lisp.
+(with-test (:name (make-thread :interrupt-with make-thread :bug-1180102)
+ :skipped-on '(not :sb-thread))
+ (dotimes (i 100)
+ (let ((threads '())
+ (parent *current-thread*))
+ (dotimes (i 100)
+ (push (make-thread
+ (lambda ()
+ (interrupt-thread
+ parent
+ (lambda () (push (make-thread (lambda ())) threads)))))
+ threads)
+ (push (make-thread (lambda ())) threads))
+ (mapc #'join-thread threads))))