|
|
@ -18,6 +18,7 @@ |
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
#include "core/hle/kernel/kernel.h"
|
|
|
#include "core/hle/kernel/process.h"
|
|
|
#include "core/hle/kernel/process.h"
|
|
|
#include "core/hle/kernel/scheduler.h"
|
|
|
#include "core/hle/kernel/scheduler.h"
|
|
|
|
|
|
#include "core/hle/kernel/time_manager.h"
|
|
|
|
|
|
|
|
|
namespace Kernel { |
|
|
namespace Kernel { |
|
|
|
|
|
|
|
|
@ -356,6 +357,29 @@ void GlobalScheduler::Shutdown() { |
|
|
thread_list.clear(); |
|
|
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) |
|
|
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) {} |
|
|
: system(system), cpu_core(cpu_core), core_id(core_id) {} |
|
|
|
|
|
|
|
|
@ -485,4 +509,28 @@ void Scheduler::Shutdown() { |
|
|
selected_thread = nullptr; |
|
|
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
|
|
|
} // namespace Kernel
|