summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/thread.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/thread.cpp')
-rw-r--r--src/core/hle/kernel/thread.cpp49
1 files changed, 15 insertions, 34 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index ef705e327..934ca87c4 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -21,27 +21,6 @@
21 21
22namespace Kernel { 22namespace Kernel {
23 23
24enum ThreadStatus {
25 THREADSTATUS_RUNNING = 1,
26 THREADSTATUS_READY = 2,
27 THREADSTATUS_WAIT = 4,
28 THREADSTATUS_SUSPEND = 8,
29 THREADSTATUS_DORMANT = 16,
30 THREADSTATUS_DEAD = 32,
31 THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
32};
33
34enum WaitType {
35 WAITTYPE_NONE,
36 WAITTYPE_SLEEP,
37 WAITTYPE_SEMA,
38 WAITTYPE_EVENTFLAG,
39 WAITTYPE_THREADEND,
40 WAITTYPE_VBLANK,
41 WAITTYPE_MUTEX,
42 WAITTYPE_SYNCH,
43};
44
45class Thread : public Kernel::Object { 24class Thread : public Kernel::Object {
46public: 25public:
47 26
@@ -101,16 +80,18 @@ void __SaveContext(ThreadContext& ctx) {
101} 80}
102 81
103/// Loads a CPU context 82/// Loads a CPU context
104void __LoadContext(const ThreadContext& ctx) { 83void __LoadContext(ThreadContext& ctx) {
105 Core::g_app_core->LoadContext(ctx); 84 Core::g_app_core->LoadContext(ctx);
106} 85}
107 86
108/// Resets a thread 87/// Resets a thread
109void __ResetThread(Thread* t, s32 lowest_priority) { 88void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) {
110 memset(&t->context, 0, sizeof(ThreadContext)); 89 memset(&t->context, 0, sizeof(ThreadContext));
111 90
91 t->context.cpu_registers[0] = arg;
112 t->context.pc = t->entry_point; 92 t->context.pc = t->entry_point;
113 t->context.sp = t->stack_top; 93 t->context.sp = t->stack_top;
94 t->context.cpsr = 0x1F; // Usermode
114 95
115 if (t->current_priority < lowest_priority) { 96 if (t->current_priority < lowest_priority) {
116 t->current_priority = t->initial_priority; 97 t->current_priority = t->initial_priority;
@@ -201,7 +182,7 @@ Thread* __NextThread() {
201} 182}
202 183
203/// Puts a thread in the wait state for the given type/reason 184/// Puts a thread in the wait state for the given type/reason
204void __WaitCurThread(WaitType wait_type, const char* reason) { 185void WaitCurThread(WaitType wait_type, const char* reason) {
205 Thread* t = __GetCurrentThread(); 186 Thread* t = __GetCurrentThread();
206 t->wait_type = wait_type; 187 t->wait_type = wait_type;
207 __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); 188 __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND)));
@@ -248,7 +229,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio
248} 229}
249 230
250/// Creates a new thread - wrapper for external user 231/// Creates a new thread - wrapper for external user
251Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, 232Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s32 processor_id,
252 u32 stack_top, int stack_size) { 233 u32 stack_top, int stack_size) {
253 if (name == NULL) { 234 if (name == NULL) {
254 ERROR_LOG(KERNEL, "CreateThread(): NULL name"); 235 ERROR_LOG(KERNEL, "CreateThread(): NULL name");
@@ -275,6 +256,8 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 process
275 Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, 256 Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top,
276 stack_size); 257 stack_size);
277 258
259 __ResetThread(t, arg, 0);
260
278 HLE::EatCycles(32000); 261 HLE::EatCycles(32000);
279 262
280 // This won't schedule to the new thread, but it may to one woken from eating cycles. 263 // This won't schedule to the new thread, but it may to one woken from eating cycles.
@@ -299,7 +282,7 @@ Handle SetupMainThread(s32 priority, int stack_size) {
299 Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 282 Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority,
300 THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); 283 THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
301 284
302 __ResetThread(t, 0); 285 __ResetThread(t, 0, 0);
303 286
304 // If running another thread already, set it to "ready" state 287 // If running another thread already, set it to "ready" state
305 Thread* cur = __GetCurrentThread(); 288 Thread* cur = __GetCurrentThread();
@@ -317,18 +300,16 @@ Handle SetupMainThread(s32 priority, int stack_size) {
317 300
318/// 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)
319void Reschedule(const char* reason) { 302void Reschedule(const char* reason) {
303 Thread* prev = __GetCurrentThread();
320 Thread* next = __NextThread(); 304 Thread* next = __NextThread();
321 if (next > 0) { 305 if (next > 0) {
322 __SwitchContext(next, reason); 306 __SwitchContext(next, reason);
323 }
324}
325 307
326//////////////////////////////////////////////////////////////////////////////////////////////////// 308 // Hack - automatically change previous thread (which would have been in "wait" state) to
327 309 // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to
328/// Put current thread in a wait state - on WaitSynchronization 310 // actually wait for whatever event it is supposed to be waiting on.
329void WaitThread_Synchronization() { 311 __ChangeReadyState(prev, true);
330 // TODO(bunnei): Just a placeholder function for now... FixMe 312 }
331 __WaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called");
332} 313}
333 314
334//////////////////////////////////////////////////////////////////////////////////////////////////// 315////////////////////////////////////////////////////////////////////////////////////////////////////