ReadGuard ReadWriteLock::TryRead() { u32 current_key = (mMutualExclusivityMask & READ_COUNT_MASK); u32 insert_key = current_key + 1; const bool success = (atomic_compare_and_swap(&mMutualExclusivityMask, current_key, insert_key) == current_key); return success ? ReadGuard(this) : ReadGuard(nullptr); }
ReadGuard ReadWriteLock::Read() { const u32 lock_key(EXCL_ENCODE(exclusive_write, 0)); // No need to encode since we know the insert counter exclusively owns the lower 28 bits of mMutualExclusivityMask. // mask off the mutualexclusitivity to get the insert count. should aquire (or keep) insert exclusivity by inrementing insert count. const ThreadID threadID = GetCurrentThreadId(); u32 current_key = (mMutualExclusivityMask & READ_COUNT_MASK); u32 insert_key = current_key + 1; while (atomic_compare_and_swap(&mMutualExclusivityMask, current_key, insert_key) != current_key) { if (threadID == mWriteEntryThread && mMutualExclusivityMask == lock_key) { atomic_increment((u32*)&mReentrancyCount); break; } cond_wait(); current_key = (mMutualExclusivityMask & READ_COUNT_MASK); insert_key = current_key + 1; } return ReadGuard(this); }
inline ReadGuard read_guard() { return ReadGuard(this); }