diff options
Diffstat (limited to '')
| -rw-r--r-- | src/core/cpu_manager.cpp | 42 | ||||
| -rw-r--r-- | src/core/cpu_manager.h | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scheduler.h | 5 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_thread.h | 1 |
6 files changed, 28 insertions, 40 deletions
diff --git a/src/core/cpu_manager.cpp b/src/core/cpu_manager.cpp index 838d6be21..9b1565ae1 100644 --- a/src/core/cpu_manager.cpp +++ b/src/core/cpu_manager.cpp | |||
| @@ -144,39 +144,25 @@ void CpuManager::SingleCoreRunIdleThread() { | |||
| 144 | } | 144 | } |
| 145 | 145 | ||
| 146 | void CpuManager::PreemptSingleCore(bool from_running_environment) { | 146 | void CpuManager::PreemptSingleCore(bool from_running_environment) { |
| 147 | { | 147 | auto& kernel = system.Kernel(); |
| 148 | auto& kernel = system.Kernel(); | ||
| 149 | auto& scheduler = kernel.Scheduler(current_core); | ||
| 150 | |||
| 151 | Kernel::KThread* current_thread = scheduler.GetSchedulerCurrentThread(); | ||
| 152 | if (idle_count >= 4 || from_running_environment) { | ||
| 153 | if (!from_running_environment) { | ||
| 154 | system.CoreTiming().Idle(); | ||
| 155 | idle_count = 0; | ||
| 156 | } | ||
| 157 | kernel.SetIsPhantomModeForSingleCore(true); | ||
| 158 | system.CoreTiming().Advance(); | ||
| 159 | kernel.SetIsPhantomModeForSingleCore(false); | ||
| 160 | } | ||
| 161 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||
| 162 | system.CoreTiming().ResetTicks(); | ||
| 163 | scheduler.Unload(scheduler.GetSchedulerCurrentThread()); | ||
| 164 | |||
| 165 | auto& next_scheduler = kernel.Scheduler(current_core); | ||
| 166 | 148 | ||
| 167 | // Disable dispatch. We're about to preempt this thread. | 149 | if (idle_count >= 4 || from_running_environment) { |
| 168 | Kernel::KScopedDisableDispatch dd{kernel}; | 150 | if (!from_running_environment) { |
| 169 | Common::Fiber::YieldTo(current_thread->GetHostContext(), *next_scheduler.GetSwitchFiber()); | 151 | system.CoreTiming().Idle(); |
| 152 | idle_count = 0; | ||
| 153 | } | ||
| 154 | kernel.SetIsPhantomModeForSingleCore(true); | ||
| 155 | system.CoreTiming().Advance(); | ||
| 156 | kernel.SetIsPhantomModeForSingleCore(false); | ||
| 170 | } | 157 | } |
| 158 | current_core.store((current_core + 1) % Core::Hardware::NUM_CPU_CORES); | ||
| 159 | system.CoreTiming().ResetTicks(); | ||
| 160 | kernel.Scheduler(current_core).PreemptSingleCore(); | ||
| 171 | 161 | ||
| 172 | // We've now been scheduled again, and we may have exchanged schedulers. | 162 | // We've now been scheduled again, and we may have exchanged schedulers. |
| 173 | // Reload the scheduler in case it's different. | 163 | // Reload the scheduler in case it's different. |
| 174 | { | 164 | if (!kernel.Scheduler(current_core).IsIdle()) { |
| 175 | auto& scheduler = system.Kernel().Scheduler(current_core); | 165 | idle_count = 0; |
| 176 | scheduler.Reload(scheduler.GetSchedulerCurrentThread()); | ||
| 177 | if (!scheduler.IsIdle()) { | ||
| 178 | idle_count = 0; | ||
| 179 | } | ||
| 180 | } | 166 | } |
| 181 | } | 167 | } |
| 182 | 168 | ||
diff --git a/src/core/cpu_manager.h b/src/core/cpu_manager.h index 835505b92..95ea3ef39 100644 --- a/src/core/cpu_manager.h +++ b/src/core/cpu_manager.h | |||
| @@ -5,7 +5,6 @@ | |||
| 5 | 5 | ||
| 6 | #include <array> | 6 | #include <array> |
| 7 | #include <atomic> | 7 | #include <atomic> |
| 8 | #include <csetjmp> | ||
| 9 | #include <functional> | 8 | #include <functional> |
| 10 | #include <memory> | 9 | #include <memory> |
| 11 | #include <thread> | 10 | #include <thread> |
diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index cac96a780..230ca3b95 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp | |||
| @@ -103,7 +103,20 @@ void KScheduler::ScheduleOnInterrupt() { | |||
| 103 | GetCurrentThread(kernel).EnableDispatch(); | 103 | GetCurrentThread(kernel).EnableDispatch(); |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | void KScheduler::PreemptSingleCore() { | ||
| 107 | GetCurrentThread(kernel).DisableDispatch(); | ||
| 108 | |||
| 109 | auto* thread = GetCurrentThreadPointer(kernel); | ||
| 110 | auto& previous_scheduler = kernel.Scheduler(thread->GetCurrentCore()); | ||
| 111 | previous_scheduler.Unload(thread); | ||
| 112 | |||
| 113 | Common::Fiber::YieldTo(thread->GetHostContext(), *m_switch_fiber); | ||
| 114 | |||
| 115 | GetCurrentThread(kernel).EnableDispatch(); | ||
| 116 | } | ||
| 117 | |||
| 106 | void KScheduler::RescheduleCurrentCore() { | 118 | void KScheduler::RescheduleCurrentCore() { |
| 119 | ASSERT(!kernel.IsPhantomModeForSingleCore()); | ||
| 107 | ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() == 1); | 120 | ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() == 1); |
| 108 | 121 | ||
| 109 | GetCurrentThread(kernel).EnableDispatch(); | 122 | GetCurrentThread(kernel).EnableDispatch(); |
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 91e870933..ac7421c9a 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h | |||
| @@ -49,6 +49,7 @@ public: | |||
| 49 | 49 | ||
| 50 | void SetInterruptTaskRunnable(); | 50 | void SetInterruptTaskRunnable(); |
| 51 | void RequestScheduleOnInterrupt(); | 51 | void RequestScheduleOnInterrupt(); |
| 52 | void PreemptSingleCore(); | ||
| 52 | 53 | ||
| 53 | u64 GetIdleCount() { | 54 | u64 GetIdleCount() { |
| 54 | return m_state.idle_count; | 55 | return m_state.idle_count; |
| @@ -62,10 +63,6 @@ public: | |||
| 62 | return m_current_thread.load() == m_idle_thread; | 63 | return m_current_thread.load() == m_idle_thread; |
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | std::shared_ptr<Common::Fiber> GetSwitchFiber() { | ||
| 66 | return m_switch_fiber; | ||
| 67 | } | ||
| 68 | |||
| 69 | KThread* GetPreviousThread() const { | 66 | KThread* GetPreviousThread() const { |
| 70 | return m_state.prev_thread; | 67 | return m_state.prev_thread; |
| 71 | } | 68 | } |
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index d5d390f04..3640d1d13 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -1204,12 +1204,6 @@ KScopedDisableDispatch::~KScopedDisableDispatch() { | |||
| 1204 | return; | 1204 | return; |
| 1205 | } | 1205 | } |
| 1206 | 1206 | ||
| 1207 | // Skip the reschedule if single-core. | ||
| 1208 | if (!Settings::values.use_multi_core.GetValue()) { | ||
| 1209 | GetCurrentThread(kernel).EnableDispatch(); | ||
| 1210 | return; | ||
| 1211 | } | ||
| 1212 | |||
| 1213 | if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) { | 1207 | if (GetCurrentThread(kernel).GetDisableDispatchCount() <= 1) { |
| 1214 | auto scheduler = kernel.CurrentScheduler(); | 1208 | auto scheduler = kernel.CurrentScheduler(); |
| 1215 | 1209 | ||
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 1fc8f5f3e..9ee20208e 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h | |||
| @@ -110,7 +110,6 @@ void SetCurrentThread(KernelCore& kernel, KThread* thread); | |||
| 110 | [[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); | 110 | [[nodiscard]] KThread* GetCurrentThreadPointer(KernelCore& kernel); |
| 111 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); | 111 | [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); |
| 112 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); | 112 | [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); |
| 113 | size_t CaptureBacktrace(void** buffer, size_t max); | ||
| 114 | 113 | ||
| 115 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, | 114 | class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KWorkerTask>, |
| 116 | public boost::intrusive::list_base_hook<> { | 115 | public boost::intrusive::list_base_hook<> { |