#pragma once #include #include #include #include class TFutexLike { private: #ifdef _linux_ int Value; #else TAtomic Value; TMutex Mutex; TCondVar CondVar; #endif public: TFutexLike() : Value(0) { } int AddAndGet(int add) { #ifdef _linux_ //return __atomic_add_fetch(&Value, add, __ATOMIC_SEQ_CST); return __sync_add_and_fetch(&Value, add); #else return AtomicAdd(Value, add); #endif } int GetAndAdd(int add) { return AddAndGet(add) - add; } // until we have modern GCC #if 0 int GetAndSet(int newValue) { #ifdef _linux_ return __atomic_exchange_n(&Value, newValue, __ATOMIC_SEQ_CST); #else return AtomicSwap(&Value, newValue); #endif } #endif int Get() { #ifdef _linux_ //return __atomic_load_n(&Value, __ATOMIC_SEQ_CST); __sync_synchronize(); return Value; #else return AtomicGet(Value); #endif } void Set(int newValue) { #ifdef _linux_ //__atomic_store_n(&Value, newValue, __ATOMIC_SEQ_CST); Value = newValue; __sync_synchronize(); #else AtomicSet(Value, newValue); #endif } int GetAndIncrement() { return AddAndGet(1) - 1; } int IncrementAndGet() { return AddAndGet(1); } int GetAndDecrement() { return AddAndGet(-1) + 1; } int DecrementAndGet() { return AddAndGet(-1); } void Wake(size_t count = Max()); void Wait(int expected); };