From 14bd37c5dc67c7777d4bea8d996bf2dfd8c7bdcc Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 22 May 2014 18:50:36 -0400 Subject: thread: moved ThreadStatus/WaitType to header, added support for arg on CreateThread, added correct CPSR reset --- src/core/hle/kernel/thread.cpp | 49 +++++++++++++----------------------------- src/core/hle/kernel/thread.h | 26 +++++++++++++++++++++- 2 files changed, 40 insertions(+), 35 deletions(-) (limited to 'src/core') 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 @@ namespace Kernel { -enum ThreadStatus { - THREADSTATUS_RUNNING = 1, - THREADSTATUS_READY = 2, - THREADSTATUS_WAIT = 4, - THREADSTATUS_SUSPEND = 8, - THREADSTATUS_DORMANT = 16, - THREADSTATUS_DEAD = 32, - THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND -}; - -enum WaitType { - WAITTYPE_NONE, - WAITTYPE_SLEEP, - WAITTYPE_SEMA, - WAITTYPE_EVENTFLAG, - WAITTYPE_THREADEND, - WAITTYPE_VBLANK, - WAITTYPE_MUTEX, - WAITTYPE_SYNCH, -}; - class Thread : public Kernel::Object { public: @@ -101,16 +80,18 @@ void __SaveContext(ThreadContext& ctx) { } /// Loads a CPU context -void __LoadContext(const ThreadContext& ctx) { +void __LoadContext(ThreadContext& ctx) { Core::g_app_core->LoadContext(ctx); } /// Resets a thread -void __ResetThread(Thread* t, s32 lowest_priority) { +void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { memset(&t->context, 0, sizeof(ThreadContext)); + t->context.cpu_registers[0] = arg; t->context.pc = t->entry_point; t->context.sp = t->stack_top; + t->context.cpsr = 0x1F; // Usermode if (t->current_priority < lowest_priority) { t->current_priority = t->initial_priority; @@ -201,7 +182,7 @@ Thread* __NextThread() { } /// Puts a thread in the wait state for the given type/reason -void __WaitCurThread(WaitType wait_type, const char* reason) { +void WaitCurThread(WaitType wait_type, const char* reason) { Thread* t = __GetCurrentThread(); t->wait_type = wait_type; __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 } /// Creates a new thread - wrapper for external user -Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, +Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s32 processor_id, u32 stack_top, int stack_size) { if (name == NULL) { ERROR_LOG(KERNEL, "CreateThread(): NULL name"); @@ -275,6 +256,8 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 process Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, stack_size); + __ResetThread(t, arg, 0); + HLE::EatCycles(32000); // 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) { Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); - __ResetThread(t, 0); + __ResetThread(t, 0, 0); // If running another thread already, set it to "ready" state Thread* cur = __GetCurrentThread(); @@ -317,18 +300,16 @@ Handle SetupMainThread(s32 priority, int stack_size) { /// Reschedules to the next available thread (call after current thread is suspended) void Reschedule(const char* reason) { + Thread* prev = __GetCurrentThread(); Thread* next = __NextThread(); if (next > 0) { __SwitchContext(next, reason); - } -} -//////////////////////////////////////////////////////////////////////////////////////////////////// - -/// Put current thread in a wait state - on WaitSynchronization -void WaitThread_Synchronization() { - // TODO(bunnei): Just a placeholder function for now... FixMe - __WaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called"); + // Hack - automatically change previous thread (which would have been in "wait" state) to + // "ready" state, so that we can immediately resume to it when new thread yields. FixMe to + // actually wait for whatever event it is supposed to be waiting on. + __ChangeReadyState(prev, true); + } } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 0d1fe19bf..82bf16082 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -20,10 +20,31 @@ enum ThreadProcessorId { THREADPROCESSORID_ALL = 0xFFFFFFFC, ///< Enables both cores }; +enum ThreadStatus { + THREADSTATUS_RUNNING = 1, + THREADSTATUS_READY = 2, + THREADSTATUS_WAIT = 4, + THREADSTATUS_SUSPEND = 8, + THREADSTATUS_DORMANT = 16, + THREADSTATUS_DEAD = 32, + THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND +}; + +enum WaitType { + WAITTYPE_NONE, + WAITTYPE_SLEEP, + WAITTYPE_SEMA, + WAITTYPE_EVENTFLAG, + WAITTYPE_THREADEND, + WAITTYPE_VBLANK, + WAITTYPE_MUTEX, + WAITTYPE_SYNCH, +}; + namespace Kernel { /// Creates a new thread - wrapper for external user -Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, +Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s32 processor_id, u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Sets up the primary application thread @@ -32,6 +53,9 @@ Handle SetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Reschedules to the next available thread (call after current thread is suspended) void Reschedule(const char* reason); +/// Puts a thread in the wait state for the given type/reason +void WaitCurThread(WaitType wait_type, const char* reason); + /// Resumes a thread from waiting by marking it as "ready" void ResumeThreadFromWait(Handle handle); -- cgit v1.2.3