gcc -v Using built-in specs. Target: i686-apple-darwin10 Configured with: /var/tmp/gcc/gcc-5659~1/src/configure --disable-checking --enable-werror --prefix=/usr --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin10 --program-prefix=i686-apple-darwin10- --host=x86_64-apple-darwin10 --target=i686-apple-darwin10 --with-gxx-include-dir=/include/c++/4.2.1 Thread model: posix gcc version 4.2.1 (Apple Inc. build 5659) -- BEGIN header OSAtomicLock.h #ifndef OSATOMICLOCK_H #define OSATOMICLOCK_H #if !defined(OS_INLINE) #if defined(__GNUC__) && (__GNUC__ == 4) && !defined(DEBUG) #define OS_INLINE static __inline__ __attribute__((always_inline)) #elif defined(__GNUC__) #define OS_INLINE static __inline__ #elif defined(__cplusplus) #define OS_INLINE static inline #elif defined(_MSC_VER) #define OS_INLINE static __inline #elif defined(__WIN32__) #define OS_INLINE static __inline__ #endif #endif #if defined(__WIN32__) typedef __int32 OSAtomicLockLock; #define OSAtomicLockInit 0 D_INLINE void __OSAtomicLockLock(volatile OSAtomicLock *LOCK) { while (InterlockedCompareExchange((LONG volatile *)LOCK, ~0, 0) != 0) { Sleep(0); } } D_INLINE void __OSAtomicLockUnlock(volatile OSAtomicLock *LOCK) { MemoryBarrier(); *LOCK = 0; } #elif defined(__APPLE__) #include <libkern/OSAtomic.h> typedef OSSpinLock OSAtomicLock; #define OSAtomicLockInit OS_SPINLOCK_INIT #define __OSAtomicLockLock(LOCK) ({ \ OSAtomicLock *lck_p = (LOCK); \ OSAtomicLock lck_v = *lck_p; \ if (0 != lck_v && ~0 != lck_v && (uintptr_t)lck_p != (uintptr_t)lck_v) { } \ OSSpinLockLock(lck_p); \ }) #define __OSAtomicLockUnlock(LOCK) ({ \ OSAtomicLock *lck_p = (LOCK); \ OSAtomicLock lck_v = *lck_p; \ if (~0 != lck_v && (uintptr_t)lck_p != (uintptr_t)lck_v) { } \ OSSpinLockUnlock(lck_p); \ }) #else // means posix #define _MULTI_THREADED #include <pthread.h> #if defined(__linux__) #define OSAtomicLockInit PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP #else #define OSAtomicLockInit PTHREAD_MUTEX_INITIALIZER #endif typedef pthread_mutex_t OSAtomicLock; #define __OSAtomicLockLock(LOCK) ({ \ OSAtomicLock *lck_p = (LOCK); \ pthread_mutex_lock(lck_p); \ }) #define __OSAtomicLockUnlock(LOCK) ({ \ OSAtomicLock *lck_p = (LOCK); \ pthread_mutex_unlock(lck_p); \ }) #endif #define OSAtomicLockInitialize(LOCK) (LOCK = OSAtomicLockInit) #define OSAtomicLockLock(LOCK) __OSAtomicLockLock(LOCK) #define OSAtomicLockUnlock(LOCK) __OSAtomicLockUnlock(LOCK) #define OSAtomicAutoLock(LOCK, BLOCK) \ OSAtomicLockLock(LOCK); \ BLOCK \ OSAtomicLockUnlock(LOCK); #endif // OSATOMICLOCK_H /* HOWTO static OSAtomicLock __myGlobalLock = OSAtomicLockInit; void mylocalfunc() { OSAtomicLockLock(&__myGlobalLock); //do stuff OSAtomicLockUnlock(&__myGlobalLock); } */ -- END header OSAtomicLock.h -- BEGIN test1.c #include <stdio.h> #include "OSAtomicLock.h" static OSAtomicLock __myGlobalLock = OSAtomicLockInit; int main (int argc, const char** argv) { OSAtomicLockLock(&__myGlobalLock); fprintf(stderr,"hello\n"); OSAtomicLockLock(&__myGlobalLock); return 0; } -- END test1.c -- BEGIN test2.c #include <stdio.h> #include "OSAtomicLock.h" static OSAtomicLock __myGlobalLock = OSAtomicLockInit; int main (int argc, const char** argv) { OSAtomicAutoLock ( &__myGlobalLock, fprintf(stderr,"hello\n"); ) return 0; } -- END test2.c and the main thread blocked; -- BEGIN test1.S L2: ... movq -24(%rbp), %rdi call _OSSpinLockUnlock movl $0, %eax leave ret -- END test1.S -- BEGIN test2.S L2: ... je L5 L5: movq -24(%rbp), %rdi call _OSSpinLockLock movl $0, %eax leave ret -- END test2.S and the main thread will bell; Best Regards