Atmosphere/mesosphere/source/threading/KConditionVariable.cpp

43 lines
1.2 KiB
C++
Raw Normal View History

2018-10-31 20:47:31 +00:00
#include <mesosphere/threading/KConditionVariable.hpp>
#include <mesosphere/threading/KScheduler.hpp>
#include <mesosphere/core/KCoreContext.hpp>
namespace mesosphere
{
void KConditionVariable::wait_until_impl(const KSystemClock::time_point &timeoutPoint) noexcept
{
// Official kernel counts number of waiters, but that isn't necessary
bool hasWaited = false;
KThread *currentThread = KCoreContext::GetCurrentInstance().GetCurrentThread();
2018-10-31 20:47:31 +00:00
{
2018-11-05 13:12:38 +00:00
KScopedCriticalSection criticalSection{};
2018-10-31 20:47:31 +00:00
mutex_.unlock();
if (currentThread->WaitForKernelSync(waiterList) && timeoutPoint > KSystemClock::time_point{}) {
hasWaited = true;
currentThread->SetAlarmTime(timeoutPoint);
2018-10-31 20:47:31 +00:00
}
}
if (hasWaited) {
currentThread->ClearAlarm();
}
2018-10-31 20:47:31 +00:00
mutex_.lock();
}
void KConditionVariable::notify_one() noexcept
{
2018-11-05 13:12:38 +00:00
KScopedCriticalSection criticalSection{};
2018-10-31 20:47:31 +00:00
auto t = waiterList.begin();
if (t != waiterList.end()) {
t->ResumeFromKernelSync();
}
}
void KConditionVariable::notify_all() noexcept
{
2018-11-05 13:12:38 +00:00
KScopedCriticalSection criticalSection{};
2018-10-31 20:47:31 +00:00
KThread::ResumeAllFromKernelSync(waiterList);
}
}