X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fthreads.pure.lisp;h=fb2182242472f2d51cb490c26c02bf90bacff0ef;hb=ab5427d31da2bd95805cccc8e47b8f43d3dd606d;hp=3d6d119b4e8e9f0533c93de0f6c34887b513e732;hpb=b56c1a4dc22aa0ac827343667584aa6090b15f02;p=sbcl.git diff --git a/tests/threads.pure.lisp b/tests/threads.pure.lisp index 3d6d119..fb21822 100644 --- a/tests/threads.pure.lisp +++ b/tests/threads.pure.lisp @@ -495,3 +495,49 @@ (join-thread (make-thread (lambda () (sleep 10))) :timeout 0.01 :default cookie))))) + +(with-test (:name :semaphore-notification + :skipped-on '(not :sb-thread)) + (let ((sem (make-semaphore)) + (ok nil) + (n 0)) + (flet ((critical () + (let ((note (make-semaphore-notification))) + (sb-sys:without-interrupts + (unwind-protect + (progn + (sb-sys:with-local-interrupts + (wait-on-semaphore sem :notification note) + (sleep (random 0.1))) + (incf n)) + ;; Re-increment on exit if we decremented it. + (when (semaphore-notification-status note) + (signal-semaphore sem)) + ;; KLUDGE: Prevent interrupts after this point from + ;; unwinding us, so that we can reason about the counts. + (sb-thread::block-deferrable-signals)))))) + (let* ((threads (loop for i from 1 upto 100 + collect (make-thread #'critical :name (format nil "T~A" i)))) + (safe nil) + (unsafe nil) + (interruptor (make-thread (lambda () + (loop until ok) + (let (x) + (dolist (thread threads) + (cond (x + (push thread unsafe) + (sleep (random 0.1)) + (ignore-errors + (terminate-thread thread))) + (t + (push thread safe))) + (setf x (not x)))))))) + (signal-semaphore sem) + (setf ok t) + (join-thread interruptor) + (mapc #'join-thread safe) + (let ((k (count-if (lambda (th) + (join-thread th :default nil)) + unsafe))) + (assert (= n (+ k (length safe)))) + (assert unsafe))))))