diff options
| author | bunnei <bunneidev@gmail.com> | 2021-01-20 16:47:57 -0800 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2021-01-28 21:42:26 -0800 | 
| commit | ca78f77827376af1cd42f655dca6f8d1d2725200 (patch) | |
| tree | 0e8a382e4091d43bcb331f23b139c9997c2f5ac3 | |
| parent | cdd14b03e5c8e29bc6cd11bbde0ef726d2f166ce (diff) | |
hle: kernel: KScheduler: Introduce thread context_guard.
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 18 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 1 | 
2 files changed, 16 insertions, 3 deletions
| diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 5bdbd9a9b..e99122f4c 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -668,6 +668,7 @@ void KScheduler::Unload(KThread* thread) {          } else {              prev_thread = nullptr;          } +        thread->context_guard.unlock();      }  } @@ -700,15 +701,23 @@ void KScheduler::SwitchContextStep2() {  void KScheduler::ScheduleImpl() {      KThread* previous_thread = current_thread; -    current_thread = state.highest_priority_thread; +    KThread* next_thread = state.highest_priority_thread;      state.needs_scheduling = false; -    if (current_thread == previous_thread) { +    // We never want to schedule a null thread, so use the idle thread if we don't have a next. +    if (next_thread == nullptr) { +        next_thread = idle_thread; +    } + +    // If we're not actually switching thread, there's nothing to do. +    if (next_thread == current_thread) {          guard.unlock();          return;      } +    current_thread = next_thread; +      Process* const previous_process = system.Kernel().CurrentProcess();      UpdateLastContextSwitchTime(previous_thread, previous_process); @@ -748,10 +757,13 @@ void KScheduler::SwitchToCurrent() {          };          do {              if (current_thread != nullptr) { +                current_thread->context_guard.lock();                  if (current_thread->GetRawState() != ThreadState::Runnable) { +                    current_thread->context_guard.unlock();                      break;                  } -                if (static_cast<u32>(current_thread->GetActiveCore()) != core_id) { +                if (current_thread->GetActiveCore() != core_id) { +                    current_thread->context_guard.unlock();                      break;                  }              } diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 7845821ba..eeddf5a65 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -712,6 +712,7 @@ private:      s8 priority_inheritance_count{};      bool resource_limit_release_hint{};      StackParameters stack_parameters{}; +    Common::SpinLock context_guard{};      // For emulation      std::shared_ptr<Common::Fiber> host_context{}; | 
