From 6b264518a50ce21cb1be55ff3eac4e1c85582cfe Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 May 2014 22:11:18 -0400 Subject: added initial kernel/thread modules --- src/core/hle/kernel/kernel.cpp | 142 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 src/core/hle/kernel/kernel.cpp (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp new file mode 100644 index 0000000000..fc494fe30f --- /dev/null +++ b/src/core/hle/kernel/kernel.cpp @@ -0,0 +1,142 @@ +// Copyright 2014 Citra Emulator Project / PPSSPP Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/common.h" + +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/thread.h" + +KernelObjectPool g_kernel_objects; + +void __KernelInit() { + __KernelThreadingInit(); +} + +void __KernelShutdown() { + __KernelThreadingShutdown(); +} + +KernelObjectPool::KernelObjectPool() { + memset(occupied, 0, sizeof(bool) * MAX_COUNT); + next_id = INITIAL_NEXT_ID; +} + +UID KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) { + if (range_top > MAX_COUNT) { + range_top = MAX_COUNT; + } + if (next_id >= range_bottom && next_id < range_top) { + range_bottom = next_id++; + } + for (int i = range_bottom; i < range_top; i++) { + if (!occupied[i]) { + occupied[i] = true; + pool[i] = obj; + pool[i]->uid = i + HANDLE_OFFSET; + return i + HANDLE_OFFSET; + } + } + ERROR_LOG(HLE, "Unable to allocate kernel object, too many objects slots in use."); + return 0; +} + +bool KernelObjectPool::IsValid(UID handle) +{ + int index = handle - HANDLE_OFFSET; + if (index < 0) + return false; + if (index >= MAX_COUNT) + return false; + + return occupied[index]; +} + +void KernelObjectPool::Clear() +{ + for (int i = 0; i < MAX_COUNT; i++) + { + //brutally clear everything, no validation + if (occupied[i]) + delete pool[i]; + occupied[i] = false; + } + memset(pool, 0, sizeof(KernelObject*)*MAX_COUNT); + next_id = INITIAL_NEXT_ID; +} + +KernelObject *&KernelObjectPool::operator [](UID handle) +{ + _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ"); + return pool[handle - HANDLE_OFFSET]; +} + +void KernelObjectPool::List() { + for (int i = 0; i < MAX_COUNT; i++) { + if (occupied[i]) { + if (pool[i]) { + INFO_LOG(KERNEL, "KO %i: %s \"%s\"", i + HANDLE_OFFSET, pool[i]->GetTypeName(), + pool[i]->GetName()); + } + } + } +} + +int KernelObjectPool::GetCount() +{ + int count = 0; + for (int i = 0; i < MAX_COUNT; i++) + { + if (occupied[i]) + count++; + } + return count; +} + +KernelObject *KernelObjectPool::CreateByIDType(int type) { + // Used for save states. This is ugly, but what other way is there? + switch (type) { + //case SCE_KERNEL_TMID_Alarm: + // return __KernelAlarmObject(); + //case SCE_KERNEL_TMID_EventFlag: + // return __KernelEventFlagObject(); + //case SCE_KERNEL_TMID_Mbox: + // return __KernelMbxObject(); + //case SCE_KERNEL_TMID_Fpl: + // return __KernelMemoryFPLObject(); + //case SCE_KERNEL_TMID_Vpl: + // return __KernelMemoryVPLObject(); + //case PPSSPP_KERNEL_TMID_PMB: + // return __KernelMemoryPMBObject(); + //case PPSSPP_KERNEL_TMID_Module: + // return __KernelModuleObject(); + //case SCE_KERNEL_TMID_Mpipe: + // return __KernelMsgPipeObject(); + //case SCE_KERNEL_TMID_Mutex: + // return __KernelMutexObject(); + //case SCE_KERNEL_TMID_LwMutex: + // return __KernelLwMutexObject(); + //case SCE_KERNEL_TMID_Semaphore: + // return __KernelSemaphoreObject(); + //case SCE_KERNEL_TMID_Callback: + // return __KernelCallbackObject(); + //case SCE_KERNEL_TMID_Thread: + // return __KernelThreadObject(); + //case SCE_KERNEL_TMID_VTimer: + // return __KernelVTimerObject(); + //case SCE_KERNEL_TMID_Tlspl: + // return __KernelTlsplObject(); + //case PPSSPP_KERNEL_TMID_File: + // return __KernelFileNodeObject(); + //case PPSSPP_KERNEL_TMID_DirList: + // return __KernelDirListingObject(); + + default: + ERROR_LOG(COMMON, "Unable to load state: could not find object type %d.", type); + return NULL; + } +} -- cgit v1.2.3 From 1583d2b6f32ec6f558646284a8130c0759e93e12 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 13 May 2014 21:57:12 -0400 Subject: - added __KernelLoadExec function - fixed some logging --- src/core/hle/kernel/kernel.cpp | 11 +++++++++++ src/core/hle/kernel/kernel.h | 37 ++++++++++++++++++++++++------------- 2 files changed, 35 insertions(+), 13 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index fc494fe30f..fb6ae8495a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -8,6 +8,7 @@ #include "common/common.h" +#include "core/core.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" @@ -140,3 +141,13 @@ KernelObject *KernelObjectPool::CreateByIDType(int type) { return NULL; } } + +bool __KernelLoadExec(u32 entry_point) { + __KernelInit(); + + Core::g_app_core->SetPC(entry_point); + + UID thread_id = __KernelSetupRootThread(0xDEADBEEF, 0, 0x31); + + return true; +} diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 2381ca7f74..0eb58210cc 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -8,6 +8,15 @@ typedef u32 UID; +enum KernelIDType { + KERNEL_ID_TYPE_THREAD = 1, + KERNEL_ID_TYPE_SEMAPHORE = 2, + KERNEL_ID_TYPE_MUTEX = 3, + KERNEL_ID_TYPE_EVENT = 4, +}; + +#define KERNELOBJECT_MAX_NAME_LENGTH 31 + class KernelObjectPool; class KernelObject { @@ -18,7 +27,7 @@ public: UID GetUID() const { return uid; } virtual const char *GetTypeName() { return "[BAD KERNEL OBJECT TYPE]"; } virtual const char *GetName() { return "[UNKNOWN KERNEL OBJECT]"; } - virtual int GetIDType() const = 0; + virtual KernelIDType GetIDType() const = 0; //virtual void GetQuickInfo(char *ptr, int size); }; @@ -36,8 +45,8 @@ public: u32 Destroy(UID handle) { u32 error; if (Get(handle, error)) { - occupied[handle - handleOffset] = false; - delete pool[handle - handleOffset]; + occupied[handle - HANDLE_OFFSET] = false; + delete pool[handle - HANDLE_OFFSET]; } return error; }; @@ -46,24 +55,24 @@ public: template T* Get(UID handle, u32& outError) { - if (handle < handleOffset || handle >= handleOffset + maxCount || !occupied[handle - handleOffset]) { + if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP if (handle != 0 && (u32)handle != 0x80020001) { - WARN_LOG(SCEKERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); + WARN_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); } - outError = T::GetMissingErrorCode(); + outError = 0;//T::GetMissingErrorCode(); return 0; } else { // Previously we had a dynamic_cast here, but since RTTI was disabled traditionally, // it just acted as a static case and everything worked. This means that we will never // see the Wrong type object error below, but we'll just have to live with that danger. - T* t = static_cast(pool[handle - handleOffset]); + T* t = static_cast(pool[handle - HANDLE_OFFSET]); if (t == 0 || t->GetIDType() != T::GetStaticIDType()) { - WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); - outError = T::GetMissingErrorCode(); + WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); + outError = 0;//T::GetMissingErrorCode(); return 0; } - outError = SCE_KERNEL_ERROR_OK; + outError = 0;//SCE_KERNEL_ERROR_OK; return t; } } @@ -71,15 +80,15 @@ public: // ONLY use this when you know the handle is valid. template T *GetFast(UID handle) { - const UID realHandle = handle - handleOffset; - _dbg_assert_(SCEKERNEL, realHandle >= 0 && realHandle < maxCount && occupied[realHandle]); + const UID realHandle = handle - HANDLE_OFFSET; + _dbg_assert_(KERNEL, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]); return static_cast(pool[realHandle]); } template void Iterate(bool func(T *, ArgT), ArgT arg) { int type = T::GetStaticIDType(); - for (int i = 0; i < maxCount; i++) + for (int i = 0; i < MAX_COUNT; i++) { if (!occupied[i]) continue; @@ -119,3 +128,5 @@ private: }; extern KernelObjectPool g_kernel_objects; + +bool __KernelLoadExec(u32 entry_point); -- cgit v1.2.3 From 9f5588725c9c16543f55ad05965086b8962a460f Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 14 May 2014 20:49:27 -0400 Subject: changed primary thread priority to 0x30 - this is typical, not 0x31 --- src/core/hle/kernel/kernel.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index fb6ae8495a..1c26fb388e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -147,7 +147,8 @@ bool __KernelLoadExec(u32 entry_point) { Core::g_app_core->SetPC(entry_point); - UID thread_id = __KernelSetupRootThread(0xDEADBEEF, 0, 0x31); + // 0x30 is the typical main thread priority I've seen used so far + UID thread_id = __KernelSetupRootThread(0xDEADBEEF, 0, 0x30); return true; } -- cgit v1.2.3 From a7cc430aa4da2962dcf08db2f6009fc272bdda70 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 15 May 2014 18:26:28 -0400 Subject: changed "UID" to "Handle" to be a little more consistent with CTR naming --- src/core/hle/kernel/kernel.cpp | 10 +++++----- src/core/hle/kernel/kernel.h | 29 ++++++++++++++++------------- 2 files changed, 21 insertions(+), 18 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1c26fb388e..f7145ddd8f 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -27,7 +27,7 @@ KernelObjectPool::KernelObjectPool() { next_id = INITIAL_NEXT_ID; } -UID KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) { +Handle KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) { if (range_top > MAX_COUNT) { range_top = MAX_COUNT; } @@ -38,7 +38,7 @@ UID KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) if (!occupied[i]) { occupied[i] = true; pool[i] = obj; - pool[i]->uid = i + HANDLE_OFFSET; + pool[i]->handle = i + HANDLE_OFFSET; return i + HANDLE_OFFSET; } } @@ -46,7 +46,7 @@ UID KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) return 0; } -bool KernelObjectPool::IsValid(UID handle) +bool KernelObjectPool::IsValid(Handle handle) { int index = handle - HANDLE_OFFSET; if (index < 0) @@ -70,7 +70,7 @@ void KernelObjectPool::Clear() next_id = INITIAL_NEXT_ID; } -KernelObject *&KernelObjectPool::operator [](UID handle) +KernelObject *&KernelObjectPool::operator [](Handle handle) { _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ"); return pool[handle - HANDLE_OFFSET]; @@ -148,7 +148,7 @@ bool __KernelLoadExec(u32 entry_point) { Core::g_app_core->SetPC(entry_point); // 0x30 is the typical main thread priority I've seen used so far - UID thread_id = __KernelSetupRootThread(0xDEADBEEF, 0, 0x30); + Handle thread_id = __KernelSetupMainThread(0x30); return true; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0eb58210cc..24d422682e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -6,7 +6,7 @@ #include "common/common_types.h" -typedef u32 UID; +typedef s32 Handle; enum KernelIDType { KERNEL_ID_TYPE_THREAD = 1, @@ -15,20 +15,23 @@ enum KernelIDType { KERNEL_ID_TYPE_EVENT = 4, }; +enum { + KERNELOBJECT_MAX_NAME_LENGTH = 255, +}; + #define KERNELOBJECT_MAX_NAME_LENGTH 31 class KernelObjectPool; class KernelObject { friend class KernelObjectPool; - u32 uid; + u32 handle; public: virtual ~KernelObject() {} - UID GetUID() const { return uid; } + Handle GetHandle() const { return handle; } virtual const char *GetTypeName() { return "[BAD KERNEL OBJECT TYPE]"; } virtual const char *GetName() { return "[UNKNOWN KERNEL OBJECT]"; } virtual KernelIDType GetIDType() const = 0; - //virtual void GetQuickInfo(char *ptr, int size); }; class KernelObjectPool { @@ -36,13 +39,13 @@ public: KernelObjectPool(); ~KernelObjectPool() {} - // Allocates a UID within the range and inserts the object into the map. - UID Create(KernelObject *obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); + // Allocates a handle within the range and inserts the object into the map. + Handle Create(KernelObject *obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); static KernelObject *CreateByIDType(int type); template - u32 Destroy(UID handle) { + u32 Destroy(Handle handle) { u32 error; if (Get(handle, error)) { occupied[handle - HANDLE_OFFSET] = false; @@ -51,10 +54,10 @@ public: return error; }; - bool IsValid(UID handle); + bool IsValid(Handle handle); template - T* Get(UID handle, u32& outError) { + T* Get(Handle handle, u32& outError) { if (handle < HANDLE_OFFSET || handle >= HANDLE_OFFSET + MAX_COUNT || !occupied[handle - HANDLE_OFFSET]) { // Tekken 6 spams 0x80020001 gets wrong with no ill effects, also on the real PSP if (handle != 0 && (u32)handle != 0x80020001) { @@ -79,8 +82,8 @@ public: // ONLY use this when you know the handle is valid. template - T *GetFast(UID handle) { - const UID realHandle = handle - HANDLE_OFFSET; + T *GetFast(Handle handle) { + const Handle realHandle = handle - HANDLE_OFFSET; _dbg_assert_(KERNEL, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]); return static_cast(pool[realHandle]); } @@ -100,7 +103,7 @@ public: } } - bool GetIDType(UID handle, int *type) const { + bool GetIDType(Handle handle, int *type) const { if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) || !occupied[handle - HANDLE_OFFSET]) { ERROR_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); @@ -111,7 +114,7 @@ public: return true; } - KernelObject *&operator [](UID handle); + KernelObject *&operator [](Handle handle); void List(); void Clear(); int GetCount(); -- cgit v1.2.3 From 44336329eddd7dbe1f76144e9a1e95e5f76ed372 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 May 2014 18:13:25 -0400 Subject: - created a Kernel namespace - cleaned up Kernel code a bit (moved stuff into namespace, fixed whitespace issues) - added handle types for all different CTROS handles --- src/core/hle/kernel/kernel.cpp | 49 +++++++++++++------------- src/core/hle/kernel/kernel.h | 75 +++++++++++++++++++++++----------------- src/core/hle/kernel/thread.cpp | 18 +++++----- src/core/hle/kernel/thread.h | 4 +-- src/core/hle/service/service.cpp | 4 +-- src/core/hle/service/service.h | 12 +++---- 6 files changed, 87 insertions(+), 75 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f7145ddd8f..b1fdffde5e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -12,22 +12,16 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" -KernelObjectPool g_kernel_objects; +namespace Kernel { -void __KernelInit() { - __KernelThreadingInit(); -} - -void __KernelShutdown() { - __KernelThreadingShutdown(); -} +ObjectPool g_object_pool; -KernelObjectPool::KernelObjectPool() { +ObjectPool::ObjectPool() { memset(occupied, 0, sizeof(bool) * MAX_COUNT); next_id = INITIAL_NEXT_ID; } -Handle KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_top) { +Handle ObjectPool::Create(Object* obj, int range_bottom, int range_top) { if (range_top > MAX_COUNT) { range_top = MAX_COUNT; } @@ -46,8 +40,7 @@ Handle KernelObjectPool::Create(KernelObject *obj, int range_bottom, int range_t return 0; } -bool KernelObjectPool::IsValid(Handle handle) -{ +bool ObjectPool::IsValid(Handle handle) { int index = handle - HANDLE_OFFSET; if (index < 0) return false; @@ -57,26 +50,24 @@ bool KernelObjectPool::IsValid(Handle handle) return occupied[index]; } -void KernelObjectPool::Clear() -{ - for (int i = 0; i < MAX_COUNT; i++) - { +void ObjectPool::Clear() { + for (int i = 0; i < MAX_COUNT; i++) { //brutally clear everything, no validation if (occupied[i]) delete pool[i]; occupied[i] = false; } - memset(pool, 0, sizeof(KernelObject*)*MAX_COUNT); + memset(pool, 0, sizeof(Object*)*MAX_COUNT); next_id = INITIAL_NEXT_ID; } -KernelObject *&KernelObjectPool::operator [](Handle handle) +Object* &ObjectPool::operator [](Handle handle) { _dbg_assert_msg_(KERNEL, IsValid(handle), "GRABBING UNALLOCED KERNEL OBJ"); return pool[handle - HANDLE_OFFSET]; } -void KernelObjectPool::List() { +void ObjectPool::List() { for (int i = 0; i < MAX_COUNT; i++) { if (occupied[i]) { if (pool[i]) { @@ -87,18 +78,16 @@ void KernelObjectPool::List() { } } -int KernelObjectPool::GetCount() -{ +int ObjectPool::GetCount() { int count = 0; - for (int i = 0; i < MAX_COUNT; i++) - { + for (int i = 0; i < MAX_COUNT; i++) { if (occupied[i]) count++; } return count; } -KernelObject *KernelObjectPool::CreateByIDType(int type) { +Object* ObjectPool::CreateByIDType(int type) { // Used for save states. This is ugly, but what other way is there? switch (type) { //case SCE_KERNEL_TMID_Alarm: @@ -142,8 +131,18 @@ KernelObject *KernelObjectPool::CreateByIDType(int type) { } } +void Init() { + __KernelThreadingInit(); +} + +void Shutdown() { + __KernelThreadingShutdown(); +} + +} // namespace + bool __KernelLoadExec(u32 entry_point) { - __KernelInit(); + Kernel::Init(); Core::g_app_core->SetPC(entry_point); diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 8f2b7b36da..19edb7b57f 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -9,41 +9,50 @@ typedef u32 Handle; typedef s32 Result; -enum KernelIDType { - KERNEL_ID_TYPE_THREAD, - KERNEL_ID_TYPE_SEMAPHORE, - KERNEL_ID_TYPE_MUTEX, - KERNEL_ID_TYPE_EVENT, - KERNEL_ID_TYPE_SERVICE, +namespace Kernel { + +enum class HandleType : u32 { + Unknown = 0, + Port = 1, + Service = 2, + Event = 3, + Mutex = 4, + SharedMemory = 5, + Redirection = 6, + Thread = 7, + Process = 8, + Arbiter = 9, + File = 10, + Semaphore = 11, }; - + enum { - KERNEL_MAX_NAME_LENGTH = 0x100, - KERNEL_DEFAULT_STACK_SIZE = 0x4000, + MAX_NAME_LENGTH = 0x100, + DEFAULT_STACK_SIZE = 0x4000, }; -class KernelObjectPool; +class ObjectPool; -class KernelObject { - friend class KernelObjectPool; +class Object : NonCopyable { + friend class ObjectPool; u32 handle; public: - virtual ~KernelObject() {} + virtual ~Object() {} Handle GetHandle() const { return handle; } virtual const char *GetTypeName() { return "[BAD KERNEL OBJECT TYPE]"; } virtual const char *GetName() { return "[UNKNOWN KERNEL OBJECT]"; } - virtual KernelIDType GetIDType() const = 0; + virtual Kernel::HandleType GetHandleType() const = 0; }; -class KernelObjectPool { +class ObjectPool : NonCopyable { public: - KernelObjectPool(); - ~KernelObjectPool() {} + ObjectPool(); + ~ObjectPool() {} // Allocates a handle within the range and inserts the object into the map. - Handle Create(KernelObject *obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); + Handle Create(Object* obj, int range_bottom=INITIAL_NEXT_ID, int range_top=0x7FFFFFFF); - static KernelObject *CreateByIDType(int type); + static Object* CreateByIDType(int type); template u32 Destroy(Handle handle) { @@ -71,7 +80,7 @@ public: // it just acted as a static case and everything worked. This means that we will never // see the Wrong type object error below, but we'll just have to live with that danger. T* t = static_cast(pool[handle - HANDLE_OFFSET]); - if (t == 0 || t->GetIDType() != T::GetStaticIDType()) { + if (t == 0 || t->GetHandleType() != T::GetStaticHandleType()) { WARN_LOG(KERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle); outError = 0;//T::GetMissingErrorCode(); return 0; @@ -86,17 +95,17 @@ public: T *GetFast(Handle handle) { const Handle realHandle = handle - HANDLE_OFFSET; _dbg_assert_(KERNEL, realHandle >= 0 && realHandle < MAX_COUNT && occupied[realHandle]); - return static_cast(pool[realHandle]); + return static_cast(pool[realHandle]); } template - void Iterate(bool func(T *, ArgT), ArgT arg) { + void Iterate(bool func(T*, ArgT), ArgT arg) { int type = T::GetStaticIDType(); for (int i = 0; i < MAX_COUNT; i++) { if (!occupied[i]) continue; - T *t = static_cast(pool[i]); + T* t = static_cast(pool[i]); if (t->GetIDType() == type) { if (!func(t, arg)) break; @@ -104,33 +113,37 @@ public: } } - bool GetIDType(Handle handle, int *type) const { + bool GetIDType(Handle handle, HandleType* type) const { if ((handle < HANDLE_OFFSET) || (handle >= HANDLE_OFFSET + MAX_COUNT) || !occupied[handle - HANDLE_OFFSET]) { ERROR_LOG(KERNEL, "Kernel: Bad object handle %i (%08x)", handle, handle); return false; } - KernelObject *t = pool[handle - HANDLE_OFFSET]; - *type = t->GetIDType(); + Object* t = pool[handle - HANDLE_OFFSET]; + *type = t->GetHandleType(); return true; } - KernelObject *&operator [](Handle handle); + Object* &operator [](Handle handle); void List(); void Clear(); int GetCount(); private: + enum { MAX_COUNT = 0x1000, HANDLE_OFFSET = 0x100, INITIAL_NEXT_ID = 0x10, }; - KernelObject *pool[MAX_COUNT]; - bool occupied[MAX_COUNT]; - int next_id; + + Object* pool[MAX_COUNT]; + bool occupied[MAX_COUNT]; + int next_id; }; -extern KernelObjectPool g_kernel_objects; +extern ObjectPool g_object_pool; + +} // namespace bool __KernelLoadExec(u32 entry_point); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 634218e8ba..2955d6f5b2 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -42,14 +42,14 @@ enum WaitType { WAITTYPE_SYNCH, }; -class Thread : public KernelObject { +class Thread : public Kernel::Object { public: const char *GetName() { return name; } const char *GetTypeName() { return "Thread"; } - static KernelIDType GetStaticIDType() { return KERNEL_ID_TYPE_THREAD; } - KernelIDType GetIDType() const { return KERNEL_ID_TYPE_THREAD; } + static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Thread; } + Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Thread; } inline bool IsRunning() const { return (status & THREADSTATUS_RUNNING) != 0; } inline bool IsStopped() const { return (status & THREADSTATUS_DORMANT) != 0; } @@ -71,7 +71,7 @@ public: WaitType wait_type; - char name[KERNEL_MAX_NAME_LENGTH+1]; + char name[Kernel::MAX_NAME_LENGTH + 1]; }; // Lists all thread ids that aren't deleted/etc. @@ -201,7 +201,7 @@ Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, Thread *t = new Thread; - handle = g_kernel_objects.Create(t); + handle = Kernel::g_object_pool.Create(t); g_thread_queue.push_back(handle); g_thread_ready_queue.prepare(priority); @@ -214,8 +214,8 @@ Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, t->processor_id = processor_id; t->wait_type = WAITTYPE_NONE; - strncpy(t->name, name, KERNEL_MAX_NAME_LENGTH); - t->name[KERNEL_MAX_NAME_LENGTH] = '\0'; + strncpy(t->name, name, Kernel::MAX_NAME_LENGTH); + t->name[Kernel::MAX_NAME_LENGTH] = '\0'; return t; } @@ -296,7 +296,7 @@ Thread *__KernelNextThread() { if (next < 0) { return NULL; } - return g_kernel_objects.GetFast(next); + return Kernel::g_object_pool.GetFast(next); } /// Sets up the primary application thread @@ -326,7 +326,7 @@ Handle __KernelSetupMainThread(s32 priority, int stack_size) { /// Resumes a thread from waiting by marking it as "ready" void __KernelResumeThreadFromWait(Handle handle) { u32 error; - Thread *t = g_kernel_objects.Get(handle, error); + Thread *t = Kernel::g_object_pool.Get(handle, error); if (t) { t->status &= ~THREADSTATUS_WAIT; if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index eca84c7180..207a5227b1 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -23,10 +23,10 @@ enum ThreadProcessorId { /// Creates a new thread - wrapper for external user Handle __KernelCreateThread(const char *name, u32 entry_point, s32 priority, - s32 processor_id, u32 stack_top, int stack_size=KERNEL_DEFAULT_STACK_SIZE); + s32 processor_id, u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Sets up the primary application thread -Handle __KernelSetupMainThread(s32 priority, int stack_size=KERNEL_DEFAULT_STACK_SIZE); +Handle __KernelSetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Reschedules to the next available thread (call after current thread is suspended) void __KernelReschedule(const char *reason); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index b3e414e0f9..08d0c43ff5 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -34,7 +34,7 @@ Manager::~Manager() { /// Add a service to the manager (does not create it though) void Manager::AddService(Interface* service) { - m_port_map[service->GetPortName()] = g_kernel_objects.Create(service); + m_port_map[service->GetPortName()] = Kernel::g_object_pool.Create(service); m_services.push_back(service); } @@ -48,7 +48,7 @@ void Manager::DeleteService(std::string port_name) { /// Get a Service Interface from its Handle Interface* Manager::FetchFromHandle(Handle handle) { - return g_kernel_objects.GetFast(handle); + return Kernel::g_object_pool.GetFast(handle); } /// Get a Service Interface from its port diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 450a439fe0..f334dbcb8e 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -36,15 +36,15 @@ inline static u32* GetCommandBuffer(const int offset=0) { class Manager; /// Interface to a CTROS service -class Interface : public KernelObject { +class Interface : public Kernel::Object { friend class Manager; public: const char *GetName() { return GetPortName(); } const char *GetTypeName() { return GetPortName(); } - static KernelIDType GetStaticIDType() { return KERNEL_ID_TYPE_THREAD; } - KernelIDType GetIDType() const { return KERNEL_ID_TYPE_THREAD; } + static Kernel::HandleType GetStaticHandleType() { return Kernel::HandleType::Service; } + Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Service; } typedef void (*Function)(Interface*); @@ -63,8 +63,8 @@ public: } /// Allocates a new handle for the service - Handle CreateHandle(KernelObject *obj) { - Handle handle = g_kernel_objects.Create(obj); + Handle CreateHandle(Kernel::Object *obj) { + Handle handle = Kernel::g_object_pool.Create(obj); m_handles.push_back(handle); return handle; } @@ -72,7 +72,7 @@ public: /// Frees a handle from the service template void DeleteHandle(const Handle handle) { - g_kernel_objects.Destroy(handle); + g_object_pool.Destroy(handle); m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); } -- cgit v1.2.3 From 75c6d2a8fa3547946227094af6c179e5ccba0e1e Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 May 2014 19:37:46 -0400 Subject: thread: moved threading calls to the Kernel namespace --- src/core/hle/kernel/kernel.cpp | 6 +- src/core/hle/kernel/thread.cpp | 184 +++++++++++++++++++++-------------------- src/core/hle/kernel/thread.h | 26 ++++-- src/core/hle/svc.cpp | 4 +- 4 files changed, 117 insertions(+), 103 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b1fdffde5e..45e36173c0 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -132,11 +132,11 @@ Object* ObjectPool::CreateByIDType(int type) { } void Init() { - __KernelThreadingInit(); + Kernel::ThreadingInit(); } void Shutdown() { - __KernelThreadingShutdown(); + Kernel::ThreadingShutdown(); } } // namespace @@ -147,7 +147,7 @@ bool __KernelLoadExec(u32 entry_point) { Core::g_app_core->SetPC(entry_point); // 0x30 is the typical main thread priority I've seen used so far - Handle thread_id = __KernelSetupMainThread(0x30); + Handle thread_id = Kernel::SetupMainThread(0x30); return true; } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index b3d306c531..7b4f0ea47d 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -19,7 +19,7 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/thread.h" -// Enums +namespace Kernel { enum ThreadStatus { THREADSTATUS_RUNNING = 1, @@ -81,33 +81,32 @@ std::vector g_thread_queue; Common::ThreadQueueList g_thread_ready_queue; Handle g_current_thread_handle; - Thread* g_current_thread; +/// Gets the current thread inline Thread* __GetCurrentThread() { return g_current_thread; } +/// Sets the current thread inline void __SetCurrentThread(Thread* t) { g_current_thread = t; g_current_thread_handle = t->GetHandle(); } -//////////////////////////////////////////////////////////////////////////////////////////////////// - /// Saves the current CPU context -void __KernelSaveContext(ThreadContext& ctx) { +void __SaveContext(ThreadContext& ctx) { Core::g_app_core->SaveContext(ctx); } /// Loads a CPU context -void __KernelLoadContext(const ThreadContext& ctx) { +void __LoadContext(const ThreadContext& ctx) { Core::g_app_core->LoadContext(ctx); } /// Resets a thread -void __KernelResetThread(Thread* t, s32 lowest_priority) { +void __ResetThread(Thread* t, s32 lowest_priority) { memset(&t->context, 0, sizeof(ThreadContext)); t->context.pc = t->entry_point; @@ -121,7 +120,7 @@ void __KernelResetThread(Thread* t, s32 lowest_priority) { } /// Change a thread to "ready" state -void __KernelChangeReadyState(Thread* t, bool ready) { +void __ChangeReadyState(Thread* t, bool ready) { Handle handle = t->GetHandle(); if (t->IsReady()) { if (!ready) { @@ -138,11 +137,11 @@ void __KernelChangeReadyState(Thread* t, bool ready) { } /// Changes a threads state -void __KernelChangeThreadState(Thread* t, ThreadStatus new_status) { +void __ChangeThreadState(Thread* t, ThreadStatus new_status) { if (!t || t->status == new_status) { return; } - __KernelChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); + __ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); t->status = new_status; if (new_status == THREADSTATUS_WAIT) { @@ -153,16 +152,75 @@ void __KernelChangeThreadState(Thread* t, ThreadStatus new_status) { } /// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields) -void __KernelCallThread(Thread* t) { +void __CallThread(Thread* t) { // Stop waiting if (t->wait_type != WAITTYPE_NONE) { t->wait_type = WAITTYPE_NONE; } - __KernelChangeThreadState(t, THREADSTATUS_READY); + __ChangeThreadState(t, THREADSTATUS_READY); +} + +/// Switches CPU context to that of the specified thread +void __SwitchContext(Thread* t, const char* reason) { + Thread* cur = __GetCurrentThread(); + + // Save context for current thread + if (cur) { + __SaveContext(cur->context); + + if (cur->IsRunning()) { + __ChangeReadyState(cur, true); + } + } + // Load context of new thread + if (t) { + __SetCurrentThread(t); + __ChangeReadyState(t, false); + t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; + t->wait_type = WAITTYPE_NONE; + __LoadContext(t->context); + } else { + __SetCurrentThread(NULL); + } +} + +/// Gets the next thread that is ready to be run by priority +Thread* __NextThread() { + Handle next; + Thread* cur = __GetCurrentThread(); + + if (cur && cur->IsRunning()) { + next = g_thread_ready_queue.pop_first_better(cur->current_priority); + } else { + next = g_thread_ready_queue.pop_first(); + } + if (next < 0) { + return NULL; + } + return Kernel::g_object_pool.GetFast(next); +} + +/// Resumes a thread from waiting by marking it as "ready" +void __ResumeThreadFromWait(Handle handle) { + u32 error; + Thread* t = Kernel::g_object_pool.Get(handle, error); + if (t) { + t->status &= ~THREADSTATUS_WAIT; + if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { + __ChangeReadyState(t, true); + } + } +} + +/// Puts a thread in the wait state for the given type/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))); } /// Creates a new thread -Thread* __KernelCreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority, +Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority, s32 processor_id, u32 stack_top, int stack_size) { Thread* t = new Thread; @@ -187,31 +245,31 @@ Thread* __KernelCreateThread(Handle& handle, const char* name, u32 entry_point, } /// Creates a new thread - wrapper for external user -Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, +Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, u32 stack_top, int stack_size) { if (name == NULL) { - ERROR_LOG(KERNEL, "__KernelCreateThread(): NULL name"); + ERROR_LOG(KERNEL, "CreateThread(): NULL name"); return -1; } if ((u32)stack_size < 0x200) { - ERROR_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid stack_size=0x%08X", name, + ERROR_LOG(KERNEL, "CreateThread(name=%s): invalid stack_size=0x%08X", name, stack_size); return -1; } if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); - WARN_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid priority=0x%08X, clamping to %08X", + WARN_LOG(KERNEL, "CreateThread(name=%s): invalid priority=0x%08X, clamping to %08X", name, priority, new_priority); // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm // validity of this priority = new_priority; } if (!Memory::GetPointer(entry_point)) { - ERROR_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid entry %08x", name, entry_point); + ERROR_LOG(KERNEL, "CreateThread(name=%s): invalid entry %08x", name, entry_point); return -1; } Handle handle; - Thread* t = __KernelCreateThread(handle, name, entry_point, priority, processor_id, stack_top, + Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, stack_size); HLE::EatCycles(32000); @@ -220,114 +278,62 @@ Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority, s32 // Technically, this should not eat all at once, and reschedule in the middle, but that's hard. HLE::ReSchedule("thread created"); - __KernelCallThread(t); + __CallThread(t); return handle; } -/// Switches CPU context to that of the specified thread -void __KernelSwitchContext(Thread* t, const char* reason) { - Thread* cur = __GetCurrentThread(); - - // Save context for current thread - if (cur) { - __KernelSaveContext(cur->context); - - if (cur->IsRunning()) { - __KernelChangeReadyState(cur, true); - } - } - // Load context of new thread - if (t) { - __SetCurrentThread(t); - __KernelChangeReadyState(t, false); - t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; - t->wait_type = WAITTYPE_NONE; - __KernelLoadContext(t->context); - } else { - __SetCurrentThread(NULL); - } -} - -/// Gets the next thread that is ready to be run by priority -Thread* __KernelNextThread() { - Handle next; - Thread* cur = __GetCurrentThread(); - - if (cur && cur->IsRunning()) { - next = g_thread_ready_queue.pop_first_better(cur->current_priority); - } else { - next = g_thread_ready_queue.pop_first(); - } - if (next < 0) { - return NULL; - } - return Kernel::g_object_pool.GetFast(next); +/// Gets the current thread +Handle GetCurrentThread() { + return __GetCurrentThread()->GetHandle(); } /// Sets up the primary application thread -Handle __KernelSetupMainThread(s32 priority, int stack_size) { +Handle SetupMainThread(s32 priority, int stack_size) { Handle handle; // Initialize new "main" thread - Thread* t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority, + Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority, THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); - __KernelResetThread(t, 0); + __ResetThread(t, 0); // If running another thread already, set it to "ready" state Thread* cur = __GetCurrentThread(); if (cur && cur->IsRunning()) { - __KernelChangeReadyState(cur, true); + __ChangeReadyState(cur, true); } // Run new "main" thread __SetCurrentThread(t); t->status = THREADSTATUS_RUNNING; - __KernelLoadContext(t->context); + __LoadContext(t->context); return handle; } -/// Resumes a thread from waiting by marking it as "ready" -void __KernelResumeThreadFromWait(Handle handle) { - u32 error; - Thread* t = Kernel::g_object_pool.Get(handle, error); - if (t) { - t->status &= ~THREADSTATUS_WAIT; - if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { - __KernelChangeReadyState(t, true); - } - } -} - -/// Puts a thread in the wait state for the given type/reason -void __KernelWaitCurThread(WaitType wait_type, const char* reason) { - Thread* t = __GetCurrentThread(); - t->wait_type = wait_type; - __KernelChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); -} - /// Reschedules to the next available thread (call after current thread is suspended) -void __KernelReschedule(const char* reason) { - Thread* next = __KernelNextThread(); +void Reschedule(const char* reason) { + Thread* next = __NextThread(); if (next > 0) { - __KernelSwitchContext(next, reason); + __SwitchContext(next, reason); } } //////////////////////////////////////////////////////////////////////////////////////////////////// /// Put current thread in a wait state - on WaitSynchronization -void __KernelWaitThread_Synchronization() { +void WaitThread_Synchronization() { // TODO(bunnei): Just a placeholder function for now... FixMe - __KernelWaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called"); + __WaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called"); } //////////////////////////////////////////////////////////////////////////////////////////////////// -void __KernelThreadingInit() { +void ThreadingInit() { } -void __KernelThreadingShutdown() { +void ThreadingShutdown() { } + +} // namespace diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 72e9a416de..2c01992730 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -7,8 +7,6 @@ #include "common/common_types.h" #include "core/hle/kernel/kernel.h" -class Thread; - enum ThreadPriority { THREADPRIO_HIGHEST = 0, THREADPRIO_DEFAULT = 16, @@ -21,18 +19,28 @@ enum ThreadProcessorId { THREADPROCESSORID_ALL = 0xFFFFFFFC, }; +namespace Kernel { + /// Creates a new thread - wrapper for external user -Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority, - s32 processor_id, u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE); +Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id, + u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Sets up the primary application thread -Handle __KernelSetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); +Handle SetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE); /// Reschedules to the next available thread (call after current thread is suspended) -void __KernelReschedule(const char* reason); +void Reschedule(const char* reason); -void __KernelThreadingInit(); -void __KernelThreadingShutdown(); +/// Gets the current thread +Handle GetCurrentThread(); /// Put current thread in a wait state - on WaitSynchronization -void __KernelWaitThread_Synchronization(); +void WaitThread_Synchronization(); + +/// Initialize threading +void ThreadingInit(); + +/// Shutdown threading +void ThreadingShutdown(); + +} // namespace diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index a9141699c8..6f0f099c68 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -123,7 +123,7 @@ Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wa for (u32 i = 0; i < handle_count; i++) { DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]); } - __KernelReschedule("WaitSynchronizationN"); + Kernel::Reschedule("WaitSynchronizationN"); return 0; } @@ -175,7 +175,7 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st "threadpriority=0x%08X, processorid=0x%08X", entry_point, name.c_str(), arg, stack_top, priority, processor_id); - Handle handle = __KernelCreateThread(name.c_str(), entry_point, priority, processor_id, + Handle handle = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id, stack_top); Core::g_app_core->SetReg(1, 0xFEEDDEAF); -- cgit v1.2.3 From d26f3d4c1ff27f740fe7185e1bca7dcfc5851919 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 22 May 2014 19:06:12 -0400 Subject: kernel: refactored function naming to remove "__" prefix --- src/core/hle/kernel/kernel.cpp | 15 +++++--- src/core/hle/kernel/kernel.h | 9 +++-- src/core/hle/kernel/mutex.cpp | 28 +++++++-------- src/core/hle/kernel/thread.cpp | 78 +++++++++++++++++++++--------------------- src/core/hle/kernel/thread.h | 4 +-- src/core/loader.cpp | 6 ++-- 6 files changed, 75 insertions(+), 65 deletions(-) (limited to 'src/core/hle/kernel/kernel.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 45e36173c0..de80de8937 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -139,15 +139,20 @@ void Shutdown() { Kernel::ThreadingShutdown(); } -} // namespace - -bool __KernelLoadExec(u32 entry_point) { - Kernel::Init(); +/** + * Loads executable stored at specified address + * @entry_point Entry point in memory of loaded executable + * @return True on success, otherwise false + */ +bool LoadExec(u32 entry_point) { + Init(); Core::g_app_core->SetPC(entry_point); // 0x30 is the typical main thread priority I've seen used so far - Handle thread_id = Kernel::SetupMainThread(0x30); + Handle thread = Kernel::SetupMainThread(0x30); return true; } + +} // namespace diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 1803399142..7cd79c2c41 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -144,6 +144,11 @@ private: extern ObjectPool g_object_pool; -} // namespace +/** + * Loads executable stored at specified address + * @entry_point Entry point in memory of loaded executable + * @return True on success, otherwise false + */ +bool LoadExec(u32 entry_point); -bool __KernelLoadExec(u32 entry_point); +} // namespace diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 7cf3439e98..019efbc785 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -30,17 +30,17 @@ public: typedef std::multimap MutexMap; static MutexMap g_mutex_held_locks; -void __MutexAcquireLock(Mutex* mutex, Handle thread) { +void MutexAcquireLock(Mutex* mutex, Handle thread) { g_mutex_held_locks.insert(std::make_pair(thread, mutex->GetHandle())); mutex->lock_thread = thread; } -void __MutexAcquireLock(Mutex* mutex) { - Handle thread = GetCurrentThread(); - __MutexAcquireLock(mutex, thread); +void MutexAcquireLock(Mutex* mutex) { + Handle thread = GetCurrentThreadHandle(); + MutexAcquireLock(mutex, thread); } -void __MutexEraseLock(Mutex* mutex) { +void MutexEraseLock(Mutex* mutex) { Handle handle = mutex->GetHandle(); auto locked = g_mutex_held_locks.equal_range(mutex->lock_thread); for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { @@ -52,29 +52,29 @@ void __MutexEraseLock(Mutex* mutex) { mutex->lock_thread = -1; } -bool __LockMutex(Mutex* mutex) { +bool LockMutex(Mutex* mutex) { // Mutex alread locked? if (mutex->locked) { return false; } - __MutexAcquireLock(mutex); + MutexAcquireLock(mutex); return true; } -bool __ReleaseMutexForThread(Mutex* mutex, Handle thread) { - __MutexAcquireLock(mutex, thread); +bool ReleaseMutexForThread(Mutex* mutex, Handle thread) { + MutexAcquireLock(mutex, thread); Kernel::ResumeThreadFromWait(thread); return true; } -bool __ReleaseMutex(Mutex* mutex) { - __MutexEraseLock(mutex); +bool ReleaseMutex(Mutex* mutex) { + MutexEraseLock(mutex); bool woke_threads = false; auto iter = mutex->waiting_threads.begin(); // Find the next waiting thread for the mutex... while (!woke_threads && !mutex->waiting_threads.empty()) { - woke_threads |= __ReleaseMutexForThread(mutex, *iter); + woke_threads |= ReleaseMutexForThread(mutex, *iter); mutex->waiting_threads.erase(iter); } // Reset mutex lock thread handle, nothing is waiting @@ -91,7 +91,7 @@ bool __ReleaseMutex(Mutex* mutex) { */ Result ReleaseMutex(Handle handle) { Mutex* mutex = Kernel::g_object_pool.GetFast(handle); - if (!__ReleaseMutex(mutex)) { + if (!ReleaseMutex(mutex)) { return -1; } return 0; @@ -110,7 +110,7 @@ Mutex* CreateMutex(Handle& handle, bool initial_locked) { // Acquire mutex with current thread if initialized as locked... if (mutex->locked) { - __MutexAcquireLock(mutex); + MutexAcquireLock(mutex); // Otherwise, reset lock thread handle } else { diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 934ca87c4d..5f1d5c4002 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -64,28 +64,33 @@ Thread* g_current_thread; /// Gets the current thread -inline Thread* __GetCurrentThread() { +inline Thread* GetCurrentThread() { return g_current_thread; } +/// Gets the current thread handle +Handle GetCurrentThreadHandle() { + return GetCurrentThread()->GetHandle(); +} + /// Sets the current thread -inline void __SetCurrentThread(Thread* t) { +inline void SetCurrentThread(Thread* t) { g_current_thread = t; g_current_thread_handle = t->GetHandle(); } /// Saves the current CPU context -void __SaveContext(ThreadContext& ctx) { +void SaveContext(ThreadContext& ctx) { Core::g_app_core->SaveContext(ctx); } /// Loads a CPU context -void __LoadContext(ThreadContext& ctx) { +void LoadContext(ThreadContext& ctx) { Core::g_app_core->LoadContext(ctx); } /// Resets a thread -void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { +void ResetThread(Thread* t, u32 arg, s32 lowest_priority) { memset(&t->context, 0, sizeof(ThreadContext)); t->context.cpu_registers[0] = arg; @@ -101,7 +106,7 @@ void __ResetThread(Thread* t, u32 arg, s32 lowest_priority) { } /// Change a thread to "ready" state -void __ChangeReadyState(Thread* t, bool ready) { +void ChangeReadyState(Thread* t, bool ready) { Handle handle = t->GetHandle(); if (t->IsReady()) { if (!ready) { @@ -118,11 +123,11 @@ void __ChangeReadyState(Thread* t, bool ready) { } /// Changes a threads state -void __ChangeThreadState(Thread* t, ThreadStatus new_status) { +void ChangeThreadState(Thread* t, ThreadStatus new_status) { if (!t || t->status == new_status) { return; } - __ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); + ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0); t->status = new_status; if (new_status == THREADSTATUS_WAIT) { @@ -133,42 +138,42 @@ void __ChangeThreadState(Thread* t, ThreadStatus new_status) { } /// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields) -void __CallThread(Thread* t) { +void CallThread(Thread* t) { // Stop waiting if (t->wait_type != WAITTYPE_NONE) { t->wait_type = WAITTYPE_NONE; } - __ChangeThreadState(t, THREADSTATUS_READY); + ChangeThreadState(t, THREADSTATUS_READY); } /// Switches CPU context to that of the specified thread -void __SwitchContext(Thread* t, const char* reason) { - Thread* cur = __GetCurrentThread(); +void SwitchContext(Thread* t, const char* reason) { + Thread* cur = GetCurrentThread(); // Save context for current thread if (cur) { - __SaveContext(cur->context); + SaveContext(cur->context); if (cur->IsRunning()) { - __ChangeReadyState(cur, true); + ChangeReadyState(cur, true); } } // Load context of new thread if (t) { - __SetCurrentThread(t); - __ChangeReadyState(t, false); + SetCurrentThread(t); + ChangeReadyState(t, false); t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY; t->wait_type = WAITTYPE_NONE; - __LoadContext(t->context); + LoadContext(t->context); } else { - __SetCurrentThread(NULL); + SetCurrentThread(NULL); } } /// Gets the next thread that is ready to be run by priority -Thread* __NextThread() { +Thread* NextThread() { Handle next; - Thread* cur = __GetCurrentThread(); + Thread* cur = GetCurrentThread(); if (cur && cur->IsRunning()) { next = g_thread_ready_queue.pop_first_better(cur->current_priority); @@ -183,9 +188,9 @@ Thread* __NextThread() { /// Puts a thread in the wait state for the given type/reason void WaitCurThread(WaitType wait_type, const char* reason) { - Thread* t = __GetCurrentThread(); + Thread* t = GetCurrentThread(); t->wait_type = wait_type; - __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); + ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND))); } /// Resumes a thread from waiting by marking it as "ready" @@ -195,7 +200,7 @@ void ResumeThreadFromWait(Handle handle) { if (t) { t->status &= ~THREADSTATUS_WAIT; if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) { - __ChangeReadyState(t, true); + ChangeReadyState(t, true); } } } @@ -256,7 +261,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top, stack_size); - __ResetThread(t, arg, 0); + ResetThread(t, arg, 0); HLE::EatCycles(32000); @@ -264,16 +269,11 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3 // Technically, this should not eat all at once, and reschedule in the middle, but that's hard. HLE::ReSchedule("thread created"); - __CallThread(t); + CallThread(t); return handle; } -/// Gets the current thread -Handle GetCurrentThread() { - return __GetCurrentThread()->GetHandle(); -} - /// Sets up the primary application thread Handle SetupMainThread(s32 priority, int stack_size) { Handle handle; @@ -282,33 +282,33 @@ 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, 0); + ResetThread(t, 0, 0); // If running another thread already, set it to "ready" state - Thread* cur = __GetCurrentThread(); + Thread* cur = GetCurrentThread(); if (cur && cur->IsRunning()) { - __ChangeReadyState(cur, true); + ChangeReadyState(cur, true); } // Run new "main" thread - __SetCurrentThread(t); + SetCurrentThread(t); t->status = THREADSTATUS_RUNNING; - __LoadContext(t->context); + LoadContext(t->context); return handle; } /// Reschedules to the next available thread (call after current thread is suspended) void Reschedule(const char* reason) { - Thread* prev = __GetCurrentThread(); - Thread* next = __NextThread(); + Thread* prev = GetCurrentThread(); + Thread* next = NextThread(); if (next > 0) { - __SwitchContext(next, reason); + SwitchContext(next, reason); // 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); + ChangeReadyState(prev, true); } } diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 82bf16082e..a9e9eb95fb 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -59,8 +59,8 @@ void WaitCurThread(WaitType wait_type, const char* reason); /// Resumes a thread from waiting by marking it as "ready" void ResumeThreadFromWait(Handle handle); -/// Gets the current thread -Handle GetCurrentThread(); +/// Gets the current thread handle +Handle GetCurrentThreadHandle(); /// Put current thread in a wait state - on WaitSynchronization void WaitThread_Synchronization(); diff --git a/src/core/loader.cpp b/src/core/loader.cpp index 444b75feba..ff1c873bb6 100644 --- a/src/core/loader.cpp +++ b/src/core/loader.cpp @@ -56,7 +56,7 @@ bool Load_ELF(std::string &filename) { elf_reader = new ElfReader(buffer); elf_reader->LoadInto(0x00100000); - __KernelLoadExec(elf_reader->GetEntryPoint()); + Kernel::LoadExec(elf_reader->GetEntryPoint()); delete[] buffer; delete elf_reader; @@ -102,7 +102,7 @@ bool Load_DAT(std::string &filename) { *d++ = (*s++); } - __KernelLoadExec(entry_point); + Kernel::LoadExec(entry_point); delete[] buffer; @@ -144,7 +144,7 @@ bool Load_BIN(std::string &filename) { *d++ = (*s++); } - __KernelLoadExec(entry_point); + Kernel::LoadExec(entry_point); delete[] buffer; } -- cgit v1.2.3