X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ftarget-thread.lisp;h=fac5220bbb3324cee2c0a4f369cfefe222c07586;hb=59f4a9f62d1ab9656b02eef240d7aac65669262d;hp=3493cfce2f4897fa7a034edb9a02575174f34a64;hpb=695734b2aff0e6b7ee7ea6f0424d3c0b46d088ca;p=sbcl.git diff --git a/src/code/target-thread.lisp b/src/code/target-thread.lisp index 3493cfc..fac5220 100644 --- a/src/code/target-thread.lisp +++ b/src/code/target-thread.lisp @@ -218,8 +218,15 @@ in future versions." (defun release-spinlock (spinlock) (declare (optimize (speed 3) (safety 0))) - (setf (spinlock-value spinlock) nil) - nil) + ;; Simply setting SPINLOCK-VALUE to NIL is not enough as it does not + ;; propagate to other processors, plus without a memory barrier the + ;; CPU might reorder instructions allowing code from the critical + ;; section to leak out. Use COMPARE-AND-SWAP for the memory barrier + ;; effect and do some sanity checking while we are at it. + (unless (eq *current-thread* + (sb!ext:compare-and-swap (spinlock-value spinlock) + *current-thread* nil)) + (error "Only the owner can release the spinlock ~S." spinlock))) ;;;; mutexes