/* * Provides atomic operations for SMP/MT safety. Uses whatever OS Primitives * are offered. * * Current implementation should be complete on Mac OS X 10.4, but does not provide * complete barriers on Linux. * * By including this file, you should have the following atomic primitives: * fullMemoryBarrier() * readMemoryBarrier() * writeMemoryBarrier() * * template bool CASPointer( T oldVal, T newVal, T* Val ) */ #ifndef ATOMIC_H #define ATOMIC_H using namespace std; #if defined(__linux__) || defined(__FreeBSD__) //extern "C" { //# define new nw //# define unlikely(a) __builtin_expect(a,false) //# include //# undef new //} //# define fullMemoryBarrier() do{ asm volatile("":::"memory"); smp_mb(); }while(false) //# define readMemoryBarrier() do{ asm volatile("":::"memory"); smp_rmb(); }while(false) //# define writeMemoryBarrier() do{ asm volatile("":::"memory"); smp_wmb(); }while(false) # define fullMemoryBarrier() do{ asm volatile("":::"memory"); }while(false) # define readMemoryBarrier() do{ asm volatile("":::"memory"); }while(false) # define writeMemoryBarrier() do{ asm volatile("":::"memory"); }while(false) #elif defined(__APPLE__) # include # include /* Here are the memory barrier functions. Mac OS X only provides full memory barriers, so the three types of barriers are the same. The asm volatile may be redundant with the memory barrier, but until I have proof of that, I'm leaving it. The assembly calls are probably unnecessary */ # define fullMemoryBarrier() do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false) # define readMemoryBarrier() do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false) # define writeMemoryBarrier() do{ asm volatile("":::"memory"); OSMemoryBarrier(); }while(false) template bool CASPointer( T oldVal, T newVal, T* Val ) { if( sizeof( T ) == 4 ) return OSAtomicCompareAndSwap32( (int32_t)oldVal, (int32_t)newVal, (int32_t *)Val ); //else if( sizeof( T ) == 8 ) // return OSAtomicCompareAndSwap64( (int64_t)oldVal, (int64_t)newVal, (int64_t *)Val ); else throw runtime_error( "Unkown size in comparison" ); } #elif defined(_MSC_VER) && (_MSC_VER >= 1400) /* For Visual C++ 8.0 and above, use these Microsoft-specific * memory barriers. * Ref: http://msdn2.microsoft.com/en-us/library/f20w0x5e(VS.80).aspx */ # include # pragma intrinsic(_ReadWriteBarrier) # pragma intrinsic(_ReadBarrier) # pragma intrinsic(_WriteBarrier) # define PaUtil_FullMemoryBarrier() _ReadWriteBarrier() # define PaUtil_ReadMemoryBarrier() _ReadBarrier() # define PaUtil_WriteMemoryBarrier() _WriteBarrier() #else # error "Memory Barriers not defined on this system or system unknown." #endif #endif /* ATOMIC_H */