summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/scheduler.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2020-02-22 22:32:21 -0500
committerGravatar GitHub2020-02-22 22:32:21 -0500
commit3ef5f2017dba35742b32500e95744512dd5ef630 (patch)
treeca5359a2ae4e34608e5564e43bdefe4946e413c8 /src/core/hle/kernel/scheduler.cpp
parentMerge pull request #3444 from bunnei/linux-audio-fix (diff)
parentScheduler: Inline global scheduler in Scheduler Lock. (diff)
downloadyuzu-3ef5f2017dba35742b32500e95744512dd5ef630.tar.gz
yuzu-3ef5f2017dba35742b32500e95744512dd5ef630.tar.xz
yuzu-3ef5f2017dba35742b32500e95744512dd5ef630.zip
Merge pull request #3416 from FernandoS27/schedule
Kernel: Refactors and Implement a TimeManager and SchedulerLocks
Diffstat (limited to 'src/core/hle/kernel/scheduler.cpp')
-rw-r--r--src/core/hle/kernel/scheduler.cpp56
1 files changed, 53 insertions, 3 deletions
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 86f1421bf..c65f82fb7 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -18,10 +18,11 @@
18#include "core/hle/kernel/kernel.h" 18#include "core/hle/kernel/kernel.h"
19#include "core/hle/kernel/process.h" 19#include "core/hle/kernel/process.h"
20#include "core/hle/kernel/scheduler.h" 20#include "core/hle/kernel/scheduler.h"
21#include "core/hle/kernel/time_manager.h"
21 22
22namespace Kernel { 23namespace Kernel {
23 24
24GlobalScheduler::GlobalScheduler(Core::System& system) : system{system} {} 25GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {}
25 26
26GlobalScheduler::~GlobalScheduler() = default; 27GlobalScheduler::~GlobalScheduler() = default;
27 28
@@ -35,7 +36,7 @@ void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) {
35} 36}
36 37
37void GlobalScheduler::UnloadThread(std::size_t core) { 38void GlobalScheduler::UnloadThread(std::size_t core) {
38 Scheduler& sched = system.Scheduler(core); 39 Scheduler& sched = kernel.Scheduler(core);
39 sched.UnloadThread(); 40 sched.UnloadThread();
40} 41}
41 42
@@ -50,7 +51,7 @@ void GlobalScheduler::SelectThread(std::size_t core) {
50 sched.is_context_switch_pending = sched.selected_thread != sched.current_thread; 51 sched.is_context_switch_pending = sched.selected_thread != sched.current_thread;
51 std::atomic_thread_fence(std::memory_order_seq_cst); 52 std::atomic_thread_fence(std::memory_order_seq_cst);
52 }; 53 };
53 Scheduler& sched = system.Scheduler(core); 54 Scheduler& sched = kernel.Scheduler(core);
54 Thread* current_thread = nullptr; 55 Thread* current_thread = nullptr;
55 // Step 1: Get top thread in schedule queue. 56 // Step 1: Get top thread in schedule queue.
56 current_thread = scheduled_queue[core].empty() ? nullptr : scheduled_queue[core].front(); 57 current_thread = scheduled_queue[core].empty() ? nullptr : scheduled_queue[core].front();
@@ -356,6 +357,32 @@ void GlobalScheduler::Shutdown() {
356 thread_list.clear(); 357 thread_list.clear();
357} 358}
358 359
360void GlobalScheduler::Lock() {
361 Core::EmuThreadHandle current_thread = kernel.GetCurrentEmuThreadID();
362 if (current_thread == current_owner) {
363 ++scope_lock;
364 } else {
365 inner_lock.lock();
366 current_owner = current_thread;
367 ASSERT(current_owner != Core::EmuThreadHandle::InvalidHandle());
368 scope_lock = 1;
369 }
370}
371
372void GlobalScheduler::Unlock() {
373 if (--scope_lock != 0) {
374 ASSERT(scope_lock > 0);
375 return;
376 }
377 for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
378 SelectThread(i);
379 }
380 current_owner = Core::EmuThreadHandle::InvalidHandle();
381 scope_lock = 1;
382 inner_lock.unlock();
383 // TODO(Blinkhawk): Setup the interrupts and change context on current core.
384}
385
359Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) 386Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id)
360 : system(system), cpu_core(cpu_core), core_id(core_id) {} 387 : system(system), cpu_core(cpu_core), core_id(core_id) {}
361 388
@@ -485,4 +512,27 @@ void Scheduler::Shutdown() {
485 selected_thread = nullptr; 512 selected_thread = nullptr;
486} 513}
487 514
515SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} {
516 kernel.GlobalScheduler().Lock();
517}
518
519SchedulerLock::~SchedulerLock() {
520 kernel.GlobalScheduler().Unlock();
521}
522
523SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle,
524 Thread* time_task, s64 nanoseconds)
525 : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{
526 nanoseconds} {
527 event_handle = InvalidHandle;
528}
529
530SchedulerLockAndSleep::~SchedulerLockAndSleep() {
531 if (sleep_cancelled) {
532 return;
533 }
534 auto& time_manager = kernel.TimeManager();
535 time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds);
536}
537
488} // namespace Kernel 538} // namespace Kernel