- 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
This commit is contained in:
		@@ -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();
 | 
			
		||||
}
 | 
			
		||||
ObjectPool g_object_pool;
 | 
			
		||||
 | 
			
		||||
void __KernelShutdown() {
 | 
			
		||||
    __KernelThreadingShutdown();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <class T>
 | 
			
		||||
    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<T*>(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<T *>(pool[realHandle]);
 | 
			
		||||
        return static_cast<T*>(pool[realHandle]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    template <class T, typename ArgT>
 | 
			
		||||
    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<T *>(pool[i]);
 | 
			
		||||
            T* t = static_cast<T*>(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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Thread>(next);
 | 
			
		||||
    return Kernel::g_object_pool.GetFast<Thread>(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<Thread>(handle, error);
 | 
			
		||||
    Thread *t = Kernel::g_object_pool.Get<Thread>(handle, error);
 | 
			
		||||
    if (t) {
 | 
			
		||||
        t->status &= ~THREADSTATUS_WAIT;
 | 
			
		||||
        if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
 | 
			
		||||
 
 | 
			
		||||
@@ -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);
 | 
			
		||||
 
 | 
			
		||||
@@ -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<Interface>(handle);
 | 
			
		||||
    return Kernel::g_object_pool.GetFast<Interface>(handle);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get a Service Interface from its port
 | 
			
		||||
 
 | 
			
		||||
@@ -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 <class T>
 | 
			
		||||
    void DeleteHandle(const Handle handle) {
 | 
			
		||||
        g_kernel_objects.Destroy<T>(handle);
 | 
			
		||||
        g_object_pool.Destroy<T>(handle);
 | 
			
		||||
        m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user