From 0728dfef84ded5e68bdb3b0781ea00ca7cc85659 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Thu, 13 Feb 2020 22:04:10 -0400 Subject: Kernel: Make global scheduler depend on KernelCore --- src/core/hle/kernel/scheduler.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/scheduler.cpp') diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 86f1421bf..118c1aa95 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -21,7 +21,7 @@ namespace Kernel { -GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {} +GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {} GlobalScheduler::~GlobalScheduler() = default; @@ -35,7 +35,7 @@ void GlobalScheduler::RemoveThread(std::shared_ptr thread) { } void GlobalScheduler::UnloadThread(std::size_t core) { - Scheduler& sched = system.Scheduler(core); + Scheduler& sched = kernel.Scheduler(core); sched.UnloadThread(); } @@ -50,7 +50,7 @@ void GlobalScheduler::SelectThread(std::size_t core) { sched.is_context_switch_pending = sched.selected_thread != sched.current_thread; std::atomic_thread_fence(std::memory_order_seq_cst); }; - Scheduler& sched = system.Scheduler(core); + Scheduler& sched = kernel.Scheduler(core); Thread* current_thread = nullptr; // Step 1: Get top thread in schedule queue. current_thread = scheduled_queue[core].empty() ? nullptr : scheduled_queue[core].front(); -- cgit v1.2.3 From ea956c823e5e6b7f6fd16780b613263d6fadd5da Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Fri, 14 Feb 2020 11:44:31 -0400 Subject: Kernel: Implement Scheduler locks --- src/core/hle/kernel/scheduler.cpp | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'src/core/hle/kernel/scheduler.cpp') 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 -- cgit v1.2.3 From d219a96cc828d17932beebead209ba696b92a911 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 22 Feb 2020 10:27:40 -0400 Subject: Kernel: Address Feedback. --- src/core/hle/kernel/scheduler.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/core/hle/kernel/scheduler.cpp') diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 9556df951..e5892727e 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -358,26 +358,29 @@ void GlobalScheduler::Shutdown() { } void GlobalScheduler::Lock() { - Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadId(); + Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadID(); if (current_thread == current_owner) { ++scope_lock; } else { inner_lock.lock(); current_owner = current_thread; + ASSERT(current_owner != Core::EmuThreadHandle::InvalidHandle()); 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. + if (--scope_lock != 0) { + ASSERT(scope_lock > 0); + return; + } + 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) -- cgit v1.2.3 From a1bf353780254b8cb03ea0f820917d104ce9ca66 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 22 Feb 2020 11:51:03 -0400 Subject: Kernel: Correct pending feedback. --- src/core/hle/kernel/scheduler.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/scheduler.cpp') diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index e5892727e..f2664ce65 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -530,10 +530,11 @@ SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_h } SchedulerLockAndSleep::~SchedulerLockAndSleep() { - if (!sleep_cancelled) { - auto& time_manager = kernel.TimeManager(); - time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); + if (sleep_cancelled) { + return; } + auto& time_manager = kernel.TimeManager(); + time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); } } // namespace Kernel -- cgit v1.2.3 From 3d0a2375ca73ae73d2ed4ee382aa0bb0378242d0 Mon Sep 17 00:00:00 2001 From: Fernando Sahmkow Date: Sat, 22 Feb 2020 12:39:17 -0400 Subject: Scheduler: Inline global scheduler in Scheduler Lock. --- src/core/hle/kernel/scheduler.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/scheduler.cpp') diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index f2664ce65..c65f82fb7 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -513,13 +513,11 @@ void Scheduler::Shutdown() { } SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { - auto& global_scheduler = kernel.GlobalScheduler(); - global_scheduler.Lock(); + kernel.GlobalScheduler().Lock(); } SchedulerLock::~SchedulerLock() { - auto& global_scheduler = kernel.GlobalScheduler(); - global_scheduler.Unlock(); + kernel.GlobalScheduler().Unlock(); } SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, -- cgit v1.2.3