1 ;;;; support for threads needed at cross-compile time
3 ;;;; This software is part of the SBCL system. See the README file for
6 ;;;; This software is derived from the CMU CL system, which was
7 ;;;; written at Carnegie Mellon University and released into the
8 ;;;; public domain. The software is in the public domain and is
9 ;;;; provided with absolutely no warranty. See the COPYING and CREDITS
10 ;;;; files for more information.
12 (in-package "SB!THREAD")
17 (name nil :type (or null simple-string))
19 #!+(and sb-lutex sb-thread)
25 (name nil :type (or null simple-string))
28 (sb!xc:defmacro with-mutex ((mutex &key (value '*current-thread*) (wait-p t))
31 "Acquire MUTEX for the dynamic scope of BODY, setting it to
32 NEW-VALUE or some suitable default value if NIL. If WAIT-P is non-NIL
33 and the mutex is in use, sleep until it is available"
34 `(dx-flet ((with-mutex-thunk () ,@body))
41 (sb!xc:defmacro with-system-mutex ((mutex &key without-gcing) &body body)
42 `(dx-flet ((with-system-mutex-thunk () ,@body))
43 (call-with-system-mutex
44 #'with-system-mutex-thunk
48 (sb!xc:defmacro with-recursive-lock ((mutex) &body body)
50 "Acquires MUTEX for the dynamic scope of BODY. Within that scope
51 further recursive lock attempts for the same mutex succeed. It is
52 allowed to mix WITH-MUTEX and WITH-RECURSIVE-LOCK for the same mutex
53 provided the default value is used for the mutex."
54 `(dx-flet ((with-recursive-lock-thunk () ,@body))
55 (call-with-recursive-lock
56 #'with-recursive-lock-thunk
59 (sb!xc:defmacro with-recursive-spinlock ((spinlock) &body body)
60 `(dx-flet ((with-recursive-spinlock-thunk () ,@body))
61 (call-with-recursive-spinlock
62 #'with-recursive-spinlock-thunk
65 (sb!xc:defmacro with-recursive-system-spinlock ((spinlock &key without-gcing)
67 `(dx-flet ((with-recursive-system-spinlock-thunk () ,@body))
68 (call-with-recursive-system-spinlock
69 #'with-recursive-system-spinlock-thunk
73 (sb!xc:defmacro with-spinlock ((spinlock) &body body)
74 `(dx-flet ((with-spinlock-thunk () ,@body))
79 ;;; KLUDGE: this separate implementation for (NOT SB-THREAD) is not
80 ;;; strictly necessary; GET-MUTEX and RELEASE-MUTEX are implemented.
81 ;;; However, there would be a (possibly slight) performance hit in
85 (defun call-with-system-mutex (function mutex &optional without-gcing-p)
86 (declare (ignore mutex)
92 (allow-with-interrupts (funcall function)))))
94 (defun call-with-system-spinlock (function spinlock &optional without-gcing-p)
95 (declare (ignore spinlock)
101 (allow-with-interrupts (funcall function)))))
103 (defun call-with-recursive-system-spinlock (function lock
104 &optional without-gcing-p)
105 (declare (ignore lock)
111 (allow-with-interrupts (funcall function)))))
113 (defun call-with-mutex (function mutex value waitp)
114 (declare (ignore mutex value waitp)
118 (defun call-with-recursive-lock (function mutex)
119 (declare (ignore mutex) (function function))
122 (defun call-with-spinlock (function spinlock)
123 (declare (ignore spinlock) (function function))
126 (defun call-with-recursive-spinlock (function spinlock)
127 (declare (ignore spinlock) (function function))
131 ;;; KLUDGE: These need to use DX-LET, because the cleanup form that
132 ;;; closes over GOT-IT causes a value-cell to be allocated for it -- and
133 ;;; we prefer that to go on the stack since it can.
135 (defun call-with-system-mutex (function mutex &optional without-gcing-p)
136 (declare (function function))
137 (flet ((%call-with-system-mutex ()
140 (when (setf got-it (get-mutex mutex))
143 (release-mutex mutex))))))
146 (%call-with-system-mutex))
148 (allow-with-interrupts (%call-with-system-mutex))))))
150 (defun call-with-system-spinlock (function spinlock &optional without-gcing-p)
151 (declare (function function))
152 (flet ((%call-with-system-spinlock ()
155 (when (setf got-it (get-spinlock spinlock))
158 (release-spinlock spinlock))))))
161 (%call-with-system-spinlock))
163 (allow-with-interrupts (%call-with-system-spinlock))))))
165 (defun call-with-recursive-system-spinlock (function lock
166 &optional without-gcing-p)
167 (declare (function function))
168 (flet ((%call-with-system-spinlock ()
169 (dx-let ((inner-lock-p (eq *current-thread* (spinlock-value lock)))
172 (when (or inner-lock-p (setf got-it (get-spinlock lock)))
175 (release-spinlock lock))))))
178 (%call-with-system-spinlock))
180 (allow-with-interrupts (%call-with-system-spinlock))))))
182 (defun call-with-spinlock (function spinlock)
183 (declare (function function))
184 (dx-let ((got-it nil))
187 (when (setf got-it (allow-with-interrupts
188 (get-spinlock spinlock)))
189 (with-local-interrupts (funcall function)))
191 (release-spinlock spinlock))))))
193 (defun call-with-mutex (function mutex value waitp)
194 (declare (function function))
195 (dx-let ((got-it nil))
198 (when (setq got-it (allow-with-interrupts
199 (get-mutex mutex value waitp)))
200 (with-local-interrupts (funcall function)))
202 (release-mutex mutex))))))
204 (defun call-with-recursive-lock (function mutex)
205 (declare (function function))
206 (dx-let ((inner-lock-p (eq (mutex-value mutex) *current-thread*))
210 (when (or inner-lock-p (setf got-it (allow-with-interrupts
212 (with-local-interrupts (funcall function)))
214 (release-mutex mutex))))))
218 (defun call-with-recursive-spinlock (function spinlock)
219 (declare (function function))
220 (dx-let ((inner-lock-p (eq (spinlock-value spinlock) *current-thread*))
224 (when (or inner-lock-p (setf got-it (allow-with-interrupts
225 (get-spinlock spinlock))))
226 (with-local-interrupts (funcall function)))
228 (release-spinlock spinlock)))))))