diff options
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r-- | src/core/hle/kernel/scheduler.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 118c1aa95..9556df951 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -18,6 +18,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/scheduler.h" +#include "core/hle/kernel/time_manager.h" namespace Kernel { @@ -356,6 +357,29 @@ void GlobalScheduler::Shutdown() { thread_list.clear(); } +void GlobalScheduler::Lock() { + Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadId(); + if (current_thread == current_owner) { + ++scope_lock; + } else { + inner_lock.lock(); + current_owner = current_thread; + scope_lock = 1; + } +} + +void GlobalScheduler::Unlock() { + if (--scope_lock == 0) { + for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + SelectThread(i); + } + current_owner = Core::EmuThreadHandle::InvalidHandle(); + scope_lock = 1; + inner_lock.unlock(); + // TODO(Blinkhawk): Setup the interrupts and change context on current core. + } +} + Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) : system(system), cpu_core(cpu_core), core_id(core_id) {} @@ -485,4 +509,28 @@ void Scheduler::Shutdown() { selected_thread = nullptr; } +SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { + auto& global_scheduler = kernel.GlobalScheduler(); + global_scheduler.Lock(); +} + +SchedulerLock::~SchedulerLock() { + auto& global_scheduler = kernel.GlobalScheduler(); + global_scheduler.Unlock(); +} + +SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, + Thread* time_task, s64 nanoseconds) + : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{ + nanoseconds} { + event_handle = InvalidHandle; +} + +SchedulerLockAndSleep::~SchedulerLockAndSleep() { + if (!sleep_cancelled) { + auto& time_manager = kernel.TimeManager(); + time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); + } +} + } // namespace Kernel |