#ifdef _MULTITHREADED #ifdef PLATFORM_WIN32 typedef LONG Atomic; inline int AtomicRead(const volatile Atomic& t) { return t; } inline void AtomicWrite(volatile Atomic& t, int val) { t = val; } inline int AtomicInc(volatile Atomic& t) { return InterlockedIncrement((Atomic *)&t); } inline int AtomicDec(volatile Atomic& t) { return InterlockedDecrement((Atomic *)&t); } inline int AtomicXAdd(volatile Atomic& t, int incr) { return InterlockedExchangeAdd((Atomic *)&t, incr); } class CriticalSection { protected: CRITICAL_SECTION section; #ifdef _DEBUG dword threadid; #endif CriticalSection(int) {} public: void Enter(); void Leave(); CriticalSection(); ~CriticalSection() { DeleteCriticalSection(§ion); } struct Lock; }; #ifndef _DEBUG inline void CriticalSection::Enter() { EnterCriticalSection(§ion); } inline void CriticalSection::Leave() { LeaveCriticalSection(§ion); } inline CriticalSection::CriticalSection() { InitializeCriticalSection(§ion); } #endif #endif #ifdef PLATFORM_POSIX typedef _Atomic_word Atomic; inline int AtomicRead(const volatile Atomic& t) { return t; } inline void AtomicWrite(volatile Atomic& t, int val) { t = val; } inline int AtomicInc(volatile Atomic& t) { using namespace __gnu_cxx; __atomic_add(&t, 1); return t; } inline int AtomicDec(volatile Atomic& t) { using namespace __gnu_cxx; __atomic_add(&t, -1); return t; } inline int AtomicXAdd(volatile Atomic& t, int incr) { using namespace __gnu_cxx; return __exchange_and_add(&t, incr); } class CriticalSection { protected: pthread_mutex_t mutex[1]; CriticalSection(int) {} public: void Enter() { pthread_mutex_lock(mutex); } void Leave() { pthread_mutex_unlock(mutex); } struct Lock; CriticalSection() { pthread_mutex_init(mutex, NULL); } ~CriticalSection() { pthread_mutex_destroy(mutex); } }; #endif struct CriticalSection::Lock { CriticalSection& s; Lock(CriticalSection& s) : s(s) { s.Enter(); } ~Lock() { s.Leave(); } }; class StaticCriticalSection { volatile CriticalSection *section; byte buffer[sizeof(CriticalSection)]; void Initialize(); public: CriticalSection& Get() { if(!section) Initialize(); return *const_cast(section); } operator CriticalSection&() { return Get(); } void Enter() { Get().Enter(); } void Leave() { Get().Leave(); } }; #define INTERLOCKED \ for(bool i_b_ = true; i_b_;) \ for(static UPP::StaticCriticalSection i_ss_; i_b_;) \ for(UPP::CriticalSection::Lock i_ss_lock__(i_ss_); i_b_; i_b_ = false) #define INTERLOCKED_(cs) \ for(bool i_b_ = true; i_b_;) \ for(UPP::CriticalSection::Lock i_ss_lock__(cs); i_b_; i_b_ = false) #else typedef int Atomic; inline int AtomicRead(const volatile Atomic& t) { return t; } inline void AtomicWrite(volatile Atomic& t, int data) { t = data; } inline int AtomicInc(volatile Atomic& t) { ++t; return t; } inline int AtomicDec(volatile Atomic& t) { --t; return t; } inline int AtomicXAdd(volatile Atomic& t, int incr) { Atomic x = t; t += incr; return x; } class CriticalSection { public: void Enter() {} void Leave() {} CriticalSection() {} ~CriticalSection() {} struct Lock; }; typedef CriticalSection StaticCriticalSection; struct CriticalSection::Lock { Lock(CriticalSection&) {} ~Lock() {} }; #define INTERLOCKED #define INTERLOCKED_(x) #endif