1 ;;;; -*- indent-tabs-mode: nil -*-
4 Copyright
2006, 2007 Greg Pfeil
6 Distributed under the MIT license
(see LICENSE file
)
9 (in-package #:bordeaux-threads
)
11 ;;; documentation on the LispWorks Multiprocessing interface can be found at
12 ;;; http://www.lispworks.com/documentation/lw445/LWUG/html/lwuser-156.htm
19 (defun start-multiprocessing ()
20 (mp:initialize-multiprocessing
))
22 (defun %make-thread
(function name
)
23 (mp:process-run-function
27 (multiple-value-list (funcall function
))))
28 (setf (mp:process-property
'return-values
)
30 (values-list return-values
)))))
32 (defun current-thread ()
33 #-
#.
(cl:if
(cl:find-symbol
(cl:string
'#:get-current-process
) :mp
) '(and) '(or))
35 ;; introduced in LispWorks 5.1
36 #+#.
(cl:if
(cl:find-symbol
(cl:string
'#:get-current-process
) :mp
) '(and) '(or))
37 (mp:get-current-process
))
39 (defun threadp (object)
40 (mp:process-p object
))
42 (defun thread-name (thread)
43 (mp:process-name thread
))
45 ;;; Resource contention: locks and recursive locks
47 (defun make-lock (&optional name
)
48 (mp:make-lock
:name
(or name
"Anonymous lock")
49 #-
(or lispworks4 lispworks5
) :recursivep
50 #-
(or lispworks4 lispworks5
) nil
))
52 (defun acquire-lock (lock &optional
(wait-p t
))
53 (mp:process-lock lock nil
54 (cond ((null wait-p
) 0)
55 ((numberp wait-p
) wait-p
)
58 (defun release-lock (lock)
59 (mp:process-unlock lock
))
61 (defmacro with-lock-held
((place) &body body
)
62 `(mp:with-lock
(,place
) ,@body
))
64 (defun make-recursive-lock (&optional name
)
65 (mp:make-lock
:name
(or name
"Anonymous recursive lock")
66 #-
(or lispworks4 lispworks5
) :recursivep
67 #-
(or lispworks4 lispworks5
) t
))
69 (defun acquire-recursive-lock (lock &optional
(wait-p t
))
70 (acquire-lock lock wait-p
))
72 (defun release-recursive-lock (lock)
75 (defmacro with-recursive-lock-held
((place) &body body
)
76 `(mp:with-lock
(,place
) ,@body
))
78 ;;; Resource contention: condition variables
81 (defun make-condition-variable (&key name
)
82 (mp:make-condition-variable
:name
(or name
"Anonymous condition variable")))
85 (defun condition-wait (condition-variable lock
&key timeout
)
86 (mp:condition-variable-wait condition-variable lock
:timeout timeout
)
90 (defun condition-notify (condition-variable)
91 (mp:condition-variable-signal condition-variable
))
93 (defun thread-yield ()
94 (mp:process-allow-scheduling
))
96 ;;; Introspection/debugging
99 (mp:list-all-processes
))
101 (defun interrupt-thread (thread function
&rest args
)
102 (apply #'mp
:process-interrupt thread function args
))
104 (defun destroy-thread (thread)
105 (signal-error-if-current-thread thread
)
106 (mp:process-kill thread
))
108 (defun thread-alive-p (thread)
109 (mp:process-alive-p thread
))
111 (declaim (inline %join-thread
))
112 (defun %join-thread
(thread)
113 #-
#.
(cl:if
(cl:find-symbol
(cl:string
'#:process-join
) :mp
) '(and) '(or))
114 (mp:process-wait
(format nil
"Waiting for thread ~A to complete" thread
)
115 (complement #'mp
:process-alive-p
)
117 #+#.
(cl:if
(cl:find-symbol
(cl:string
'#:process-join
) :mp
) '(and) '(or))
118 (mp:process-join thread
))
120 (defun join-thread (thread)
121 (%join-thread thread
)
123 (mp:process-property
'return-values thread
)))
124 (values-list return-values
)))