diff options
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 78 |
1 files changed, 39 insertions, 39 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 934ca87c4..5f1d5c400 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -64,28 +64,33 @@ Thread* g_current_thread; | |||
| 64 | 64 | ||
| 65 | 65 | ||
| 66 | /// Gets the current thread | 66 | /// Gets the current thread |
| 67 | inline Thread* __GetCurrentThread() { | 67 | inline Thread* GetCurrentThread() { |
| 68 | return g_current_thread; | 68 | return g_current_thread; |
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | /// Gets the current thread handle | ||
| 72 | Handle GetCurrentThreadHandle() { | ||
| 73 | return GetCurrentThread()->GetHandle(); | ||
| 74 | } | ||
| 75 | |||
| 71 | /// Sets the current thread | 76 | /// Sets the current thread |
| 72 | inline void __SetCurrentThread(Thread* t) { | 77 | inline void SetCurrentThread(Thread* t) { |
| 73 | g_current_thread = t; | 78 | g_current_thread = t; |
| 74 | g_current_thread_handle = t->GetHandle(); | 79 | g_current_thread_handle = t->GetHandle(); |
| 75 | } | 80 | } |
| 76 | 81 | ||
| 77 | /// Saves the current CPU context | 82 | /// Saves the current CPU context |
| 78 | void __SaveContext(ThreadContext& ctx) { | 83 | void SaveContext(ThreadContext& ctx) { |
| 79 | Core::g_app_core->SaveContext(ctx); | 84 | Core::g_app_core->SaveContext(ctx); |
| 80 | } | 85 | } |
| 81 | 86 | ||
| 82 | /// Loads a CPU context | 87 | /// Loads a CPU context |
| 83 | void __LoadContext(ThreadContext& ctx) { | 88 | void LoadContext(ThreadContext& ctx) { |
| 84 | Core::g_app_core->LoadContext(ctx); | 89 | Core::g_app_core->LoadContext(ctx); |
| 85 | } | 90 | } |
| 86 | 91 | ||
| 87 | /// Resets a thread | 92 | /// Resets a thread |
| 88 | void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { | 93 | void ResetThread(Thread* t, u32 arg, s32 lowest_priority) { |
| 89 | memset(&t->context, 0, sizeof(ThreadContext)); | 94 | memset(&t->context, 0, sizeof(ThreadContext)); |
| 90 | 95 | ||
| 91 | t->context.cpu_registers[0] = arg; | 96 | t->context.cpu_registers[0] = arg; |
| @@ -101,7 +106,7 @@ void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { | |||
| 101 | } | 106 | } |
| 102 | 107 | ||
| 103 | /// Change a thread to "ready" state | 108 | /// Change a thread to "ready" state |
| 104 | void __ChangeReadyState(Thread* t, bool ready) { | 109 | void ChangeReadyState(Thread* t, bool ready) { |
| 105 | Handle handle = t->GetHandle(); | 110 | Handle handle = t->GetHandle(); |
| 106 | if (t->IsReady()) { | 111 | if (t->IsReady()) { |
| 107 | if (!ready) { | 112 | if (!ready) { |
| @@ -118,11 +123,11 @@ void __ChangeReadyState(Thread* t, bool ready) { | |||
| 118 | } | 123 | } |
| 119 | 124 | ||
| 120 | /// Changes a threads state | 125 | /// Changes a threads state |
| 121 | void __ChangeThreadState(Thread* t, ThreadStatus new_status) { | 126 | void ChangeThreadState(Thread* t, ThreadStatus new_status) { |
| 122 | if (!t || t->status == new_status) { | 127 | if (!t || t->status == new_status) { |
| 123 | return; | 128 | return; |
| 124 | } | 129 | } |
| 125 | __ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); | 130 | ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); |
| 126 | t->status = new_status; | 131 | t->status = new_status; |
| 127 | 132 | ||
| 128 | if (new_status == THREADSTATUS_WAIT) { | 133 | if (new_status == THREADSTATUS_WAIT) { |
| @@ -133,42 +138,42 @@ void __ChangeThreadState(Thread* t, ThreadStatus new_status) { | |||
| 133 | } | 138 | } |
| 134 | 139 | ||
| 135 | /// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields) | 140 | /// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields) |
| 136 | void __CallThread(Thread* t) { | 141 | void CallThread(Thread* t) { |
| 137 | // Stop waiting | 142 | // Stop waiting |
| 138 | if (t->wait_type != WAITTYPE_NONE) { | 143 | if (t->wait_type != WAITTYPE_NONE) { |
| 139 | t->wait_type = WAITTYPE_NONE; | 144 | t->wait_type = WAITTYPE_NONE; |
| 140 | } | 145 | } |
| 141 | __ChangeThreadState(t, THREADSTATUS_READY); | 146 | ChangeThreadState(t, THREADSTATUS_READY); |
| 142 | } | 147 | } |
| 143 | 148 | ||
| 144 | /// Switches CPU context to that of the specified thread | 149 | /// Switches CPU context to that of the specified thread |
| 145 | void __SwitchContext(Thread* t, const char* reason) { | 150 | void SwitchContext(Thread* t, const char* reason) { |
| 146 | Thread* cur = __GetCurrentThread(); | 151 | Thread* cur = GetCurrentThread(); |
| 147 | 152 | ||
| 148 | // Save context for current thread | 153 | // Save context for current thread |
| 149 | if (cur) { | 154 | if (cur) { |
| 150 | __SaveContext(cur->context); | 155 | SaveContext(cur->context); |
| 151 | 156 | ||
| 152 | if (cur->IsRunning()) { | 157 | if (cur->IsRunning()) { |
| 153 | __ChangeReadyState(cur, true); | 158 | ChangeReadyState(cur, true); |
| 154 | } | 159 | } |
| 155 | } | 160 | } |
| 156 | // Load context of new thread | 161 | // Load context of new thread |
| 157 | if (t) { | 162 | if (t) { |
| 158 | __SetCurrentThread(t); | 163 | SetCurrentThread(t); |
| 159 | __ChangeReadyState(t, false); | 164 | ChangeReadyState(t, false); |
| 160 | t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; | 165 | t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; |
| 161 | t->wait_type = WAITTYPE_NONE; | 166 | t->wait_type = WAITTYPE_NONE; |
| 162 | __LoadContext(t->context); | 167 | LoadContext(t->context); |
| 163 | } else { | 168 | } else { |
| 164 | __SetCurrentThread(NULL); | 169 | SetCurrentThread(NULL); |
| 165 | } | 170 | } |
| 166 | } | 171 | } |
| 167 | 172 | ||
| 168 | /// Gets the next thread that is ready to be run by priority | 173 | /// Gets the next thread that is ready to be run by priority |
| 169 | Thread* __NextThread() { | 174 | Thread* NextThread() { |
| 170 | Handle next; | 175 | Handle next; |
| 171 | Thread* cur = __GetCurrentThread(); | 176 | Thread* cur = GetCurrentThread(); |
| 172 | 177 | ||
| 173 | if (cur && cur->IsRunning()) { | 178 | if (cur && cur->IsRunning()) { |
| 174 | next = g_thread_ready_queue.pop_first_better(cur->current_priority); | 179 | next = g_thread_ready_queue.pop_first_better(cur->current_priority); |
| @@ -183,9 +188,9 @@ Thread* __NextThread() { | |||
| 183 | 188 | ||
| 184 | /// Puts a thread in the wait state for the given type/reason | 189 | /// Puts a thread in the wait state for the given type/reason |
| 185 | void WaitCurThread(WaitType wait_type, const char* reason) { | 190 | void WaitCurThread(WaitType wait_type, const char* reason) { |
| 186 | Thread* t = __GetCurrentThread(); | 191 | Thread* t = GetCurrentThread(); |
| 187 | t->wait_type = wait_type; | 192 | t->wait_type = wait_type; |
| 188 | __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); | 193 | ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); |
| 189 | } | 194 | } |
| 190 | 195 | ||
| 191 | /// Resumes a thread from waiting by marking it as "ready" | 196 | /// Resumes a thread from waiting by marking it as "ready" |
| @@ -195,7 +200,7 @@ void ResumeThreadFromWait(Handle handle) { | |||
| 195 | if (t) { | 200 | if (t) { |
| 196 | t->status &= ~THREADSTATUS_WAIT; | 201 | t->status &= ~THREADSTATUS_WAIT; |
| 197 | if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { | 202 | if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { |
| 198 | __ChangeReadyState(t, true); | 203 | ChangeReadyState(t, true); |
| 199 | } | 204 | } |
| 200 | } | 205 | } |
| 201 | } | 206 | } |
| @@ -256,7 +261,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 | |||
| 256 | Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, | 261 | Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, |
| 257 | stack_size); | 262 | stack_size); |
| 258 | 263 | ||
| 259 | __ResetThread(t, arg, 0); | 264 | ResetThread(t, arg, 0); |
| 260 | 265 | ||
| 261 | HLE::EatCycles(32000); | 266 | HLE::EatCycles(32000); |
| 262 | 267 | ||
| @@ -264,16 +269,11 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 | |||
| 264 | // Technically, this should not eat all at once, and reschedule in the middle, but that's hard. | 269 | // Technically, this should not eat all at once, and reschedule in the middle, but that's hard. |
| 265 | HLE::ReSchedule("thread created"); | 270 | HLE::ReSchedule("thread created"); |
| 266 | 271 | ||
| 267 | __CallThread(t); | 272 | CallThread(t); |
| 268 | 273 | ||
| 269 | return handle; | 274 | return handle; |
| 270 | } | 275 | } |
| 271 | 276 | ||
| 272 | /// Gets the current thread | ||
| 273 | Handle GetCurrentThread() { | ||
| 274 | return __GetCurrentThread()->GetHandle(); | ||
| 275 | } | ||
| 276 | |||
| 277 | /// Sets up the primary application thread | 277 | /// Sets up the primary application thread |
| 278 | Handle SetupMainThread(s32 priority, int stack_size) { | 278 | Handle SetupMainThread(s32 priority, int stack_size) { |
| 279 | Handle handle; | 279 | Handle handle; |
| @@ -282,33 +282,33 @@ Handle SetupMainThread(s32 priority, int stack_size) { | |||
| 282 | Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, | 282 | Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, |
| 283 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); | 283 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); |
| 284 | 284 | ||
| 285 | __ResetThread(t, 0, 0); | 285 | ResetThread(t, 0, 0); |
| 286 | 286 | ||
| 287 | // If running another thread already, set it to "ready" state | 287 | // If running another thread already, set it to "ready" state |
| 288 | Thread* cur = __GetCurrentThread(); | 288 | Thread* cur = GetCurrentThread(); |
| 289 | if (cur && cur->IsRunning()) { | 289 | if (cur && cur->IsRunning()) { |
| 290 | __ChangeReadyState(cur, true); | 290 | ChangeReadyState(cur, true); |
| 291 | } | 291 | } |
| 292 | 292 | ||
| 293 | // Run new "main" thread | 293 | // Run new "main" thread |
| 294 | __SetCurrentThread(t); | 294 | SetCurrentThread(t); |
| 295 | t->status = THREADSTATUS_RUNNING; | 295 | t->status = THREADSTATUS_RUNNING; |
| 296 | __LoadContext(t->context); | 296 | LoadContext(t->context); |
| 297 | 297 | ||
| 298 | return handle; | 298 | return handle; |
| 299 | } | 299 | } |
| 300 | 300 | ||
| 301 | /// Reschedules to the next available thread (call after current thread is suspended) | 301 | /// Reschedules to the next available thread (call after current thread is suspended) |
| 302 | void Reschedule(const char* reason) { | 302 | void Reschedule(const char* reason) { |
| 303 | Thread* prev = __GetCurrentThread(); | 303 | Thread* prev = GetCurrentThread(); |
| 304 | Thread* next = __NextThread(); | 304 | Thread* next = NextThread(); |
| 305 | if (next > 0) { | 305 | if (next > 0) { |
| 306 | __SwitchContext(next, reason); | 306 | SwitchContext(next, reason); |
| 307 | 307 | ||
| 308 | // Hack - automatically change previous thread (which would have been in "wait" state) to | 308 | // Hack - automatically change previous thread (which would have been in "wait" state) to |
| 309 | // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to | 309 | // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to |
| 310 | // actually wait for whatever event it is supposed to be waiting on. | 310 | // actually wait for whatever event it is supposed to be waiting on. |
| 311 | __ChangeReadyState(prev, true); | 311 | ChangeReadyState(prev, true); |
| 312 | } | 312 | } |
| 313 | } | 313 | } |
| 314 | 314 | ||