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)))))