Kernel: Implement Scheduler locks

This commit is contained in:
Fernando Sahmkow 2020-02-14 11:44:31 -04:00 committed by FernandoS27
parent 5c90d22f3d
commit ea956c823e
2 changed files with 89 additions and 0 deletions

View file

@ -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