X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fthread.lisp;h=01bbac7669ab8285067d35ea7e8f171ea71a3456;hb=975f1932acc3a8e90fb31d2b055bfbdde78ea927;hp=f0c51103e702a1a77c1c77a902f062040a994b21;hpb=c548f73e8dd676d6ec4576eba6ab661a5061bdfe;p=sbcl.git diff --git a/src/code/thread.lisp b/src/code/thread.lisp index f0c5110..01bbac7 100644 --- a/src/code/thread.lisp +++ b/src/code/thread.lisp @@ -31,11 +31,19 @@ "Acquire MUTEX for the dynamic scope of BODY, setting it to NEW-VALUE or some suitable default value if NIL. If WAIT-P is non-NIL and the mutex is in use, sleep until it is available" - `(call-with-mutex - (lambda () ,@body) - ,mutex - ,value - ,wait-p)) + `(dx-flet ((with-mutex-thunk () ,@body)) + (call-with-mutex + #'with-mutex-thunk + ,mutex + ,value + ,wait-p))) + +(sb!xc:defmacro with-system-mutex ((mutex &key without-gcing) &body body) + `(dx-flet ((with-system-mutex-thunk () ,@body)) + (call-with-system-mutex + #'with-system-mutex-thunk + ,mutex + ,without-gcing))) (sb!xc:defmacro with-recursive-lock ((mutex) &body body) #!+sb-doc @@ -43,19 +51,30 @@ and the mutex is in use, sleep until it is available" further recursive lock attempts for the same mutex succeed. It is allowed to mix WITH-MUTEX and WITH-RECURSIVE-LOCK for the same mutex provided the default value is used for the mutex." - `(call-with-recursive-lock - (lambda () ,@body) - ,mutex)) + `(dx-flet ((with-recursive-lock-thunk () ,@body)) + (call-with-recursive-lock + #'with-recursive-lock-thunk + ,mutex))) (sb!xc:defmacro with-recursive-spinlock ((spinlock) &body body) - `(call-with-recursive-spinlock - (lambda () ,@body) - ,spinlock)) + `(dx-flet ((with-recursive-spinlock-thunk () ,@body)) + (call-with-recursive-spinlock + #'with-recursive-spinlock-thunk + ,spinlock))) + +(sb!xc:defmacro with-recursive-system-spinlock ((spinlock &key without-gcing) + &body body) + `(dx-flet ((with-recursive-system-spinlock-thunk () ,@body)) + (call-with-recursive-system-spinlock + #'with-recursive-system-spinlock-thunk + ,spinlock + ,without-gcing))) (sb!xc:defmacro with-spinlock ((spinlock) &body body) - `(call-with-spinlock - (lambda () ,@body) - ,spinlock)) + `(dx-flet ((with-spinlock-thunk () ,@body)) + (call-with-spinlock + #'with-spinlock-thunk + ,spinlock))) ;;; KLUDGE: this separate implementation for (NOT SB-THREAD) is not ;;; strictly necessary; GET-MUTEX and RELEASE-MUTEX are implemented. @@ -70,16 +89,26 @@ provided the default value is used for the mutex." (without-gcing (funcall function)) (without-interrupts - (funcall function)))) + (allow-with-interrupts (funcall function))))) - (defun call-with-system-spinlock (function lock &optional without-gcing-p) + (defun call-with-system-spinlock (function spinlock &optional without-gcing-p) + (declare (ignore spinlock) + (function function)) + (if without-gcing-p + (without-gcing + (funcall function)) + (without-interrupts + (allow-with-interrupts (funcall function))))) + + (defun call-with-recursive-system-spinlock (function lock + &optional without-gcing-p) (declare (ignore lock) (function function)) (if without-gcing-p (without-gcing (funcall function)) (without-interrupts - (funcall function)))) + (allow-with-interrupts (funcall function))))) (defun call-with-mutex (function mutex value waitp) (declare (ignore mutex value waitp) @@ -99,11 +128,14 @@ provided the default value is used for the mutex." (funcall function))) #!+sb-thread +;;; KLUDGE: These need to use DX-LET, because the cleanup form that +;;; closes over GOT-IT causes a value-cell to be allocated for it -- and +;;; we prefer that to go on the stack since it can. (progn (defun call-with-system-mutex (function mutex &optional without-gcing-p) (declare (function function)) (flet ((%call-with-system-mutex () - (let (got-it) + (dx-let (got-it) (unwind-protect (when (setf got-it (get-mutex mutex)) (funcall function)) @@ -113,13 +145,29 @@ provided the default value is used for the mutex." (without-gcing (%call-with-system-mutex)) (without-interrupts - (%call-with-system-mutex))))) + (allow-with-interrupts (%call-with-system-mutex)))))) - (defun call-with-recursive-system-spinlock (function lock &optional without-gcing-p) + (defun call-with-system-spinlock (function spinlock &optional without-gcing-p) (declare (function function)) (flet ((%call-with-system-spinlock () - (let ((inner-lock-p (eq *current-thread* (spinlock-value lock))) - (got-it nil)) + (dx-let (got-it) + (unwind-protect + (when (setf got-it (get-spinlock spinlock)) + (funcall function)) + (when got-it + (release-spinlock spinlock)))))) + (if without-gcing-p + (without-gcing + (%call-with-system-spinlock)) + (without-interrupts + (allow-with-interrupts (%call-with-system-spinlock)))))) + + (defun call-with-recursive-system-spinlock (function lock + &optional without-gcing-p) + (declare (function function)) + (flet ((%call-with-system-spinlock () + (dx-let ((inner-lock-p (eq *current-thread* (spinlock-value lock))) + (got-it nil)) (unwind-protect (when (or inner-lock-p (setf got-it (get-spinlock lock))) (funcall function)) @@ -129,11 +177,22 @@ provided the default value is used for the mutex." (without-gcing (%call-with-system-spinlock)) (without-interrupts - (%call-with-system-spinlock))))) + (allow-with-interrupts (%call-with-system-spinlock)))))) + + (defun call-with-spinlock (function spinlock) + (declare (function function)) + (dx-let ((got-it nil)) + (without-interrupts + (unwind-protect + (when (setf got-it (allow-with-interrupts + (get-spinlock spinlock))) + (with-local-interrupts (funcall function))) + (when got-it + (release-spinlock spinlock)))))) (defun call-with-mutex (function mutex value waitp) (declare (function function)) - (let ((got-it nil)) + (dx-let ((got-it nil)) (without-interrupts (unwind-protect (when (setq got-it (allow-with-interrupts @@ -144,8 +203,8 @@ provided the default value is used for the mutex." (defun call-with-recursive-lock (function mutex) (declare (function function)) - (let ((inner-lock-p (eq (mutex-value mutex) *current-thread*)) - (got-it nil)) + (dx-let ((inner-lock-p (eq (mutex-value mutex) *current-thread*)) + (got-it nil)) (without-interrupts (unwind-protect (when (or inner-lock-p (setf got-it (allow-with-interrupts @@ -154,20 +213,11 @@ provided the default value is used for the mutex." (when got-it (release-mutex mutex)))))) - (defun call-with-spinlock (function spinlock) - (declare (function function)) - (let ((got-it nil)) - (without-interrupts - (unwind-protect - (when (setf got-it (allow-with-interrupts - (get-spinlock spinlock))) - (with-local-interrupts (funcall function))) - (when got-it - (release-spinlock spinlock)))))) + (defun call-with-recursive-spinlock (function spinlock) (declare (function function)) - (let ((inner-lock-p (eq (spinlock-value spinlock) *current-thread*)) + (dx-let ((inner-lock-p (eq (spinlock-value spinlock) *current-thread*)) (got-it nil)) (without-interrupts (unwind-protect