diff options
| author | 2020-02-14 11:44:31 -0400 | |
|---|---|---|
| committer | 2020-02-22 11:18:07 -0400 | |
| commit | ea956c823e5e6b7f6fd16780b613263d6fadd5da (patch) | |
| tree | c5ce0c9e42f30b6342c064c50b0c712bf05cf5b0 /src/core/hle/kernel/scheduler.cpp | |
| parent | Kernel: Implement Time Manager. (diff) | |
| download | yuzu-ea956c823e5e6b7f6fd16780b613263d6fadd5da.tar.gz yuzu-ea956c823e5e6b7f6fd16780b613263d6fadd5da.tar.xz yuzu-ea956c823e5e6b7f6fd16780b613263d6fadd5da.zip | |
Kernel: Implement Scheduler locks
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 @@ | |||
| 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 | ||
| 22 | namespace Kernel { | 23 | namespace Kernel { |
| 23 | 24 | ||
| @@ -356,6 +357,29 @@ void GlobalScheduler::Shutdown() { | |||
| 356 | thread_list.clear(); | 357 | thread_list.clear(); |
| 357 | } | 358 | } |
| 358 | 359 | ||
| 360 | void 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 | scope_lock = 1; | ||
| 368 | } | ||
| 369 | } | ||
| 370 | |||
| 371 | void GlobalScheduler::Unlock() { | ||
| 372 | if (--scope_lock == 0) { | ||
| 373 | for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { | ||
| 374 | SelectThread(i); | ||
| 375 | } | ||
| 376 | current_owner = Core::EmuThreadHandle::InvalidHandle(); | ||
| 377 | scope_lock = 1; | ||
| 378 | inner_lock.unlock(); | ||
| 379 | // TODO(Blinkhawk): Setup the interrupts and change context on current core. | ||
| 380 | } | ||
| 381 | } | ||
| 382 | |||
| 359 | Scheduler::Scheduler(Core::System& system, Core::ARM_Interface& cpu_core, std::size_t core_id) | 383 | Scheduler::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) {} | 384 | : system(system), cpu_core(cpu_core), core_id(core_id) {} |
| 361 | 385 | ||
| @@ -485,4 +509,28 @@ void Scheduler::Shutdown() { | |||
| 485 | selected_thread = nullptr; | 509 | selected_thread = nullptr; |
| 486 | } | 510 | } |
| 487 | 511 | ||
| 512 | SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { | ||
| 513 | auto& global_scheduler = kernel.GlobalScheduler(); | ||
| 514 | global_scheduler.Lock(); | ||
| 515 | } | ||
| 516 | |||
| 517 | SchedulerLock::~SchedulerLock() { | ||
| 518 | auto& global_scheduler = kernel.GlobalScheduler(); | ||
| 519 | global_scheduler.Unlock(); | ||
| 520 | } | ||
| 521 | |||
| 522 | SchedulerLockAndSleep::SchedulerLockAndSleep(KernelCore& kernel, Handle& event_handle, | ||
| 523 | Thread* time_task, s64 nanoseconds) | ||
| 524 | : SchedulerLock{kernel}, event_handle{event_handle}, time_task{time_task}, nanoseconds{ | ||
| 525 | nanoseconds} { | ||
| 526 | event_handle = InvalidHandle; | ||
| 527 | } | ||
| 528 | |||
| 529 | SchedulerLockAndSleep::~SchedulerLockAndSleep() { | ||
| 530 | if (!sleep_cancelled) { | ||
| 531 | auto& time_manager = kernel.TimeManager(); | ||
| 532 | time_manager.ScheduleTimeEvent(event_handle, time_task, nanoseconds); | ||
| 533 | } | ||
| 534 | } | ||
| 535 | |||
| 488 | } // namespace Kernel | 536 | } // namespace Kernel |