1 ;;;; tests PROFILE with multiple threads
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; While most of SBCL is derived from the CMU CL system, the test
7 ;;;; files (like this one) were written from scratch after the fork
10 ;;;; This software is in the public domain and is provided with
11 ;;;; absolutely no warranty. See the COPYING and CREDITS files for
12 ;;;; more information.
14 (load "assertoid.lisp")
15 (load "test-util.lisp")
17 (defpackage :profile-test
18 (:use
:cl
:sb-thread
))
20 (in-package :profile-test
)
22 (defun miller-rabin-prime-p (n &optional
(s 50))
23 "Miller-Rabin primality test written by R. Matthew Emerson."
24 (flet ((witness-p (a n
)
25 (loop with b
= (- n
1)
26 for i from
(integer-length b
) downto
0
27 for d
= 1 then
(mod (* d d
) n
)
30 (when (and (= d
1) (/= x
1) (/= x
(- n
1)))
31 (return-from witness-p t
))
33 (setf d
(mod (* d a
) n
))))
34 finally
(return (/= d
1)))))
36 (let ((w (1+ (random (- n
1)))))
38 (return-from miller-rabin-prime-p nil
))))))
40 (defun random-of-bit-size (n-bits)
41 "Returns a random number of maximum size `N-BITS'."
42 (random (ash 1 n-bits
)))
44 (defun prime-of-bit-size (n-bits)
45 "Returns a prime number of maximum size `N-BITS'."
46 (loop for maybe-prime
= (random-of-bit-size n-bits
)
47 when
(miller-rabin-prime-p maybe-prime
)
48 do
(return maybe-prime
)))
50 (defun waste-cpu-cycles (n-primes n-prime-bits n-workers
)
55 do
(prime-of-bit-size n-prime-bits
))
57 (serious-condition (s)
59 (let* ((r (make-semaphore))
62 (loop repeat n-workers
63 collect
(sb-thread:make-thread
64 (let ((rs (make-random-state)))
67 (handler-bind ((serious-condition (lambda (c)
71 (let ((*random-state
* rs
))
75 do
(prime-of-bit-size n-prime-bits
))
77 (loop repeat n-workers do
(wait-on-semaphore r
))
78 (signal-semaphore w n-workers
)
79 (mapcar #'sb-thread
:join-thread workers
))))
83 (with-test (:name
(profile :threads
))
84 (profile "PROFILE-TEST")
85 ;; This used to signal an error with threads
86 (let* ((n #+sb-thread
5 #-sb-thread
1)
87 (res (profile-test::waste-cpu-cycles
10 256 n
))
88 (want (make-list n
:initial-element t
)))
89 (unless (equal res want
)
90 (error "wanted ~S, got ~S" want res
)))
93 (with-test (:name
:profiling-counter
)
94 ;; Make sure our profiling counters don't miscount
95 (let ((c (sb-profile::make-counter
))
98 do
(let ((n (random (* 12 (ash 1 sb-vm
:n-word-bits
)))))
99 (sb-profile::incf-counter c n
)
101 (let ((n (random (ash 1 sb-vm
:n-word-bits
))))
102 (sb-profile::incf-counter c n
)
104 (assert (= i
(sb-profile::counter-count c
)))))