summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/scheduler.h
diff options
context:
space:
mode:
authorGravatar bunnei2020-06-28 12:37:50 -0400
committerGravatar GitHub2020-06-28 12:37:50 -0400
commitb05795d704e0c194215f815a5703db09e524b59a (patch)
treeecf4023b4ee0c91555c1d8263762fcb9dcb04a17 /src/core/hle/kernel/scheduler.h
parentMerge pull request #4196 from ogniK5377/nrr-nro-fixes (diff)
parentCore/Common: Address Feedback. (diff)
downloadyuzu-b05795d704e0c194215f815a5703db09e524b59a.tar.gz
yuzu-b05795d704e0c194215f815a5703db09e524b59a.tar.xz
yuzu-b05795d704e0c194215f815a5703db09e524b59a.zip
Merge pull request #3955 from FernandoS27/prometheus-2b
Remake Kernel Scheduling, CPU Management & Boot Management (Prometheus)
Diffstat (limited to 'src/core/hle/kernel/scheduler.h')
-rw-r--r--src/core/hle/kernel/scheduler.h123
1 files changed, 85 insertions, 38 deletions
diff --git a/src/core/hle/kernel/scheduler.h b/src/core/hle/kernel/scheduler.h
index 07df33f9c..b3b4b5169 100644
--- a/src/core/hle/kernel/scheduler.h
+++ b/src/core/hle/kernel/scheduler.h
@@ -11,9 +11,14 @@
11 11
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "common/multi_level_queue.h" 13#include "common/multi_level_queue.h"
14#include "common/spin_lock.h"
14#include "core/hardware_properties.h" 15#include "core/hardware_properties.h"
15#include "core/hle/kernel/thread.h" 16#include "core/hle/kernel/thread.h"
16 17
18namespace Common {
19class Fiber;
20}
21
17namespace Core { 22namespace Core {
18class ARM_Interface; 23class ARM_Interface;
19class System; 24class System;
@@ -41,41 +46,17 @@ public:
41 return thread_list; 46 return thread_list;
42 } 47 }
43 48
44 /** 49 /// Notify the scheduler a thread's status has changed.
45 * Add a thread to the suggested queue of a cpu core. Suggested threads may be 50 void AdjustSchedulingOnStatus(Thread* thread, u32 old_flags);
46 * picked if no thread is scheduled to run on the core.
47 */
48 void Suggest(u32 priority, std::size_t core, Thread* thread);
49
50 /**
51 * Remove a thread to the suggested queue of a cpu core. Suggested threads may be
52 * picked if no thread is scheduled to run on the core.
53 */
54 void Unsuggest(u32 priority, std::size_t core, Thread* thread);
55
56 /**
57 * Add a thread to the scheduling queue of a cpu core. The thread is added at the
58 * back the queue in its priority level.
59 */
60 void Schedule(u32 priority, std::size_t core, Thread* thread);
61
62 /**
63 * Add a thread to the scheduling queue of a cpu core. The thread is added at the
64 * front the queue in its priority level.
65 */
66 void SchedulePrepend(u32 priority, std::size_t core, Thread* thread);
67 51
68 /// Reschedule an already scheduled thread based on a new priority 52 /// Notify the scheduler a thread's priority has changed.
69 void Reschedule(u32 priority, std::size_t core, Thread* thread); 53 void AdjustSchedulingOnPriority(Thread* thread, u32 old_priority);
70
71 /// Unschedules a thread.
72 void Unschedule(u32 priority, std::size_t core, Thread* thread);
73 54
74 /// Selects a core and forces it to unload its current thread's context 55 /// Notify the scheduler a thread's core and/or affinity mask has changed.
75 void UnloadThread(std::size_t core); 56 void AdjustSchedulingOnAffinity(Thread* thread, u64 old_affinity_mask, s32 old_core);
76 57
77 /** 58 /**
78 * Takes care of selecting the new scheduled thread in three steps: 59 * Takes care of selecting the new scheduled threads in three steps:
79 * 60 *
80 * 1. First a thread is selected from the top of the priority queue. If no thread 61 * 1. First a thread is selected from the top of the priority queue. If no thread
81 * is obtained then we move to step two, else we are done. 62 * is obtained then we move to step two, else we are done.
@@ -85,8 +66,10 @@ public:
85 * 66 *
86 * 3. Third is no suggested thread is found, we do a second pass and pick a running 67 * 3. Third is no suggested thread is found, we do a second pass and pick a running
87 * thread in another core and swap it with its current thread. 68 * thread in another core and swap it with its current thread.
69 *
70 * returns the cores needing scheduling.
88 */ 71 */
89 void SelectThread(std::size_t core); 72 u32 SelectThreads();
90 73
91 bool HaveReadyThreads(std::size_t core_id) const { 74 bool HaveReadyThreads(std::size_t core_id) const {
92 return !scheduled_queue[core_id].empty(); 75 return !scheduled_queue[core_id].empty();
@@ -149,6 +132,40 @@ private:
149 /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling 132 /// Unlocks the scheduler, reselects threads, interrupts cores for rescheduling
150 /// and reschedules current core if needed. 133 /// and reschedules current core if needed.
151 void Unlock(); 134 void Unlock();
135
136 void EnableInterruptAndSchedule(u32 cores_pending_reschedule,
137 Core::EmuThreadHandle global_thread);
138
139 /**
140 * Add a thread to the suggested queue of a cpu core. Suggested threads may be
141 * picked if no thread is scheduled to run on the core.
142 */
143 void Suggest(u32 priority, std::size_t core, Thread* thread);
144
145 /**
146 * Remove a thread to the suggested queue of a cpu core. Suggested threads may be
147 * picked if no thread is scheduled to run on the core.
148 */
149 void Unsuggest(u32 priority, std::size_t core, Thread* thread);
150
151 /**
152 * Add a thread to the scheduling queue of a cpu core. The thread is added at the
153 * back the queue in its priority level.
154 */
155 void Schedule(u32 priority, std::size_t core, Thread* thread);
156
157 /**
158 * Add a thread to the scheduling queue of a cpu core. The thread is added at the
159 * front the queue in its priority level.
160 */
161 void SchedulePrepend(u32 priority, std::size_t core, Thread* thread);
162
163 /// Reschedule an already scheduled thread based on a new priority
164 void Reschedule(u32 priority, std::size_t core, Thread* thread);
165
166 /// Unschedules a thread.
167 void Unschedule(u32 priority, std::size_t core, Thread* thread);
168
152 /** 169 /**
153 * Transfers a thread into an specific core. If the destination_core is -1 170 * Transfers a thread into an specific core. If the destination_core is -1
154 * it will be unscheduled from its source code and added into its suggested 171 * it will be unscheduled from its source code and added into its suggested
@@ -170,10 +187,13 @@ private:
170 std::array<u32, Core::Hardware::NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62}; 187 std::array<u32, Core::Hardware::NUM_CPU_CORES> preemption_priorities = {59, 59, 59, 62};
171 188
172 /// Scheduler lock mechanisms. 189 /// Scheduler lock mechanisms.
173 std::mutex inner_lock{}; // TODO(Blinkhawk): Replace for a SpinLock 190 bool is_locked{};
191 Common::SpinLock inner_lock{};
174 std::atomic<s64> scope_lock{}; 192 std::atomic<s64> scope_lock{};
175 Core::EmuThreadHandle current_owner{Core::EmuThreadHandle::InvalidHandle()}; 193 Core::EmuThreadHandle current_owner{Core::EmuThreadHandle::InvalidHandle()};
176 194
195 Common::SpinLock global_list_guard{};
196
177 /// Lists all thread ids that aren't deleted/etc. 197 /// Lists all thread ids that aren't deleted/etc.
178 std::vector<std::shared_ptr<Thread>> thread_list; 198 std::vector<std::shared_ptr<Thread>> thread_list;
179 KernelCore& kernel; 199 KernelCore& kernel;
@@ -190,11 +210,11 @@ public:
190 /// Reschedules to the next available thread (call after current thread is suspended) 210 /// Reschedules to the next available thread (call after current thread is suspended)
191 void TryDoContextSwitch(); 211 void TryDoContextSwitch();
192 212
193 /// Unloads currently running thread 213 /// The next two are for SingleCore Only.
194 void UnloadThread(); 214 /// Unload current thread before preempting core.
195 215 void Unload();
196 /// Select the threads in top of the scheduling multilist. 216 /// Reload current thread after core preemption.
197 void SelectThreads(); 217 void Reload();
198 218
199 /// Gets the current running thread 219 /// Gets the current running thread
200 Thread* GetCurrentThread() const; 220 Thread* GetCurrentThread() const;
@@ -209,15 +229,30 @@ public:
209 return is_context_switch_pending; 229 return is_context_switch_pending;
210 } 230 }
211 231
232 void Initialize();
233
212 /// Shutdowns the scheduler. 234 /// Shutdowns the scheduler.
213 void Shutdown(); 235 void Shutdown();
214 236
237 void OnThreadStart();
238
239 std::shared_ptr<Common::Fiber>& ControlContext() {
240 return switch_fiber;
241 }
242
243 const std::shared_ptr<Common::Fiber>& ControlContext() const {
244 return switch_fiber;
245 }
246
215private: 247private:
216 friend class GlobalScheduler; 248 friend class GlobalScheduler;
217 249
218 /// Switches the CPU's active thread context to that of the specified thread 250 /// Switches the CPU's active thread context to that of the specified thread
219 void SwitchContext(); 251 void SwitchContext();
220 252
253 /// When a thread wakes up, it must run this through it's new scheduler
254 void SwitchContextStep2();
255
221 /** 256 /**
222 * Called on every context switch to update the internal timestamp 257 * Called on every context switch to update the internal timestamp
223 * This also updates the running time ticks for the given thread and 258 * This also updates the running time ticks for the given thread and
@@ -231,14 +266,24 @@ private:
231 */ 266 */
232 void UpdateLastContextSwitchTime(Thread* thread, Process* process); 267 void UpdateLastContextSwitchTime(Thread* thread, Process* process);
233 268
269 static void OnSwitch(void* this_scheduler);
270 void SwitchToCurrent();
271
234 std::shared_ptr<Thread> current_thread = nullptr; 272 std::shared_ptr<Thread> current_thread = nullptr;
235 std::shared_ptr<Thread> selected_thread = nullptr; 273 std::shared_ptr<Thread> selected_thread = nullptr;
274 std::shared_ptr<Thread> current_thread_prev = nullptr;
275 std::shared_ptr<Thread> selected_thread_set = nullptr;
276 std::shared_ptr<Thread> idle_thread = nullptr;
277
278 std::shared_ptr<Common::Fiber> switch_fiber = nullptr;
236 279
237 Core::System& system; 280 Core::System& system;
238 u64 last_context_switch_time = 0; 281 u64 last_context_switch_time = 0;
239 u64 idle_selection_count = 0; 282 u64 idle_selection_count = 0;
240 const std::size_t core_id; 283 const std::size_t core_id;
241 284
285 Common::SpinLock guard{};
286
242 bool is_context_switch_pending = false; 287 bool is_context_switch_pending = false;
243}; 288};
244 289
@@ -261,6 +306,8 @@ public:
261 sleep_cancelled = true; 306 sleep_cancelled = true;
262 } 307 }
263 308
309 void Release();
310
264private: 311private:
265 Handle& event_handle; 312 Handle& event_handle;
266 Thread* time_task; 313 Thread* time_task;