From 029ff9f1fd013ec46f3d61510c5f95f05bca698e Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 3 Dec 2014 23:22:06 -0500 Subject: [PATCH 1/3] SVC: Implemented GetThreadId. For now threads are using their Handle value as their Id, it should not really cause any problems because Handle values are unique in Citra, but it should be changed. I left a ToDo there because this is not correct behavior as per hardware. --- src/core/hle/kernel/thread.cpp | 16 ++++++++++++++++ src/core/hle/kernel/thread.h | 3 +++ src/core/hle/svc.cpp | 9 +++++---- 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index f59795901..6da238828 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -49,6 +49,8 @@ public: ThreadContext context; + u32 thread_id; + u32 status; u32 entry_point; u32 stack_top; @@ -325,6 +327,9 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio thread_queue.push_back(handle); thread_ready_queue.prepare(priority); + // TODO(Subv): Assign valid ids to each thread, they are much lower than handle values + // they appear to begin at 276 and continue from there + thread->thread_id = handle; thread->status = THREADSTATUS_DORMANT; thread->entry_point = entry_point; thread->stack_top = stack_top; @@ -465,6 +470,17 @@ void Reschedule() { } } +ResultCode GetThreadId(u32* thread_id, Handle handle) { + Thread* thread = g_object_pool.Get(handle); + if (thread == nullptr) + return ResultCode(ErrorDescription::InvalidHandle, ErrorModule::OS, + ErrorSummary::WrongArgument, ErrorLevel::Permanent); + + *thread_id = thread->thread_id; + + return RESULT_SUCCESS; +} + //////////////////////////////////////////////////////////////////////////////////////////////////// void ThreadingInit() { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index ce63a70d3..e87867ac0 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -58,6 +58,9 @@ void Reschedule(); /// Stops the current thread ResultCode StopThread(Handle thread, const char* reason); +// Retrieves the thread id of the specified thread handle +ResultCode GetThreadId(u32* thread_id, Handle handle); + /// Resumes a thread from waiting by marking it as "ready" void ResumeThreadFromWait(Handle handle); diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 43a3cbe03..a5805ed05 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -281,10 +281,11 @@ static Result ReleaseMutex(Handle handle) { return res.raw; } -/// Get current thread ID -static Result GetThreadId(u32* thread_id, Handle thread) { - ERROR_LOG(SVC, "(UNIMPLEMENTED) called thread=0x%08X", thread); - return 0; +/// Get the ID for the specified thread. +static Result GetThreadId(u32* thread_id, Handle handle) { + DEBUG_LOG(SVC, "called thread=0x%08X", handle); + ResultCode result = Kernel::GetThreadId(thread_id, handle); + return result.raw; } /// Query memory From ef1d5cda06deac153582766fa9fc4074cb91f3d5 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Dec 2014 08:13:53 -0500 Subject: [PATCH 2/3] Threads: Implemented a sequential thread id --- src/core/hle/kernel/thread.cpp | 16 +++++++++++++--- src/core/hle/kernel/thread.h | 7 ++++++- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 6da238828..ccb927381 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -78,6 +78,17 @@ static Common::ThreadQueueList thread_ready_queue; static Handle current_thread_handle; static Thread* current_thread; +static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup +static u32 next_thread_id; ///< The next available thread id + +/** + * Gets the next available thread id and increments it + * @return Next available thread id + */ +static u32 NextThreadId() { + return next_thread_id++; +} + /// Gets the current thread inline Thread* GetCurrentThread() { return current_thread; @@ -327,9 +338,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio thread_queue.push_back(handle); thread_ready_queue.prepare(priority); - // TODO(Subv): Assign valid ids to each thread, they are much lower than handle values - // they appear to begin at 276 and continue from there - thread->thread_id = handle; + thread->thread_id = NextThreadId(); thread->status = THREADSTATUS_DORMANT; thread->entry_point = entry_point; thread->stack_top = stack_top; @@ -484,6 +493,7 @@ ResultCode GetThreadId(u32* thread_id, Handle handle) { //////////////////////////////////////////////////////////////////////////////////////////////////// void ThreadingInit() { + next_thread_id = INITIAL_THREAD_ID; } void ThreadingShutdown() { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index e87867ac0..53a19d779 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -58,7 +58,12 @@ void Reschedule(); /// Stops the current thread ResultCode StopThread(Handle thread, const char* reason); -// Retrieves the thread id of the specified thread handle +/** + * Retrieves the ID of the specified thread handle + * @param thread_id Will contain the output thread id + * @param handle Handle to the thread we want + * @return Whether the function was successful or not + */ ResultCode GetThreadId(u32* thread_id, Handle handle); /// Resumes a thread from waiting by marking it as "ready" From 6fac2bf0ab5fa51c6b2228d6fa64752793f38965 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 4 Dec 2014 14:59:56 -0500 Subject: [PATCH 3/3] Threads: Remove a redundant function. Use the next_thread_id variable directly. --- src/core/hle/kernel/thread.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index ccb927381..8d65dc84d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -81,14 +81,6 @@ static Thread* current_thread; static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup static u32 next_thread_id; ///< The next available thread id -/** - * Gets the next available thread id and increments it - * @return Next available thread id - */ -static u32 NextThreadId() { - return next_thread_id++; -} - /// Gets the current thread inline Thread* GetCurrentThread() { return current_thread; @@ -338,7 +330,7 @@ Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 prio thread_queue.push_back(handle); thread_ready_queue.prepare(priority); - thread->thread_id = NextThreadId(); + thread->thread_id = next_thread_id++; thread->status = THREADSTATUS_DORMANT; thread->entry_point = entry_point; thread->stack_top = stack_top;