X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=tests%2Fthreads.pure.lisp;h=f99e01a06ff81aa206af6c47c20dbc1d4018548b;hb=bad78f8364214129d96f1ae0e028e2810a828791;hp=1545237611a6506ceb4c299793cf0252f176d27a;hpb=feb345d07a3da8e07a455b5564006f747da4bc1e;p=sbcl.git diff --git a/tests/threads.pure.lisp b/tests/threads.pure.lisp index 1545237..f99e01a 100644 --- a/tests/threads.pure.lisp +++ b/tests/threads.pure.lisp @@ -14,12 +14,24 @@ (in-package :cl-user) (defpackage :thread-test - (:use :cl :sb-thread)) + (:use :cl :sb-thread :sb-ext)) (in-package :thread-test) (use-package :test-util) +(with-test (:name atomic-update + :skipped-on '(not :sb-thread)) + (let ((x (cons :count 0))) + (mapc #'sb-thread:join-thread + (loop repeat 1000 + collect (sb-thread:make-thread + (lambda () + (loop repeat 1000 + do (atomic-update (cdr x) #'1+) + (sleep 0.00001)))))) + (assert (equal x '(:count . 1000000))))) + (with-test (:name mutex-owner) ;; Make sure basics are sane on unithreaded ports as well (let ((mutex (make-mutex))) @@ -179,11 +191,9 @@ ;;; 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. There -;;; are also some indications that pthread_mutex_lock is not re-entrant. +;;; interrupted malloc in one thread can apparently block a free in another. (with-test (:name symbol-value-in-thread.3 - :skipped-on '(not :sb-thread) - :broken-on :darwin) + :skipped-on '(not :sb-thread)) (let* ((parent *current-thread*) (semaphore (make-semaphore)) (running t) @@ -307,13 +317,10 @@ (t1 (sb-thread:make-thread (test m1 m2 s1 s2) :name "T1")) (t2 (sb-thread:make-thread (test m2 m1 s2 s1) :name "T2"))) ;; One will deadlock, and the other will then complete normally. - ;; ...except sometimes, when we get unlucky, and both will do - ;; the deadlock detection in parallel and both signal. (let ((res (list (sb-thread:join-thread t1) (sb-thread:join-thread t2)))) (assert (or (equal '(:deadlock :ok) res) - (equal '(:ok :deadlock) res) - (equal '(:deadlock :deadlock) res)))))))) + (equal '(:ok :deadlock) res)))))))) (with-test (:name deadlock-detection.2 :skipped-on '(not :sb-thread)) (let* ((m1 (sb-thread:make-mutex :name "M1")) @@ -405,14 +412,14 @@ (assert (and (null value) error)))) -(with-test (:name (:wait-for :basics)) +(with-test (:name (:wait-for :basics) :fails-on :win32) (assert (not (sb-ext:wait-for nil :timeout 0.1))) (assert (eql 42 (sb-ext:wait-for 42))) (let ((n 0)) (assert (eql 100 (sb-ext:wait-for (when (= 100 (incf n)) n)))))) -(with-test (:name (:wait-for :deadline)) +(with-test (:name (:wait-for :deadline) :fails-on :win32) (assert (eq :ok (sb-sys:with-deadline (:seconds 10) (assert (not (sb-ext:wait-for nil :timeout 0.1))) @@ -424,7 +431,7 @@ (error "oops")) (sb-sys:deadline-timeout () :deadline))))) -(with-test (:name (:condition-wait :timeout :one-thread)) +(with-test (:name (:condition-wait :timeout :one-thread) :fails-on :win32) (let ((mutex (make-mutex)) (waitqueue (make-waitqueue))) (assert (not (with-mutex (mutex) @@ -457,7 +464,7 @@ (unless (eql 50 ok) (error "Wanted 50, got ~S" ok))))) -(with-test (:name (:wait-on-semaphore :timeout :one-thread)) +(with-test (:name (:wait-on-semaphore :timeout :one-thread) :fails-on :win32) (let ((sem (make-semaphore)) (n 0)) (signal-semaphore sem 10) @@ -476,7 +483,7 @@ collect (make-thread (lambda () (sleep (random 0.02)) - (wait-on-semaphore sem :timeout 0.01))))))) + (wait-on-semaphore sem :timeout 0.5))))))) (loop repeat 5 do (signal-semaphore sem 2)) (let ((ok (count-if #'join-thread threads))) @@ -496,7 +503,7 @@ :timeout 0.01 :default cookie))))) -(with-test (:name :semaphore-notification +(with-test (:name (:semaphore-notification :wait-on-semaphore) :skipped-on '(not :sb-thread)) (let ((sem (make-semaphore)) (ok nil) @@ -542,3 +549,46 @@ unsafe))) (assert (= n (+ k (length safe)))) (assert unsafe)))))) + +(with-test (:name (:semaphore-notification :try-sempahore) + :skipped-on '(not :sb-thread)) + (let* ((sem (make-semaphore)) + (note (make-semaphore-notification))) + (try-semaphore sem 1 note) + (assert (not (semaphore-notification-status note))) + (signal-semaphore sem) + (try-semaphore sem 1 note) + (assert (semaphore-notification-status note)))) + +(with-test (:name (:return-from-thread :normal-thread) + :skipped-on '(not :sb-thread)) + (let* ((thread (make-thread (lambda () + (return-from-thread (values 1 2 3)) + :foo))) + (values (multiple-value-list (join-thread thread)))) + (unless (equal (list 1 2 3) values) + (error "got ~S, wanted (1 2 3)" values)))) + +(with-test (:name (:return-from-thread :main-thread)) + (assert (main-thread-p)) + (assert (eq :oops + (handler-case + (return-from-thread t) + (thread-error () + :oops))))) + +(with-test (:name (:abort-thread :normal-thread) + :skipped-on '(not :sb-thread)) + (let ((thread (make-thread (lambda () + (abort-thread) + :foo)))) + (assert (eq :aborted! (join-thread thread :default :aborted!))))) + +(with-test (:name (:abort-thread :main-thread)) + (assert (main-thread-p)) + (assert (eq :oops + (handler-case + (abort-thread) + (thread-error () + :oops))))) +