Skip to content

Commit 1d487a9

Browse files
Use builtin SBCL thread API in test runner, or bordeaux-threads for #-sbcl
PiperOrigin-RevId: 710096890
1 parent ff0adb5 commit 1d487a9

File tree

4 files changed

+47
-20
lines changed

4 files changed

+47
-20
lines changed

ace.test.asd

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121
:version "1.0"
2222
:author "Lisp Community"
2323
:license "MIT"
24-
:depends-on (bordeaux-threads closer-mop trivial-garbage ace.core)
24+
;; FIXME: does it still need closer-mop?
25+
:depends-on (#-sbcl bordeaux-threads closer-mop trivial-garbage ace.core)
2526
:in-order-to ((test-op (test-op :ace.test/tests)))
2627
:serial t
2728
:components

main.lisp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,25 @@
1717

1818
(in-package :ace.test.main)
1919

20+
;;; Compatibility shims
21+
#+sbcl
22+
(progn
23+
(eval-when (:compile-toplevel :load-toplevel :execute)
24+
(import '(sb-thread:make-thread)))
25+
(defun all-threads () (sb-thread:list-all-threads)))
26+
#-sbcl
27+
(eval-when (:compile-toplevel :load-toplevel :execute)
28+
(import '(bordeaux-threads:make-thread bordeaux-threads:all-threads)))
29+
2030
(defun start-timeout-watcher ()
2131
"Runs a watcher for TIMEOUT minus 5 sec. and prints stack traces if not dead."
22-
(let ((timeout (ace.test.runner:timeout)))
32+
(let ((timeout (ace.test.runner:default-timeout)))
2333
(when (and timeout (> timeout 5))
2434
(flet ((timeout-watcher ()
2535
(sleep (- timeout 5))
2636
(format *error-output* "INFO: The test is about to timeout.~%")
2737
(thread:print-backtraces)))
28-
(thread:make-thread #'timeout-watcher :name "Timeout-Watcher")))))
38+
(make-thread #'timeout-watcher :name "Timeout-Watcher")))))
2939

3040
#+google3
3141
(flag:define ace.test.runner::*parallel* t
@@ -66,6 +76,5 @@ If ABORT is true, the process exits recklessly without cleaning up."
6676
(sb-thread:%dispose-thread-structs)
6777
;; - thread structures (not threads) awaiting reuse in the recycle list
6878
(sb-alien:alien-funcall empty-thread-recyclebin))
69-
(format *error-output* "INFO: Exiting with ~D thread~:p remaining.~%"
70-
(length (thread:all-threads)))
79+
(format *error-output* "INFO: Exiting with ~D thread~:p remaining.~%" (length (all-threads)))
7180
(exit :timeout 10))

runner.lisp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,6 @@
1515

1616
(defpackage #:ace.test.runner
1717
(:use #:common-lisp #:ace.core)
18-
(:import-from #:ace.core.thread
19-
#:join-thread
20-
#:make-thread
21-
#:with-timeout
22-
#:make-mutex
23-
#:with-mutex)
2418
(:import-from #:ace.core.tty
2519
#:ttyp
2620
#:*print-ansi*)
@@ -35,6 +29,7 @@
3529
#:missed
3630
#:*on-missed-expectation*
3731
#:alternate-truth-form)
32+
(:import-from #+sbcl #:sb-ext #-sbcl #:bordeaux-threads #:timeout)
3833
(:export
3934
;; Execution of tests.
4035
#:*checks-count*
@@ -47,11 +42,28 @@
4742
#:run-and-report-tests
4843
#:deregister-tests
4944
#:*debug-unit-tests*
50-
#:timeout
45+
;; TIMEOUT is a symbol naming a condition, and it was confusing to also have it name a function,
46+
;; so the function is now named DEFAULT-TIMEOUT
47+
#:default-timeout
5148
#:order))
5249

5350
(in-package #:ace.test.runner)
5451

52+
;;; Compatibility shims
53+
#+sbcl
54+
(progn
55+
(eval-when (:compile-toplevel :load-toplevel :execute)
56+
(import '(sb-thread:make-thread sb-thread:join-thread sb-thread:with-mutex)))
57+
(defmacro with-timeout ((time) &body body) `(sb-ext:with-timeout ,time ,@body))
58+
(defun make-mutex (name) (sb-thread:make-mutex :name name)))
59+
#-sbcl
60+
(progn
61+
(eval-when (:compile-toplevel :load-toplevel :execute)
62+
(import '(bordeaux-threads:make-thread bordeaux-threads:join-thread)))
63+
(defun make-mutex (name) (bordeaux-threads:make-lock name))
64+
(defmacro with-mutex ((lock) &body body) `(bordeaux-threads:with-lock-held (,lock) ,@body))
65+
(defmacro with-timeout (&whole form) `(bordeaux-threads:with-timeout ,@(cdr form))))
66+
5567
;;; Test execution.
5668

5769
(declaim (list *unit-tests*))
@@ -326,7 +338,7 @@ Returns true if there was no error."
326338
(test-run-start-time run)
327339
(handler-bind ((missed #'on-warning)
328340
(error #'on-error)
329-
(bordeaux-threads:timeout #'on-error))
341+
(timeout #'on-error))
330342
(loop do
331343
(with-simple-restart (retry "Retry ~S" test)
332344
(return
@@ -336,7 +348,7 @@ Returns true if there was no error."
336348
(funcall (symbol-function test)))))))
337349
(update-test-run run)))))
338350

339-
(defun timeout ()
351+
(defun default-timeout ()
340352
"Return a value for the default test timeout in seconds."
341353
;; The test timeout is provided by blaze test in the TEST_TIMEOUT variable.
342354
;; See: http://bazel.build/docs/test-encyclopedia.html
@@ -450,7 +462,7 @@ If PARALLEL is NIL, the PARALLEL tests will be empty."))
450462
(let* ((run (make-test-run
451463
:test test
452464
:parallel (and parallel (not (get test 'order)))
453-
:timeout (get test 'timeout (timeout))
465+
:timeout (get test 'timeout (default-timeout))
454466
:output-stream (make-string-output-stream)))
455467
(package (symbol-package test))
456468
(name (format nil "~@[~A::~]~A"
@@ -563,6 +575,9 @@ If PARALLEL is NIL, the PARALLEL tests will be empty."))
563575
(prog1
564576
(report-tests (%run-tests :debug nil :verbose verbose :out out) :out out)
565577
;; Cleanup Lisp-gc managed c-objects so asan doesn't complain
578+
;; This GC call assumes that cleanups are synchronous with completion of GC,
579+
;; but we've seen ASAN complains anyway as it requires lots of other help.
580+
;; So probably just remove this after further testing.
566581
(trivial-garbage:gc :full t)))
567582

568583
(defun deregister-tests (&optional (select :all))

test.lisp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,6 @@
2020
#:run-tests
2121
#:order
2222
#:timeout)
23-
;; Use bordeaux-threads to minimize dependencies
24-
;; TODO(czak): Move to mocks.lisp.
25-
(:import-from #:bordeaux-threads
26-
#:make-recursive-lock
27-
#:with-recursive-lock-held)
2823
(:export
2924
;; Testing utilities.
3025
#:signals
@@ -162,6 +157,13 @@ Example:
162157
;;;
163158
;;; Convenience for testing bad/unsafe legacy code that depends on global state.
164159

160+
(defun make-recursive-lock (name)
161+
#+sbcl (sb-thread:make-mutex :name name)
162+
#-sbcl (bordeaux-threads:make-recursive-lock name))
163+
(defmacro with-recursive-lock-held ((lock) &body body)
164+
#+sbcl `(sb-thread:with-recursive-lock (,lock) ,@body)
165+
#-sbcl `(bordeaux-threads:with-recursive-lock-held (,lock) ,@body))
166+
165167
(defvar *unsafe-code-test-mutex* (make-recursive-lock "UNSAFE-CODE-TEST-MUTEX")
166168
"Used to serialize tests that mutate global space.")
167169

0 commit comments

Comments
 (0)