From 3be1a565f895d5399a6c1f6d0997dc528537fe86 Mon Sep 17 00:00:00 2001 From: Chloe Marcec Date: Sat, 30 Jan 2021 20:40:49 +1100 Subject: kernel: Rewrite resource limit to be more accurate Matches closer to hardware --- src/core/hle/kernel/k_light_condition_variable.h | 60 ++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 src/core/hle/kernel/k_light_condition_variable.h (limited to 'src/core/hle/kernel/k_light_condition_variable.h') diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h new file mode 100644 index 000000000..26573a239 --- /dev/null +++ b/src/core/hle/kernel/k_light_condition_variable.h @@ -0,0 +1,60 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" +#include "core/hle/kernel/k_thread_queue.h" +#include "core/hle/kernel/time_manager.h" + +namespace Kernel { +class KernelCore; + +class KLightConditionVariable { +private: + KThreadQueue m_thread_queue; + +public: + KLightConditionVariable(KernelCore& kernel) : m_thread_queue(kernel), kernel(kernel) {} + + void Wait(KLightLock* lock, s64 timeout = -1ll) { + WaitImpl(lock, timeout); + lock->Lock(); + } + + void Broadcast() { + KScopedSchedulerLock lk{kernel}; + while (m_thread_queue.WakeupFrontThread() != nullptr) { + /* We want to signal all threads, and so should continue waking up until there's nothing + * to wake. */ + } + } + +private: + void WaitImpl(KLightLock* lock, s64 timeout) { + KThread* owner = GetCurrentThreadPointer(kernel); + // KHardwareTimer* timer; + + /* Sleep the thread. */ + { + KScopedSchedulerLockAndSleep lk(kernel, owner, timeout); + lock->Unlock(); + + if (!m_thread_queue.SleepThread(owner)) { + lk.CancelSleep(); + return; + } + } + + /* Cancel the task that the sleep setup. */ + kernel.TimeManager().UnscheduleTimeEvent(owner); + } + KernelCore& kernel; +}; +} // namespace Kernel -- cgit v1.2.3