class Atomic { std::atomic<int> val = 0; static const int writeLockBit = 0x40000000; static const int upgradableBit = 0x00010000; static const int readerBits = 0x0000ffff; void LockInternal(int delta, int testBits) { int expected; do { do { expected = val; } while (expected & testBits); } while (!val.compare_exchange_weak(expected, expected + delta)); } public: void ReadLock() { LockInternal(1, writeLockBit); } void ReadUnlock() { val.fetch_sub(1); } void ReadLockUpgradable() { LockInternal(upgradableBit, writeLockBit | upgradableBit); } void ReadUnlockUpgradable() { val.fetch_sub(upgradableBit); } void Upgrade() { LockInternal(writeLockBit - upgradableBit, readerBits | writeLockBit); } void WriteLock() { LockInternal(writeLockBit, readerBits | writeLockBit); } void WriteUnlock() { val.fetch_sub(writeLockBit); } };