From: Gábor M. <me...@us...> - 2009-01-09 16:44:04
|
Update of /cvsroot/sbcl/sbcl/src/runtime In directory fdv4jf1.ch3.sourceforge.com:/tmp/cvs-serv22045/src/runtime Modified Files: x86-64-arch.h x86-arch.h Log Message: 1.0.24.26: fix release spinlock Both in the runtime and in Lisp releasing a spinlock was a simple assignment. That doesn't work because the new value may not make it to main memory by the time another CPU wants to acquire it making it needlessly slow. Worse, it also allows the CPU to reorder instructions from the critical section after the release. There is a spinlock implementation for MIPS in the runtime, but it's not used as we don't have threads on that platform. I don't know if it's broken too. Index: x86-64-arch.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-64-arch.h,v retrieving revision 1.11 retrieving revision 1.12 diff -u -d -r1.11 -r1.12 --- x86-64-arch.h 9 Jan 2009 16:42:09 -0000 1.11 +++ x86-64-arch.h 9 Jan 2009 16:43:56 -0000 1.12 @@ -49,12 +49,6 @@ #endif } -static inline void -release_spinlock(volatile lispobj *word) -{ - *word=0; -} - static inline lispobj swap_lispobjs(volatile lispobj *dest, lispobj value) { @@ -67,4 +61,12 @@ return old_value; } +static inline void +release_spinlock(volatile lispobj *word) +{ + /* A memory barrier is needed, use swap_lispobjs. See comment in + * RELEASE-SPINLOCK in target-thread.lisp. */ + swap_lispobjs(word,0); +} + #endif /* _X86_64_ARCH_H */ Index: x86-arch.h =================================================================== RCS file: /cvsroot/sbcl/sbcl/src/runtime/x86-arch.h,v retrieving revision 1.16 retrieving revision 1.17 diff -u -d -r1.16 -r1.17 --- x86-arch.h 9 Jan 2009 16:42:09 -0000 1.16 +++ x86-arch.h 9 Jan 2009 16:43:56 -0000 1.17 @@ -48,12 +48,6 @@ #endif } -static inline void -release_spinlock(volatile lispobj *word) -{ - *word=0; -} - #include <stdio.h> static inline lispobj @@ -74,6 +68,14 @@ return old_value; } +static inline void +release_spinlock(volatile lispobj *word) +{ + /* A memory barrier is needed, use swap_lispobjs. See comment in + * RELEASE-SPINLOCK in target-thread.lisp. */ + swap_lispobjs(word,0); +} + extern void fast_bzero_detect(void *, size_t); extern void (*fast_bzero_pointer)(void *, size_t); |