ios-unity/Libraries/external/baselib/Include/Cpp/Internal/ConditionVariable_SemaphoreBased.inl.h
2023-02-10 15:13:26 +08:00

62 lines
1.9 KiB
C++

#pragma once
namespace baselib
{
BASELIB_CPP_INTERFACE
{
inline void ConditionVariable::Wait()
{
m_Data.waiters.fetch_add(1, memory_order_relaxed);
m_Lock.Release();
m_Data.semaphore.Acquire();
m_Lock.Acquire();
}
inline bool ConditionVariable::TimedWait(const timeout_ms timeoutInMilliseconds)
{
m_Data.waiters.fetch_add(1, memory_order_relaxed);
m_Lock.Release();
bool acquired = m_Data.semaphore.TryTimedAcquire(timeoutInMilliseconds);
if (acquired)
{
m_Lock.Acquire();
return true;
}
do
{
uint32_t waiters = m_Data.waiters.load(memory_order_relaxed);
while (waiters > 0)
{
if (m_Data.waiters.compare_exchange_weak(waiters, waiters - 1, memory_order_relaxed, memory_order_relaxed))
{
m_Lock.Acquire();
return false;
}
}
Baselib_Thread_YieldExecution();
}
while (!m_Data.semaphore.TryAcquire());
m_Lock.Acquire();
return true;
}
inline void ConditionVariable::Notify(uint16_t count)
{
uint32_t waitingThreads, threadsToWakeup;
do
{
waitingThreads = m_Data.waiters.load(memory_order_acquire);
threadsToWakeup = count < waitingThreads ? count : waitingThreads;
if (threadsToWakeup == 0)
return;
}
while (!m_Data.waiters.compare_exchange_weak(waitingThreads, waitingThreads - threadsToWakeup, memory_order_relaxed, memory_order_relaxed));
m_Data.semaphore.Release(threadsToWakeup);
}
}
}