void CondVar::Leave() { int lMutex = m_lMutex.load(std::memory_order_seq_cst); RL_ASSERT(lMutex < 0); for (;;) { unsigned dwWaitingToOwn = lMutex & 0x7FFFFFFFu; unsigned dwWaitingForSignal = m_dwWaitingForSignal.load(std::memory_order_seq_cst); RL_ASSERT(dwWaitingToOwn >= dwWaitingForSignal); if (dwWaitingToOwn == dwWaitingForSignal) { if (m_lMutex.compare_exchange_weak(lMutex, lMutex & 0x7FFFFFFF, std::memory_order_seq_cst)) break; } else { if (false == m_lMutex.compare_exchange_weak(lMutex, lMutex - 1, std::memory_order_seq_cst)) continue; SetEvent(m_xhEvtEnter); break; } } }
void thread(unsigned index) { if (0 == index) { HANDLE handles [2] = {sema1, sema2}; WaitForMultipleObjects(2, handles, 1, INFINITE); RL_ASSERT(data($) == 2); } else { data($) = 1; ReleaseSemaphore(sema1, 1, 0); data($) = 2; ReleaseSemaphore(sema2, 1, 0); } }
void thread(unsigned index) { if (0 == index) { HANDLE handles [2] = {sema1, sema2}; WaitForMultipleObjects(2, handles, 0, INFINITE); int d = data.load(rl::memory_order_relaxed); RL_ASSERT(d == 1 || d == 2); RL_UNTIL(d == 1); } else { data.store(1, rl::memory_order_relaxed); ReleaseSemaphore(sema1, 1, 0); data.store(2, rl::memory_order_relaxed); ReleaseSemaphore(sema2, 1, 0); } }
void thread(unsigned th) { if (0 == th) x.store(1, rl::memory_order_relaxed); else if (1 == th) { if (0 == x.load(rl::memory_order_relaxed)) return; y.store(1, rl::memory_order_release); x.load(rl::memory_order_relaxed); } else { if (0 == y.load(rl::memory_order_acquire)) return; RL_ASSERT(1 == x.load(rl::memory_order_relaxed)); } }
void CondVar::Enter() { int lMutex = m_lMutex.load(std::memory_order_seq_cst); for (;;) { if( lMutex >= 0 ) { if (m_lMutex.compare_exchange_weak(lMutex, lMutex | 0x80000000u, std::memory_order_seq_cst)) break; } else { if (false == m_lMutex.compare_exchange_weak(lMutex, lMutex + 1, std::memory_order_seq_cst)) continue; WaitForSingleObject(m_xhEvtEnter, INFINITE); RL_ASSERT(m_lMutex.load(std::memory_order_seq_cst) < 0); break; } } }
void after() { RL_ASSERT(data($) == 3); }
~nonblocking_spsc_queue() { RL_ASSERT(VAR(head) == VAR(tail)); delete (node*)VAR(head); }