From eec40f8f6f5fea63640721027408887291e19f61 Mon Sep 17 00:00:00 2001
From: archshift <admin@archshift.com>
Date: Thu, 1 May 2014 15:13:06 -0700
Subject: [PATCH 01/72] Use runtime arguments to specify boot filename.

---
 src/citra/citra.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index d55b97393..00bab3203 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -24,7 +24,7 @@ int __cdecl main(int argc, char **argv) {
 
 	System::Init(emu_window);
 
-    std::string boot_filename = "homebrew.elf";
+    std::string boot_filename = argv[1];
     std::string error_str;
     
     bool res = Loader::LoadFile(boot_filename, &error_str);

From 62528320ea31e94202d649855a5eef79e127edd9 Mon Sep 17 00:00:00 2001
From: archshift <admin@archshift.com>
Date: Thu, 1 May 2014 20:41:42 -0700
Subject: [PATCH 02/72] Check arg count before attempting to access it.

---
 src/citra/citra.cpp | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index 00bab3203..d8325772e 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -24,7 +24,14 @@ int __cdecl main(int argc, char **argv) {
 
 	System::Init(emu_window);
 
-    std::string boot_filename = argv[1];
+    std::string boot_filename;
+	
+	if (argc < 2) {
+		ERROR_LOG(BOOT, "Failed to load ROM: No ROM specified");
+	}
+	else {
+		boot_filename = argv[1];
+	}
     std::string error_str;
     
     bool res = Loader::LoadFile(boot_filename, &error_str);

From bd316ca0c0e244baf8f77b635eae85f744a62cf1 Mon Sep 17 00:00:00 2001
From: archshift <admin@archshift.com>
Date: Sun, 4 May 2014 15:47:42 -0700
Subject: [PATCH 03/72] Fixed indents

---
 src/citra/citra.cpp | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/citra/citra.cpp b/src/citra/citra.cpp
index d8325772e..80896505f 100644
--- a/src/citra/citra.cpp
+++ b/src/citra/citra.cpp
@@ -25,13 +25,13 @@ int __cdecl main(int argc, char **argv) {
 	System::Init(emu_window);
 
     std::string boot_filename;
-	
-	if (argc < 2) {
-		ERROR_LOG(BOOT, "Failed to load ROM: No ROM specified");
-	}
-	else {
-		boot_filename = argv[1];
-	}
+
+    if (argc < 2) {
+        ERROR_LOG(BOOT, "Failed to load ROM: No ROM specified");
+    }
+    else {
+        boot_filename = argv[1];
+    }
     std::string error_str;
     
     bool res = Loader::LoadFile(boot_filename, &error_str);

From daf7a7880a9e3b84c340aaf690310fb68e287372 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 9 May 2014 20:54:51 -0400
Subject: [PATCH 04/72] added kernel logger to common

---
 src/common/log.h           | 4 +++-
 src/common/log_manager.cpp | 4 ++--
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/common/log.h b/src/common/log.h
index d95f51f56..8b39b03a1 100644
--- a/src/common/log.h
+++ b/src/common/log.h
@@ -5,6 +5,8 @@
 #ifndef _LOG_H_
 #define _LOG_H_
 
+#define LOGGING
+
 #define    NOTICE_LEVEL  1  // VERY important information that is NOT errors. Like startup and OSReports.
 #define    ERROR_LEVEL   2  // Critical errors 
 #define    WARNING_LEVEL 3  // Something is suspicious.
@@ -53,7 +55,7 @@ enum LOG_TYPE {
     WII_IPC_ES,
     WII_IPC_FILEIO,
     WII_IPC_HID,
-    WII_IPC_HLE,
+    KERNEL,
     SVC,
     NDMA,
     HLE,
diff --git a/src/common/log_manager.cpp b/src/common/log_manager.cpp
index 80fd473b9..146472888 100644
--- a/src/common/log_manager.cpp
+++ b/src/common/log_manager.cpp
@@ -60,13 +60,13 @@ LogManager::LogManager()
     m_Log[LogTypes::LOADER]             = new LogContainer("Loader",            "Loader");
     m_Log[LogTypes::FILESYS]            = new LogContainer("FileSys",           "File System");
     m_Log[LogTypes::WII_IPC_HID]        = new LogContainer("WII_IPC_HID",       "WII IPC HID");
-    m_Log[LogTypes::WII_IPC_HLE]        = new LogContainer("WII_IPC_HLE",       "WII IPC HLE");
+    m_Log[LogTypes::KERNEL]             = new LogContainer("KERNEL",            "KERNEL HLE");
     m_Log[LogTypes::WII_IPC_DVD]        = new LogContainer("WII_IPC_DVD",       "WII IPC DVD");
     m_Log[LogTypes::WII_IPC_ES]         = new LogContainer("WII_IPC_ES",        "WII IPC ES");
     m_Log[LogTypes::WII_IPC_FILEIO]     = new LogContainer("WII_IPC_FILEIO",    "WII IPC FILEIO");
     m_Log[LogTypes::RENDER]             = new LogContainer("RENDER",            "RENDER");
     m_Log[LogTypes::LCD]                = new LogContainer("LCD",               "LCD");
-    m_Log[LogTypes::SVC]                = new LogContainer("SVC",               "Supervisor Call");
+    m_Log[LogTypes::SVC]                = new LogContainer("SVC",               "Supervisor Call HLE");
     m_Log[LogTypes::NDMA]               = new LogContainer("NDMA",              "NDMA");
     m_Log[LogTypes::HLE]                = new LogContainer("HLE",               "High Level Emulation");
     m_Log[LogTypes::HW]                 = new LogContainer("HW",                "Hardware");

From 6b264518a50ce21cb1be55ff3eac4e1c85582cfe Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 9 May 2014 22:11:18 -0400
Subject: [PATCH 05/72] added initial kernel/thread modules

---
 src/core/CMakeLists.txt        |   2 +
 src/core/core.vcxproj          |   4 +
 src/core/core.vcxproj.filters  |  15 +++
 src/core/hle/kernel/kernel.cpp | 142 ++++++++++++++++++++
 src/core/hle/kernel/kernel.h   | 121 +++++++++++++++++
 src/core/hle/kernel/thread.cpp | 228 +++++++++++++++++++++++++++++++++
 src/core/hle/kernel/thread.h   |  36 ++++++
 7 files changed, 548 insertions(+)
 create mode 100644 src/core/hle/kernel/kernel.cpp
 create mode 100644 src/core/hle/kernel/kernel.h
 create mode 100644 src/core/hle/kernel/thread.cpp
 create mode 100644 src/core/hle/kernel/thread.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index eb4fef381..3fa5f51f1 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -22,6 +22,8 @@ set(SRCS    core.cpp
             hle/config_mem.cpp
             hle/coprocessor.cpp
             hle/syscall.cpp
+            hle/kernel/kernel.cpp
+            hle/kernel/thread.cpp
             hle/service/apt.cpp
             hle/service/gsp.cpp
             hle/service/hid.cpp
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index b56661e48..59fc6f4fc 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -156,6 +156,8 @@
     <ClCompile Include="hle\config_mem.cpp" />
     <ClCompile Include="hle\coprocessor.cpp" />
     <ClCompile Include="hle\hle.cpp" />
+    <ClCompile Include="hle\kernel\kernel.cpp" />
+    <ClCompile Include="hle\kernel\thread.cpp" />
     <ClCompile Include="hle\service\apt.cpp" />
     <ClCompile Include="hle\service\gsp.cpp" />
     <ClCompile Include="hle\service\hid.cpp" />
@@ -198,6 +200,8 @@
     <ClInclude Include="hle\coprocessor.h" />
     <ClInclude Include="hle\function_wrappers.h" />
     <ClInclude Include="hle\hle.h" />
+    <ClInclude Include="hle\kernel\kernel.h" />
+    <ClInclude Include="hle\kernel\thread.h" />
     <ClInclude Include="hle\service\apt.h" />
     <ClInclude Include="hle\service\gsp.h" />
     <ClInclude Include="hle\service\hid.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 5c947ec23..ff988c116 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -28,6 +28,9 @@
     <Filter Include="hle\service">
       <UniqueIdentifier>{812c5189-ca49-4704-b842-3ffad09092d3}</UniqueIdentifier>
     </Filter>
+    <Filter Include="hle\kernel">
+      <UniqueIdentifier>{f2b132eb-caff-4b04-aaae-88d24393a711}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="arm\disassembler\arm_disasm.cpp">
@@ -114,6 +117,12 @@
     <ClCompile Include="hle\config_mem.cpp">
       <Filter>hle</Filter>
     </ClCompile>
+    <ClCompile Include="hle\kernel\thread.cpp">
+      <Filter>hle\kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\kernel\kernel.cpp">
+      <Filter>hle\kernel</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -223,6 +232,12 @@
     <ClInclude Include="hle\config_mem.h">
       <Filter>hle</Filter>
     </ClInclude>
+    <ClInclude Include="hle\kernel\thread.h">
+      <Filter>hle\kernel</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\kernel\kernel.h">
+      <Filter>hle\kernel</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
new file mode 100644
index 000000000..fc494fe30
--- /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 <string.h>
+
+#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;
+    }
+}
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
new file mode 100644
index 000000000..2381ca7f7
--- /dev/null
+++ b/src/core/hle/kernel/kernel.h
@@ -0,0 +1,121 @@
+// Copyright 2014 Citra Emulator Project / PPSSPP Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common_types.h"
+
+typedef u32 UID;
+
+class KernelObjectPool;
+
+class KernelObject {
+    friend class KernelObjectPool;
+    u32 uid;
+public:
+    virtual ~KernelObject() {}
+    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 void GetQuickInfo(char *ptr, int size);
+};
+
+class KernelObjectPool {
+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);
+
+    static KernelObject *CreateByIDType(int type);
+
+    template <class T>
+    u32 Destroy(UID handle) {
+        u32 error;
+        if (Get<T>(handle, error)) {
+            occupied[handle - handleOffset] = false;
+            delete pool[handle - handleOffset];
+        }
+        return error;
+    };
+
+    bool IsValid(UID handle);
+
+    template <class T>
+    T* Get(UID handle, u32& outError) {
+        if (handle < handleOffset || handle >= handleOffset + maxCount || !occupied[handle - handleOffset]) {
+            // 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);
+            }
+            outError = 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<T*>(pool[handle - handleOffset]);
+            if (t == 0 || t->GetIDType() != T::GetStaticIDType()) {
+                WARN_LOG(SCEKERNEL, "Kernel: Wrong object type for %i (%08x)", handle, handle);
+                outError = T::GetMissingErrorCode();
+                return 0;
+            }
+            outError = SCE_KERNEL_ERROR_OK;
+            return t;
+        }
+    }
+
+    // ONLY use this when you know the handle is valid.
+    template <class T>
+    T *GetFast(UID handle) {
+        const UID realHandle = handle - handleOffset;
+        _dbg_assert_(SCEKERNEL, realHandle >= 0 && realHandle < maxCount && occupied[realHandle]);
+        return static_cast<T *>(pool[realHandle]);
+    }
+
+    template <class T, typename ArgT>
+    void Iterate(bool func(T *, ArgT), ArgT arg) {
+        int type = T::GetStaticIDType();
+        for (int i = 0; i < maxCount; i++)
+        {
+            if (!occupied[i])
+                continue;
+            T *t = static_cast<T *>(pool[i]);
+            if (t->GetIDType() == type) {
+                if (!func(t, arg))
+                    break;
+            }
+        }
+    }
+
+    bool GetIDType(UID 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);
+            return false;
+        }
+        KernelObject *t = pool[handle - HANDLE_OFFSET];
+        *type = t->GetIDType();
+        return true;
+    }
+
+    KernelObject *&operator [](UID 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;
+};
+
+extern KernelObjectPool g_kernel_objects;
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
new file mode 100644
index 000000000..0ed35de83
--- /dev/null
+++ b/src/core/hle/kernel/thread.cpp
@@ -0,0 +1,228 @@
+// Copyright 2014 Citra Emulator Project / PPSSPP Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include <stdio.h>
+
+#include <list>
+#include <vector>
+#include <map>
+#include <string>
+
+#include "common/common.h"
+
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/thread.h"
+
+// Real CTR struct, don't change the fields.
+struct NativeThread {
+    //u32         Pointer to vtable
+    //u32         Reference count
+    //KProcess*   Process the thread belongs to (virtual address)
+    //u32         Thread id
+    //u32*        ptr = *(KThread+0x8C) - 0xB0
+    //u32*        End-address of the page for this thread allocated in the 0xFF4XX000 region. Thus, 
+    //      if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000.
+    //KThread*    Previous ? (virtual address)
+    //KThread*    Next ? (virtual address)
+};
+
+struct ThreadWaitInfo {
+    u32 wait_value;
+    u32 timeout_ptr;
+};
+
+class Thread : public KernelObject {
+public:
+    /*const char *GetName() { return nt.name; }*/
+    const char *GetTypeName() { return "Thread"; }
+    //void GetQuickInfo(char *ptr, int size)
+    //{
+    //    sprintf(ptr, "pc= %08x sp= %08x %s %s %s %s %s %s (wt=%i wid=%i wv= %08x )",
+    //        context.pc, context.r[13], // 13 is stack pointer
+    //        (nt.status & THREADSTATUS_RUNNING) ? "RUN" : "",
+    //        (nt.status & THREADSTATUS_READY) ? "READY" : "",
+    //        (nt.status & THREADSTATUS_WAIT) ? "WAIT" : "",
+    //        (nt.status & THREADSTATUS_SUSPEND) ? "SUSPEND" : "",
+    //        (nt.status & THREADSTATUS_DORMANT) ? "DORMANT" : "",
+    //        (nt.status & THREADSTATUS_DEAD) ? "DEAD" : "",
+    //        nt.waitType,
+    //        nt.waitID,
+    //        waitInfo.waitValue);
+    //}
+
+    //static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; }
+    //static int GetStaticIDType() { return SCE_KERNEL_TMID_Thread; }
+    //int GetIDType() const { return SCE_KERNEL_TMID_Thread; }
+
+    //bool AllocateStack(u32 &stack_size) {
+    //    FreeStack();
+
+    //    bool fromTop = (nt.attr & PSP_THREAD_ATTR_LOW_STACK) == 0;
+    //    if (nt.attr & PSP_THREAD_ATTR_KERNEL)
+    //    {
+    //        // Allocate stacks for kernel threads (idle) in kernel RAM
+    //        currentStack.start = kernelMemory.Alloc(stack_size, fromTop, (std::string("stack/") + nt.name).c_str());
+    //    }
+    //    else
+    //    {
+    //        currentStack.start = userMemory.Alloc(stack_size, fromTop, (std::string("stack/") + nt.name).c_str());
+    //    }
+    //    if (currentStack.start == (u32)-1)
+    //    {
+    //        currentStack.start = 0;
+    //        nt.initialStack = 0;
+    //        ERROR_LOG(KERNEL, "Failed to allocate stack for thread");
+    //        return false;
+    //    }
+
+    //    nt.initialStack = currentStack.start;
+    //    nt.stack_size = stack_size;
+    //    return true;
+    //}
+
+    //bool FillStack() {
+    //    // Fill the stack.
+    //    if ((nt.attr & PSP_THREAD_ATTR_NO_FILLSTACK) == 0) {
+    //        Memory::Memset(currentStack.start, 0xFF, nt.stack_size);
+    //    }
+    //    context.r[MIPS_REG_SP] = currentStack.start + nt.stack_size;
+    //    currentStack.end = context.r[MIPS_REG_SP];
+    //    // The k0 section is 256 bytes at the top of the stack.
+    //    context.r[MIPS_REG_SP] -= 256;
+    //    context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP];
+    //    u32 k0 = context.r[MIPS_REG_K0];
+    //    Memory::Memset(k0, 0, 0x100);
+    //    Memory::Write_U32(GetUID(), k0 + 0xc0);
+    //    Memory::Write_U32(nt.initialStack, k0 + 0xc8);
+    //    Memory::Write_U32(0xffffffff, k0 + 0xf8);
+    //    Memory::Write_U32(0xffffffff, k0 + 0xfc);
+    //    // After k0 comes the arguments, which is done by sceKernelStartThread().
+
+    //    Memory::Write_U32(GetUID(), nt.initialStack);
+    //    return true;
+    //}
+
+    //void FreeStack() {
+    //    if (currentStack.start != 0) {
+    //        DEBUG_LOG(KERNEL, "Freeing thread stack %s", nt.name);
+
+    //        if ((nt.attr & PSP_THREAD_ATTR_CLEAR_STACK) != 0 && nt.initialStack != 0) {
+    //            Memory::Memset(nt.initialStack, 0, nt.stack_size);
+    //        }
+
+    //        if (nt.attr & PSP_THREAD_ATTR_KERNEL) {
+    //            kernelMemory.Free(currentStack.start);
+    //        }
+    //        else {
+    //            userMemory.Free(currentStack.start);
+    //        }
+    //        currentStack.start = 0;
+    //    }
+    //}
+
+    //bool PushExtendedStack(u32 size) {
+    //    u32 stack = userMemory.Alloc(size, true, (std::string("extended/") + nt.name).c_str());
+    //    if (stack == (u32)-1)
+    //        return false;
+
+    //    pushed_stacks.push_back(currentStack);
+    //    currentStack.start = stack;
+    //    currentStack.end = stack + size;
+    //    nt.initialStack = currentStack.start;
+    //    nt.stack_size = currentStack.end - currentStack.start;
+
+    //    // We still drop the threadID at the bottom and fill it, but there's no k0.
+    //    Memory::Memset(currentStack.start, 0xFF, nt.stack_size);
+    //    Memory::Write_U32(GetUID(), nt.initialStack);
+    //    return true;
+    //}
+
+    //bool PopExtendedStack() {
+    //    if (pushed_stacks.size() == 0) {
+    //        return false;
+    //    }
+    //    userMemory.Free(currentStack.start);
+    //    currentStack = pushed_stacks.back();
+    //    pushed_stacks.pop_back();
+    //    nt.initialStack = currentStack.start;
+    //    nt.stack_size = currentStack.end - currentStack.start;
+    //    return true;
+    //}
+
+    Thread() {
+        currentStack.start = 0;
+    }
+
+    // Can't use a destructor since savestates will call that too.
+    //void Cleanup() {
+    //    // Callbacks are automatically deleted when their owning thread is deleted.
+    //    for (auto it = callbacks.begin(), end = callbacks.end(); it != end; ++it)
+    //        kernelObjects.Destroy<Callback>(*it);
+
+    //    if (pushed_stacks.size() != 0)
+    //    {
+    //        WARN_LOG(KERNEL, "Thread ended within an extended stack");
+    //        for (size_t i = 0; i < pushed_stacks.size(); ++i)
+    //            userMemory.Free(pushed_stacks[i].start);
+    //    }
+    //    FreeStack();
+    //}
+
+    void setReturnValue(u32 retval);
+    void setReturnValue(u64 retval);
+    void resumeFromWait();
+    //bool isWaitingFor(WaitType type, int id);
+    //int getWaitID(WaitType type);
+    ThreadWaitInfo getWaitInfo();
+
+    // Utils
+    //inline bool isRunning() const { return (nt.status & THREADSTATUS_RUNNING) != 0; }
+    //inline bool isStopped() const { return (nt.status & THREADSTATUS_DORMANT) != 0; }
+    //inline bool isReady() const { return (nt.status & THREADSTATUS_READY) != 0; }
+    //inline bool isWaiting() const { return (nt.status & THREADSTATUS_WAIT) != 0; }
+    //inline bool isSuspended() const { return (nt.status & THREADSTATUS_SUSPEND) != 0; }
+
+    NativeThread nt;
+
+    ThreadWaitInfo waitInfo;
+    UID moduleId;
+
+    bool isProcessingCallbacks;
+    u32 currentMipscallId;
+    UID currentCallbackId;
+
+    ThreadContext context;
+
+    std::vector<UID> callbacks;
+
+    std::list<u32> pending_calls;
+
+    struct StackInfo {
+        u32 start;
+        u32 end;
+    };
+    // This is a stack of... stacks, since sceKernelExtendThreadStack() can recurse.
+    // These are stacks that aren't "active" right now, but will pop off once the func returns.
+    std::vector<StackInfo> pushed_stacks;
+
+    StackInfo currentStack;
+
+    // For thread end.
+    std::vector<UID> waiting_threads;
+    // Key is the callback id it was for, or if no callback, the thread id.
+    std::map<UID, u64> paused_waits;
+};
+
+void __KernelThreadingInit() {
+}
+
+void __KernelThreadingShutdown() {
+}
+
+//const char *__KernelGetThreadName(UID threadID);
+//
+//void __KernelSaveContext(ThreadContext *ctx);
+//void __KernelLoadContext(ThreadContext *ctx);
+
+//void __KernelSwitchContext(Thread *target, const char *reason);
\ No newline at end of file
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
new file mode 100644
index 000000000..c3cdca31f
--- /dev/null
+++ b/src/core/hle/kernel/thread.h
@@ -0,0 +1,36 @@
+// Copyright 2014 Citra Emulator Project / PPSSPP Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common_types.h"
+
+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
+};
+
+struct ThreadContext {
+    void reset();
+
+    u32 reg[16];
+    u32 cpsr;
+    u32 pc;
+};
+
+void __KernelThreadingInit();
+void __KernelThreadingShutdown();
+
+//const char *__KernelGetThreadName(SceUID threadID);
+//
+//void __KernelSaveContext(ThreadContext *ctx);
+//void __KernelLoadContext(ThreadContext *ctx);
+
+//void __KernelSwitchContext(Thread *target, const char *reason);
\ No newline at end of file

From ce4d271a53e79814f66a46bd69a8970ea3849ee9 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 11 May 2014 22:14:13 -0400
Subject: [PATCH 06/72] added option to set CPSR register to arm_interface

---
 src/core/arm/arm_interface.h                 | 6 ++++++
 src/core/arm/interpreter/arm_interpreter.cpp | 8 ++++++++
 src/core/arm/interpreter/arm_interpreter.h   | 6 ++++++
 3 files changed, 20 insertions(+)

diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 4dfe0570b..602c91e30 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -55,6 +55,12 @@ public:
      */
     virtual u32 GetCPSR() const = 0;  
 
+    /**
+     * Set the current CPSR register
+     * @param cpsr Value to set CPSR to
+     */
+    virtual void SetCPSR(u32 cpsr) = 0;
+
     /**
      * Returns the number of clock ticks since the last rese
      * @return Returns number of clock ticks
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index 4045779d7..81147f2d4 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -77,6 +77,14 @@ u32 ARM_Interpreter::GetCPSR() const {
     return m_state->Cpsr;
 }
 
+/**
+ * Set the current CPSR register
+ * @param cpsr Value to set CPSR to
+ */
+void ARM_Interpreter::SetCPSR(u32 cpsr) {
+    m_state->Cpsr = cpsr;
+}
+
 /**
  * Returns the number of clock ticks since the last reset
  * @return Returns number of clock ticks
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 625c0c652..78b188bee 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -48,6 +48,12 @@ public:
      */
     u32 GetCPSR() const;
 
+    /**
+     * Set the current CPSR register
+     * @param cpsr Value to set CPSR to
+     */
+    void SetCPSR(u32 cpsr);
+
     /**
      * Returns the number of clock ticks since the last reset
      * @return Returns number of clock ticks

From 1583d2b6f32ec6f558646284a8130c0759e93e12 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 21:57:12 -0400
Subject: [PATCH 07/72] - 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index fc494fe30..fb6ae8495 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 2381ca7f7..0eb58210c 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<T>(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 <class T>
     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<T*>(pool[handle - handleOffset]);
+            T* t = static_cast<T*>(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 <class T>
     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<T *>(pool[realHandle]);
     }
 
     template <class T, typename ArgT>
     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);

From b5ef630c9c3133c1452462420788076e9890bcc3 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 21:58:26 -0400
Subject: [PATCH 08/72] added CreateThread, CreateMutex, and ReleaseMutex SVC
 stubs (just parameter decoding for now)

---
 src/core/hle/function_wrappers.h |  2 +-
 src/core/hle/syscall.cpp         | 43 +++++++++++++++++++++++++++-----
 2 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 18b01b14b..83be7648b 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -740,7 +740,7 @@ template<int func(void*, u32, void*, int)> void WrapI_VUVI(){
 }
 
 template<int func(void*, u32, u32, u32, u32, u32)> void WrapI_VUUUUU(){
-    u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), PARAM(2), PARAM(3), PARAM(4), PARAM(5));
+    u32 retval = func(NULL, PARAM(0), PARAM(1), PARAM(2), PARAM(3), PARAM(4));
     RETURN(retval);
 }
 
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index d47df6038..c697bc277 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -10,6 +10,8 @@
 #include "core/hle/syscall.h"
 #include "core/hle/service/service.h"
 
+#include "common/symbols.h"
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace Syscall
 
@@ -26,7 +28,8 @@ enum MapMemoryPermission {
 };
 
 /// Map application or GSP heap memory
-Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) {
+Result ControlMemory(void* _outaddr, u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissions) {
+    u32* outaddr = (u32*)_outaddr;
     u32 virtual_address = 0x00000000;
 
     DEBUG_LOG(SVC, "ControlMemory called operation=0x%08X, addr0=0x%08X, addr1=0x%08X, size=%08X, permissions=0x%08X", 
@@ -48,7 +51,9 @@ Result ControlMemory(u32 operation, u32 addr0, u32 addr1, u32 size, u32 permissi
     default:
         ERROR_LOG(SVC, "ControlMemory unknown operation=0x%08X", operation);
     }
-
+    if (NULL != outaddr) {
+        *outaddr = virtual_address;
+    }
     Core::g_app_core->SetReg(1, virtual_address);
 
     return 0;
@@ -134,16 +139,42 @@ Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void*
     return 0;
 }
 
+Result CreateThread(void* thread, u32 threadpriority, u32 entrypoint, u32 arg, u32 stacktop, u32 processorid) {
+    std::string symbol_name = "unknown";
+    if (Symbols::HasSymbol(entrypoint)) {
+        TSymbol symbol = Symbols::GetSymbol(entrypoint);
+        symbol_name = symbol.name;
+    }
+    // stack top: 0x0056A4A0
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, "
+        "stacktop=0x%08X, threadpriority=0x%08X, processorid=0x%08X", entrypoint, 
+        symbol_name.c_str(), arg, stacktop, threadpriority, processorid);
+
+    return 0;
+}
+
+Result CreateMutex(void* _mutex, u32 initial_locked) {
+    Handle* mutex = (Handle*)_mutex;
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateMutex called initial_locked=%s", 
+        initial_locked ? "true" : "false");
+    return 0;
+}
+
+Result ReleaseMutex(Handle handle) {
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) ReleaseMutex called handle=0x%08X", handle);
+    return 0;
+}
+
 const HLE::FunctionDef Syscall_Table[] = {
     {0x00,  NULL,                                       "Unknown"},
-    {0x01,  WrapI_UUUUU<ControlMemory>,                 "ControlMemory"},
+    {0x01,  WrapI_VUUUUU<ControlMemory>,                "ControlMemory"},
     {0x02,  NULL,                                       "QueryMemory"},
     {0x03,  NULL,                                       "ExitProcess"},
     {0x04,  NULL,                                       "GetProcessAffinityMask"},
     {0x05,  NULL,                                       "SetProcessAffinityMask"},
     {0x06,  NULL,                                       "GetProcessIdealProcessor"},
     {0x07,  NULL,                                       "SetProcessIdealProcessor"},
-    {0x08,  NULL,                                       "CreateThread"},
+    {0x08,  WrapI_VUUUUU<CreateThread>,                 "CreateThread"},
     {0x09,  NULL,                                       "ExitThread"},
     {0x0A,  NULL,                                       "SleepThread"},
     {0x0B,  NULL,                                       "GetThreadPriority"},
@@ -154,8 +185,8 @@ const HLE::FunctionDef Syscall_Table[] = {
     {0x10,  NULL,                                       "SetThreadIdealProcessor"},
     {0x11,  NULL,                                       "GetCurrentProcessorNumber"},
     {0x12,  NULL,                                       "Run"},
-    {0x13,  NULL,                                       "CreateMutex"},
-    {0x14,  NULL,                                       "ReleaseMutex"},
+    {0x13,  WrapI_VU<CreateMutex>,                      "CreateMutex"},
+    {0x14,  WrapI_U<ReleaseMutex>,                      "ReleaseMutex"},
     {0x15,  NULL,                                       "CreateSemaphore"},
     {0x16,  NULL,                                       "ReleaseSemaphore"},
     {0x17,  NULL,                                       "CreateEvent"},

From b87536e82cc1708d22ce4e38b34dac8190919798 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 21:58:51 -0400
Subject: [PATCH 09/72] changed loader to use __KernelLoadExec

---
 src/core/loader.cpp | 17 +++++++++--------
 1 file changed, 9 insertions(+), 8 deletions(-)

diff --git a/src/core/loader.cpp b/src/core/loader.cpp
index 8756588ae..a1f5dcdb5 100644
--- a/src/core/loader.cpp
+++ b/src/core/loader.cpp
@@ -10,7 +10,7 @@
 #include "core/core.h"
 #include "core/file_sys/directory_file_system.h"
 #include "core/elf/elf_reader.h"
-
+#include "core/hle/kernel/kernel.h"
 #include "core/mem_map.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -56,7 +56,7 @@ bool Load_ELF(std::string &filename) {
         elf_reader = new ElfReader(buffer);
         elf_reader->LoadInto(0x00100000);
 
-        Core::g_app_core->SetPC(elf_reader->GetEntryPoint());
+        __KernelLoadExec(elf_reader->GetEntryPoint());
 
         delete[] buffer;
         delete elf_reader;
@@ -89,11 +89,11 @@ bool Load_DAT(std::string &filename) {
         * but for the sake of making it easier... we'll temporarily/hackishly
         * allow it. No sense in making a proper reader for this.
         */
-        u32 entrypoint = 0x00100000; // write to same entrypoint as elf
+        u32 entry_point = 0x00100000; // write to same entrypoint as elf
         u32 payload_offset = 0xA150;
         
         const u8 *src = &buffer[payload_offset];
-        u8 *dst = Memory::GetPointer(entrypoint);
+        u8 *dst = Memory::GetPointer(entry_point);
         u32 srcSize = size - payload_offset; //just load everything...
         u32 *s = (u32*)src;
         u32 *d = (u32*)dst;
@@ -102,7 +102,8 @@ bool Load_DAT(std::string &filename) {
             *d++ = (*s++);
         }
         
-        Core::g_app_core->SetPC(entrypoint);
+        __KernelLoadExec(entry_point);
+
 
         delete[] buffer;
     }
@@ -131,10 +132,10 @@ bool Load_BIN(std::string &filename) {
 
         f.ReadBytes(buffer, size);
 
-        u32 entrypoint = 0x00100000; // Hardcoded, read from exheader
+        u32 entry_point = 0x00100000; // Hardcoded, read from exheader
         
         const u8 *src = buffer;
-        u8 *dst = Memory::GetPointer(entrypoint);
+        u8 *dst = Memory::GetPointer(entry_point);
         u32 srcSize = size;
         u32 *s = (u32*)src;
         u32 *d = (u32*)dst;
@@ -143,7 +144,7 @@ bool Load_BIN(std::string &filename) {
             *d++ = (*s++);
         }
         
-        Core::g_app_core->SetPC(entrypoint);
+        __KernelLoadExec(entry_point);
 
         delete[] buffer;
     }

From 3838d46b9022964617b93a45f3feab5052c3538b Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 22:00:11 -0400
Subject: [PATCH 10/72] added a bunch of threading code, recycled from PPSSPP,
 with lots of hacks in for 3DS... doesn't really do much yet. Just a jumping
 off point

---
 src/core/hle/kernel/thread.cpp | 586 +++++++++++++++++++++++++++++----
 src/core/hle/kernel/thread.h   |  25 +-
 2 files changed, 542 insertions(+), 69 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 0ed35de83..584276eec 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -11,10 +11,212 @@
 
 #include "common/common.h"
 
+#include "core/core.h"
+#include "core/mem_map.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/thread.h"
 
-// Real CTR struct, don't change the fields.
+struct ThreadQueueList {
+    // Number of queues (number of priority levels starting at 0.)
+    static const int NUM_QUEUES = 128;
+    // Initial number of threads a single queue can handle.
+    static const int INITIAL_CAPACITY = 32;
+
+    struct Queue {
+        // Next ever-been-used queue (worse priority.)
+        Queue *next;
+        // First valid item in data.
+        int first;
+        // One after last valid item in data.
+        int end;
+        // A too-large array with room on the front and end.
+        UID *data;
+        // Size of data array.
+        int capacity;
+    };
+
+    ThreadQueueList() {
+        memset(queues, 0, sizeof(queues));
+        first = invalid();
+    }
+
+    ~ThreadQueueList() {
+        for (int i = 0; i < NUM_QUEUES; ++i) {
+            if (queues[i].data != NULL) {
+                free(queues[i].data);
+            }
+        }
+    }
+
+    // Only for debugging, returns priority level.
+    int contains(const UID uid) {
+        for (int i = 0; i < NUM_QUEUES; ++i) {
+            if (queues[i].data == NULL) {
+                continue;
+            }
+            Queue *cur = &queues[i];
+            for (int j = cur->first; j < cur->end; ++j) {
+                if (cur->data[j] == uid) {
+                    return i;
+                }
+            }
+        }
+        return -1;
+    }
+
+    inline UID pop_first() {
+        Queue *cur = first;
+        while (cur != invalid()) {
+            if (cur->end - cur->first > 0) {
+                return cur->data[cur->first++];
+            }
+            cur = cur->next;
+        }
+
+        _dbg_assert_msg_(KERNEL, false, "ThreadQueueList should not be empty.");
+        return 0;
+    }
+
+    inline UID pop_first_better(u32 priority) {
+        Queue *cur = first;
+        Queue *stop = &queues[priority];
+        while (cur < stop) {
+            if (cur->end - cur->first > 0) {
+                return cur->data[cur->first++];
+            }
+            cur = cur->next;
+        }
+        return 0;
+    }
+
+    inline void push_front(u32 priority, const UID thread_id) {
+        Queue *cur = &queues[priority];
+        cur->data[--cur->first] = thread_id;
+        if (cur->first == 0) {
+            rebalance(priority);
+        }
+    }
+
+    inline void push_back(u32 priority, const UID thread_id)
+    {
+        Queue *cur = &queues[priority];
+        cur->data[cur->end++] = thread_id;
+        if (cur->end == cur->capacity) {
+            rebalance(priority);
+        }
+    }
+
+    inline void remove(u32 priority, const UID thread_id) {
+        Queue *cur = &queues[priority];
+        _dbg_assert_msg_(KERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
+
+        for (int i = cur->first; i < cur->end; ++i) {
+            if (cur->data[i] == thread_id) {
+                int remaining = --cur->end - i;
+                if (remaining > 0) {
+                    memmove(&cur->data[i], &cur->data[i + 1], remaining * sizeof(UID));
+                }
+                return;
+            }
+        }
+
+        // Wasn't there.
+    }
+
+    inline void rotate(u32 priority) {
+        Queue *cur = &queues[priority];
+        _dbg_assert_msg_(KERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
+
+        if (cur->end - cur->first > 1) {
+            cur->data[cur->end++] = cur->data[cur->first++];
+            if (cur->end == cur->capacity) {
+                rebalance(priority);
+            }
+        }
+    }
+
+    inline void clear() {
+        for (int i = 0; i < NUM_QUEUES; ++i) {
+            if (queues[i].data != NULL) {
+                free(queues[i].data);
+            }
+        }
+        memset(queues, 0, sizeof(queues));
+        first = invalid();
+    }
+
+    inline bool empty(u32 priority) const {
+        const Queue *cur = &queues[priority];
+        return cur->first == cur->end;
+    }
+
+    inline void prepare(u32 priority) {
+        Queue *cur = &queues[priority];
+        if (cur->next == NULL) {
+            link(priority, INITIAL_CAPACITY);
+        }
+    }
+
+private:
+    Queue *invalid() const {
+        return (Queue *)-1;
+    }
+
+    void link(u32 priority, int size) {
+        _dbg_assert_msg_(KERNEL, queues[priority].data == NULL, "ThreadQueueList::Queue should only be initialized once.");
+
+        if (size <= INITIAL_CAPACITY) {
+            size = INITIAL_CAPACITY;
+        } else {
+            int goal = size;
+            size = INITIAL_CAPACITY;
+            while (size < goal)
+                size *= 2;
+        }
+        Queue *cur = &queues[priority];
+        cur->data = (UID*)malloc(sizeof(UID)* size);
+        cur->capacity = size;
+        cur->first = size / 2;
+        cur->end = size / 2;
+
+        for (int i = (int)priority - 1; i >= 0; --i) {
+            if (queues[i].next != NULL) {
+                cur->next = queues[i].next;
+                queues[i].next = cur;
+                return;
+            }
+        }
+
+        cur->next = first;
+        first = cur;
+    }
+
+    void rebalance(u32 priority) {
+        Queue *cur = &queues[priority];
+        int size = cur->end - cur->first;
+        if (size >= cur->capacity - 2) {
+            UID* new_data = (UID*)realloc(cur->data, cur->capacity * 2 * sizeof(UID));
+            if (new_data != NULL) {
+                cur->capacity *= 2;
+                cur->data = new_data;
+            }
+        }
+
+        int newFirst = (cur->capacity - size) / 2;
+        if (newFirst != cur->first) {
+            memmove(&cur->data[newFirst], &cur->data[cur->first], size * sizeof(UID));
+            cur->first = newFirst;
+            cur->end = newFirst + size;
+        }
+    }
+
+    // The first queue that's ever been used.
+    Queue* first;
+    // The priority level queues of thread ids.
+    Queue queues[NUM_QUEUES];
+};
+
+// Supposed to represent a real CTR struct... but not sure of the correct fields yet.
 struct NativeThread {
     //u32         Pointer to vtable
     //u32         Reference count
@@ -25,6 +227,22 @@ struct NativeThread {
     //      if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000.
     //KThread*    Previous ? (virtual address)
     //KThread*    Next ? (virtual address)
+
+    u32_le native_size;
+    char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
+
+    // Threading stuff
+    u32_le status;
+    u32_le entry_point;
+    u32_le initial_stack;
+    u32_le stack_top;
+    u32_le stack_size;
+    
+    u32_le arg;
+    u32_le processor_id;
+
+    s32_le initial_priority;
+    s32_le current_priority;
 };
 
 struct ThreadWaitInfo {
@@ -52,42 +270,23 @@ public:
     //}
 
     //static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; }
-    //static int GetStaticIDType() { return SCE_KERNEL_TMID_Thread; }
-    //int GetIDType() const { return SCE_KERNEL_TMID_Thread; }
+    static KernelIDType GetStaticIDType() { return KERNEL_ID_TYPE_THREAD; }
+    KernelIDType GetIDType() const { return KERNEL_ID_TYPE_THREAD; }
 
-    //bool AllocateStack(u32 &stack_size) {
-    //    FreeStack();
-
-    //    bool fromTop = (nt.attr & PSP_THREAD_ATTR_LOW_STACK) == 0;
-    //    if (nt.attr & PSP_THREAD_ATTR_KERNEL)
-    //    {
-    //        // Allocate stacks for kernel threads (idle) in kernel RAM
-    //        currentStack.start = kernelMemory.Alloc(stack_size, fromTop, (std::string("stack/") + nt.name).c_str());
-    //    }
-    //    else
-    //    {
-    //        currentStack.start = userMemory.Alloc(stack_size, fromTop, (std::string("stack/") + nt.name).c_str());
-    //    }
-    //    if (currentStack.start == (u32)-1)
-    //    {
-    //        currentStack.start = 0;
-    //        nt.initialStack = 0;
-    //        ERROR_LOG(KERNEL, "Failed to allocate stack for thread");
-    //        return false;
-    //    }
-
-    //    nt.initialStack = currentStack.start;
-    //    nt.stack_size = stack_size;
-    //    return true;
-    //}
+    bool SetupStack(u32 stack_top, int stack_size) {
+        current_stack.start = stack_top; 
+        nt.initial_stack = current_stack.start;
+        nt.stack_size = stack_size;
+        return true;
+    }
 
     //bool FillStack() {
     //    // Fill the stack.
     //    if ((nt.attr & PSP_THREAD_ATTR_NO_FILLSTACK) == 0) {
-    //        Memory::Memset(currentStack.start, 0xFF, nt.stack_size);
+    //        Memory::Memset(current_stack.start, 0xFF, nt.stack_size);
     //    }
-    //    context.r[MIPS_REG_SP] = currentStack.start + nt.stack_size;
-    //    currentStack.end = context.r[MIPS_REG_SP];
+    //    context.r[MIPS_REG_SP] = current_stack.start + nt.stack_size;
+    //    current_stack.end = context.r[MIPS_REG_SP];
     //    // The k0 section is 256 bytes at the top of the stack.
     //    context.r[MIPS_REG_SP] -= 256;
     //    context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP];
@@ -104,7 +303,7 @@ public:
     //}
 
     //void FreeStack() {
-    //    if (currentStack.start != 0) {
+    //    if (current_stack.start != 0) {
     //        DEBUG_LOG(KERNEL, "Freeing thread stack %s", nt.name);
 
     //        if ((nt.attr & PSP_THREAD_ATTR_CLEAR_STACK) != 0 && nt.initialStack != 0) {
@@ -112,12 +311,12 @@ public:
     //        }
 
     //        if (nt.attr & PSP_THREAD_ATTR_KERNEL) {
-    //            kernelMemory.Free(currentStack.start);
+    //            kernelMemory.Free(current_stack.start);
     //        }
     //        else {
-    //            userMemory.Free(currentStack.start);
+    //            userMemory.Free(current_stack.start);
     //        }
-    //        currentStack.start = 0;
+    //        current_stack.start = 0;
     //    }
     //}
 
@@ -126,14 +325,14 @@ public:
     //    if (stack == (u32)-1)
     //        return false;
 
-    //    pushed_stacks.push_back(currentStack);
-    //    currentStack.start = stack;
-    //    currentStack.end = stack + size;
-    //    nt.initialStack = currentStack.start;
-    //    nt.stack_size = currentStack.end - currentStack.start;
+    //    pushed_stacks.push_back(current_stack);
+    //    current_stack.start = stack;
+    //    current_stack.end = stack + size;
+    //    nt.initialStack = current_stack.start;
+    //    nt.stack_size = current_stack.end - current_stack.start;
 
-    //    // We still drop the threadID at the bottom and fill it, but there's no k0.
-    //    Memory::Memset(currentStack.start, 0xFF, nt.stack_size);
+    //    // We still drop the thread_id at the bottom and fill it, but there's no k0.
+    //    Memory::Memset(current_stack.start, 0xFF, nt.stack_size);
     //    Memory::Write_U32(GetUID(), nt.initialStack);
     //    return true;
     //}
@@ -142,16 +341,16 @@ public:
     //    if (pushed_stacks.size() == 0) {
     //        return false;
     //    }
-    //    userMemory.Free(currentStack.start);
-    //    currentStack = pushed_stacks.back();
+    //    userMemory.Free(current_stack.start);
+    //    current_stack = pushed_stacks.back();
     //    pushed_stacks.pop_back();
-    //    nt.initialStack = currentStack.start;
-    //    nt.stack_size = currentStack.end - currentStack.start;
+    //    nt.initialStack = current_stack.start;
+    //    nt.stack_size = current_stack.end - current_stack.start;
     //    return true;
     //}
 
     Thread() {
-        currentStack.start = 0;
+        current_stack.start = 0;
     }
 
     // Can't use a destructor since savestates will call that too.
@@ -177,20 +376,20 @@ public:
     ThreadWaitInfo getWaitInfo();
 
     // Utils
-    //inline bool isRunning() const { return (nt.status & THREADSTATUS_RUNNING) != 0; }
-    //inline bool isStopped() const { return (nt.status & THREADSTATUS_DORMANT) != 0; }
-    //inline bool isReady() const { return (nt.status & THREADSTATUS_READY) != 0; }
-    //inline bool isWaiting() const { return (nt.status & THREADSTATUS_WAIT) != 0; }
-    //inline bool isSuspended() const { return (nt.status & THREADSTATUS_SUSPEND) != 0; }
+    inline bool IsRunning() const { return (nt.status & THREADSTATUS_RUNNING) != 0; }
+    inline bool IsStopped() const { return (nt.status & THREADSTATUS_DORMANT) != 0; }
+    inline bool IsReady() const { return (nt.status & THREADSTATUS_READY) != 0; }
+    inline bool IsWaiting() const { return (nt.status & THREADSTATUS_WAIT) != 0; }
+    inline bool IsSuspended() const { return (nt.status & THREADSTATUS_SUSPEND) != 0; }
 
     NativeThread nt;
 
     ThreadWaitInfo waitInfo;
     UID moduleId;
 
-    bool isProcessingCallbacks;
-    u32 currentMipscallId;
-    UID currentCallbackId;
+    //bool isProcessingCallbacks;
+    //u32 currentMipscallId;
+    //UID currentCallbackId;
 
     ThreadContext context;
 
@@ -206,7 +405,7 @@ public:
     // These are stacks that aren't "active" right now, but will pop off once the func returns.
     std::vector<StackInfo> pushed_stacks;
 
-    StackInfo currentStack;
+    StackInfo current_stack;
 
     // For thread end.
     std::vector<UID> waiting_threads;
@@ -214,15 +413,276 @@ public:
     std::map<UID, u64> paused_waits;
 };
 
+void ThreadContext::reset() {
+    for (int i = 0; i < 16; i++) {
+        reg[i] = 0;
+    }
+    reg[13] = Memory::SCRATCHPAD_VADDR_END;
+    cpsr = 0;
+}
+
+// Lists all thread ids that aren't deleted/etc.
+std::vector<UID> g_thread_queue;
+
+// Lists only ready thread ids
+ThreadQueueList g_thread_ready_queue;
+
+UID g_current_thread;
+Thread* g_current_thread_ptr;
+const char *g_hle_current_thread_name = NULL;
+
+Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, 
+    u32 entrypoint, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
+
+    Thread *t = new Thread;
+    id = g_kernel_objects.Create(t);
+
+    g_thread_queue.push_back(id);
+    g_thread_ready_queue.prepare(priority);
+
+    memset(&t->nt, 0xCD, sizeof(t->nt));
+
+    t->nt.entry_point = entrypoint;
+    t->nt.native_size = sizeof(t->nt);
+    t->nt.initial_priority = t->nt.current_priority = priority;
+    t->nt.status = THREADSTATUS_DORMANT;
+    t->nt.initial_stack = t->nt.stack_top = stack_top;
+    t->nt.stack_size = stack_size;
+    t->nt.processor_id = processor_id;
+
+    strncpy(t->nt.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
+    t->nt.name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
+
+    t->nt.stack_size = stack_size;
+    t->SetupStack(stack_top, stack_size);
+
+    return t;
+}
+
+void __KernelResetThread(Thread *t, int lowest_priority) {
+    t->context.reset();
+    t->context.pc = t->nt.entry_point;
+
+    // If the thread would be better than lowestPriority, reset to its initial.  Yes, kinda odd...
+    if (t->nt.current_priority < lowest_priority)
+        t->nt.current_priority = t->nt.initial_priority;
+
+    //t->nt.wait_type = WAITTYPE_NONE;
+    //t->nt.wait_id = 0;
+    memset(&t->waitInfo, 0, sizeof(t->waitInfo));
+
+    //t->nt.exitStatus = SCE_KERNEL_ERROR_NOT_DORMANT;
+    //t->isProcessingCallbacks = false;
+    //t->currentCallbackId = 0;
+    //t->currentMipscallId = 0;
+    //t->pendingMipsCalls.clear();
+
+    //t->context.r[MIPS_REG_RA] = threadReturnHackAddr; //hack! TODO fix
+    // TODO: Not sure if it's reset here, but this makes sense.
+    //t->context.r[MIPS_REG_GP] = t->nt.gpreg;
+    //t->FillStack();
+
+    //if (!t->waitingThreads.empty())
+    //    ERROR_LOG(KERNEL, "Resetting thread with threads waiting on end?");
+}
+
+
+inline Thread *__GetCurrentThread() {
+    return g_current_thread_ptr;
+}
+
+inline void __SetCurrentThread(Thread *thread, UID thread_id, const char *name) {
+    g_current_thread = thread_id;
+    g_current_thread_ptr = thread;
+    g_hle_current_thread_name = name;
+}
+
+// TODO: Use __KernelChangeThreadState instead?  It has other affects...
+void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready) {
+    // Passing the id as a parameter is just an optimization, if it's wrong it will cause havoc.
+    _dbg_assert_msg_(KERNEL, thread->GetUID() == thread_id, "Incorrect thread_id");
+    int prio = thread->nt.current_priority;
+
+    if (thread->IsReady()) {
+        if (!ready)
+            g_thread_ready_queue.remove(prio, thread_id);
+    } else if (ready) {
+        if (thread->IsRunning()) {
+            g_thread_ready_queue.push_front(prio, thread_id);
+        } else {
+            g_thread_ready_queue.push_back(prio, thread_id);
+        }
+        thread->nt.status = THREADSTATUS_READY;
+    }
+}
+
+void __KernelChangeReadyState(UID thread_id, bool ready) {
+    u32 error;
+    Thread *thread = g_kernel_objects.Get<Thread>(thread_id, error);
+    if (thread) {
+        __KernelChangeReadyState(thread, thread_id, ready);
+    } else {
+        WARN_LOG(KERNEL, "Trying to change the ready state of an unknown thread?");
+    }
+}
+
+// Returns NULL if the current thread is fine.
+Thread* __KernelNextThread() {
+    UID bestThread;
+
+    // If the current thread is running, it's a valid candidate.
+    Thread *cur = __GetCurrentThread();
+    if (cur && cur->IsRunning()) {
+        bestThread = g_thread_ready_queue.pop_first_better(cur->nt.current_priority);
+        if (bestThread != 0) {
+            __KernelChangeReadyState(cur, g_current_thread, true);
+        }
+    } else {
+        bestThread = g_thread_ready_queue.pop_first();
+    }
+
+    // Assume g_thread_ready_queue has not become corrupt.
+    if (bestThread != 0) {
+        return g_kernel_objects.GetFast<Thread>(bestThread);
+    } else {
+        return NULL;
+    }
+}
+
+// Saves the current CPU context
+void __KernelSaveContext(ThreadContext *ctx) {
+    ctx->reg[0] = Core::g_app_core->GetReg(0);
+    ctx->reg[1] = Core::g_app_core->GetReg(1);
+    ctx->reg[2] = Core::g_app_core->GetReg(2);
+    ctx->reg[3] = Core::g_app_core->GetReg(3);
+    ctx->reg[4] = Core::g_app_core->GetReg(4);
+    ctx->reg[5] = Core::g_app_core->GetReg(5);
+    ctx->reg[6] = Core::g_app_core->GetReg(6);
+    ctx->reg[7] = Core::g_app_core->GetReg(7);
+    ctx->reg[8] = Core::g_app_core->GetReg(8);
+    ctx->reg[9] = Core::g_app_core->GetReg(9);
+    ctx->reg[10] = Core::g_app_core->GetReg(10);
+    ctx->reg[11] = Core::g_app_core->GetReg(11);
+    ctx->reg[12] = Core::g_app_core->GetReg(12);
+    ctx->reg[13] = Core::g_app_core->GetReg(13);
+    ctx->reg[14] = Core::g_app_core->GetReg(14);
+    ctx->reg[15] = Core::g_app_core->GetReg(15);
+    ctx->pc = Core::g_app_core->GetPC();
+    ctx->cpsr = Core::g_app_core->GetCPSR();
+}
+
+// Loads a CPU context
+void __KernelLoadContext(ThreadContext *ctx) {
+    Core::g_app_core->SetReg(0, ctx->reg[0]);
+    Core::g_app_core->SetReg(1, ctx->reg[1]);
+    Core::g_app_core->SetReg(2, ctx->reg[2]);
+    Core::g_app_core->SetReg(3, ctx->reg[3]);
+    Core::g_app_core->SetReg(4, ctx->reg[4]);
+    Core::g_app_core->SetReg(5, ctx->reg[5]);
+    Core::g_app_core->SetReg(6, ctx->reg[6]);
+    Core::g_app_core->SetReg(7, ctx->reg[7]);
+    Core::g_app_core->SetReg(8, ctx->reg[8]);
+    Core::g_app_core->SetReg(9, ctx->reg[9]);
+    Core::g_app_core->SetReg(10, ctx->reg[10]);
+    Core::g_app_core->SetReg(11, ctx->reg[11]);
+    Core::g_app_core->SetReg(12, ctx->reg[12]);
+    Core::g_app_core->SetReg(13, ctx->reg[13]);
+    Core::g_app_core->SetReg(14, ctx->reg[14]);
+    Core::g_app_core->SetReg(15, ctx->reg[15]);
+    Core::g_app_core->SetPC(ctx->pc);
+    Core::g_app_core->SetCPSR(ctx->cpsr);
+}
+
+void __KernelSwitchContext(Thread *target, const char *reason) {
+    u32 oldPC = 0;
+    UID oldUID = 0;
+    const char *oldName = g_hle_current_thread_name != NULL ? g_hle_current_thread_name : "(none)";
+
+    Thread *cur = __GetCurrentThread();
+    if (cur) { // It might just have been deleted.
+        __KernelSaveContext(&cur->context);
+        oldPC = Core::g_app_core->GetPC();
+        oldUID = cur->GetUID();
+
+        // Normally this is taken care of in __KernelNextThread().
+        if (cur->IsRunning())
+            __KernelChangeReadyState(cur, oldUID, true);
+    }
+
+    if (target) {
+        __SetCurrentThread(target, target->GetUID(), target->nt.name);
+        __KernelChangeReadyState(target, g_current_thread, false);
+        target->nt.status = (target->nt.status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
+
+        __KernelLoadContext(&target->context);
+    } else {
+        __SetCurrentThread(NULL, 0, NULL);
+    }
+
+#if DEBUG_LEVEL <= MAX_LOGLEVEL || DEBUG_LOG == NOTICE_LOG
+    //bool fromIdle = oldUID == threadIdleID[0] || oldUID == threadIdleID[1];
+    //bool toIdle = currentThread == threadIdleID[0] || currentThread == threadIdleID[1];
+    //if (!(fromIdle && toIdle))
+    //{
+    //    u64 nowCycles = CoreTiming::GetTicks();
+    //    s64 consumedCycles = nowCycles - lastSwitchCycles;
+    //    lastSwitchCycles = nowCycles;
+
+    //    DEBUG_LOG(SCEKERNEL, "Context switch: %s -> %s (%i->%i, pc: %08x->%08x, %s) +%lldus",
+    //        oldName, hleCurrentThreadName,
+    //        oldUID, currentThread,
+    //        oldPC, currentMIPS->pc,
+    //        reason,
+    //        cyclesToUs(consumedCycles));
+    //}
+#endif
+
+    if (target) {
+        //// No longer waiting.
+        //target->nt.waitType = WAITTYPE_NONE;
+        //target->nt.waitID = 0;
+
+        //__KernelExecutePendingARMCalls(target, true);
+    }
+}
+
+UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
+    UID id;
+
+    Thread *thread = __KernelCreateThread(id, module_id, "root", prio, Core::g_app_core->GetPC(),
+        arg, Memory::SCRATCHPAD_VADDR_END, 0xFFFFFFFE, stack_size=stack_size);
+
+    if (thread->current_stack.start == 0) {
+        ERROR_LOG(KERNEL, "Unable to allocate stack for root thread.");
+    }
+    __KernelResetThread(thread, 0);
+
+    Thread *prev_thread = __GetCurrentThread();
+    if (prev_thread && prev_thread->IsRunning())
+        __KernelChangeReadyState(g_current_thread, true);
+    __SetCurrentThread(thread, id, "root");
+    thread->nt.status = THREADSTATUS_RUNNING; // do not schedule
+
+    strcpy(thread->nt.name, "root");
+
+    __KernelLoadContext(&thread->context);
+    
+    // NOTE(bunnei): Not sure this is really correct, ignore args for now...
+    //Core::g_app_core->SetReg(0, args); 
+    //Core::g_app_core->SetReg(13, (args + 0xf) & ~0xf); // Setup SP - probably not correct
+    //u32 location = Core::g_app_core->GetReg(13); // SP
+    //Core::g_app_core->SetReg(1, location);
+    
+    //if (argp)
+    //    Memory::Memcpy(location, argp, args);
+    //// Let's assume same as starting a new thread, 64 bytes for safety/kernel.
+    //Core::g_app_core->SetReg(13, Core::g_app_core->GetReg(13) - 64);
+
+    return id;
+}
+
 void __KernelThreadingInit() {
 }
 
 void __KernelThreadingShutdown() {
 }
-
-//const char *__KernelGetThreadName(UID threadID);
-//
-//void __KernelSaveContext(ThreadContext *ctx);
-//void __KernelLoadContext(ThreadContext *ctx);
-
-//void __KernelSwitchContext(Thread *target, const char *reason);
\ No newline at end of file
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index c3cdca31f..38180cb9b 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -7,12 +7,12 @@
 #include "common/common_types.h"
 
 enum ThreadStatus {
-    THREADSTATUS_RUNNING = 1,
-    THREADSTATUS_READY = 2,
-    THREADSTATUS_WAIT = 4,
-    THREADSTATUS_SUSPEND = 8,
-    THREADSTATUS_DORMANT = 16,
-    THREADSTATUS_DEAD = 32,
+    THREADSTATUS_RUNNING    = 1,
+    THREADSTATUS_READY      = 2,
+    THREADSTATUS_WAIT       = 4,
+    THREADSTATUS_SUSPEND    = 8,
+    THREADSTATUS_DORMANT    = 16,
+    THREADSTATUS_DEAD       = 32,
 
     THREADSTATUS_WAITSUSPEND = THREADSTATUS_WAIT | THREADSTATUS_SUSPEND
 };
@@ -25,6 +25,19 @@ struct ThreadContext {
     u32 pc;
 };
 
+class Thread;
+
+Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint,
+    u32 arg, u32 stack_top, u32 processor_id, int stack_size=0x4000);
+void __KernelResetThread(Thread *t, int lowest_priority);
+void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready);
+void __KernelChangeReadyState(UID thread_id, bool ready);
+Thread* __KernelNextThread();
+void __KernelSaveContext(ThreadContext *ctx);
+void __KernelLoadContext(ThreadContext *ctx);
+void __KernelSwitchContext(Thread *target, const char *reason);
+UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000);
+
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();
 

From 7d078189daec2db8a465a401b6867739fea5043d Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 22:29:31 -0400
Subject: [PATCH 11/72] various cleanups / remove unused code

---
 src/core/hle/kernel/thread.cpp | 93 ++++++++++------------------------
 src/core/hle/kernel/thread.h   |  1 +
 2 files changed, 29 insertions(+), 65 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 584276eec..95ef2c173 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -427,10 +427,11 @@ std::vector<UID> g_thread_queue;
 // Lists only ready thread ids
 ThreadQueueList g_thread_ready_queue;
 
-UID g_current_thread;
-Thread* g_current_thread_ptr;
-const char *g_hle_current_thread_name = NULL;
+UID         g_current_thread            = 0;
+Thread*     g_current_thread_ptr        = NULL;
+const char* g_hle_current_thread_name   = NULL;
 
+/// Creates a new thread
 Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, 
     u32 entrypoint, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
 
@@ -459,38 +460,25 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
     return t;
 }
 
+/// Resets the specified thread back to initial calling state
 void __KernelResetThread(Thread *t, int lowest_priority) {
     t->context.reset();
     t->context.pc = t->nt.entry_point;
 
     // If the thread would be better than lowestPriority, reset to its initial.  Yes, kinda odd...
-    if (t->nt.current_priority < lowest_priority)
+    if (t->nt.current_priority < lowest_priority) {
         t->nt.current_priority = t->nt.initial_priority;
+    }
 
-    //t->nt.wait_type = WAITTYPE_NONE;
-    //t->nt.wait_id = 0;
     memset(&t->waitInfo, 0, sizeof(t->waitInfo));
-
-    //t->nt.exitStatus = SCE_KERNEL_ERROR_NOT_DORMANT;
-    //t->isProcessingCallbacks = false;
-    //t->currentCallbackId = 0;
-    //t->currentMipscallId = 0;
-    //t->pendingMipsCalls.clear();
-
-    //t->context.r[MIPS_REG_RA] = threadReturnHackAddr; //hack! TODO fix
-    // TODO: Not sure if it's reset here, but this makes sense.
-    //t->context.r[MIPS_REG_GP] = t->nt.gpreg;
-    //t->FillStack();
-
-    //if (!t->waitingThreads.empty())
-    //    ERROR_LOG(KERNEL, "Resetting thread with threads waiting on end?");
 }
 
-
+/// Returns the current executing thread
 inline Thread *__GetCurrentThread() {
     return g_current_thread_ptr;
 }
 
+/// Sets the current executing thread
 inline void __SetCurrentThread(Thread *thread, UID thread_id, const char *name) {
     g_current_thread = thread_id;
     g_current_thread_ptr = thread;
@@ -526,30 +514,29 @@ void __KernelChangeReadyState(UID thread_id, bool ready) {
     }
 }
 
-// Returns NULL if the current thread is fine.
+/// Returns NULL if the current thread is fine.
 Thread* __KernelNextThread() {
-    UID bestThread;
+    UID best_thread;
 
     // If the current thread is running, it's a valid candidate.
     Thread *cur = __GetCurrentThread();
     if (cur && cur->IsRunning()) {
-        bestThread = g_thread_ready_queue.pop_first_better(cur->nt.current_priority);
-        if (bestThread != 0) {
+        best_thread = g_thread_ready_queue.pop_first_better(cur->nt.current_priority);
+        if (best_thread != 0) {
             __KernelChangeReadyState(cur, g_current_thread, true);
         }
     } else {
-        bestThread = g_thread_ready_queue.pop_first();
+        best_thread = g_thread_ready_queue.pop_first();
     }
-
     // Assume g_thread_ready_queue has not become corrupt.
-    if (bestThread != 0) {
-        return g_kernel_objects.GetFast<Thread>(bestThread);
+    if (best_thread != 0) {
+        return g_kernel_objects.GetFast<Thread>(best_thread);
     } else {
         return NULL;
     }
 }
 
-// Saves the current CPU context
+/// Saves the current CPU context
 void __KernelSaveContext(ThreadContext *ctx) {
     ctx->reg[0] = Core::g_app_core->GetReg(0);
     ctx->reg[1] = Core::g_app_core->GetReg(1);
@@ -571,7 +558,7 @@ void __KernelSaveContext(ThreadContext *ctx) {
     ctx->cpsr = Core::g_app_core->GetCPSR();
 }
 
-// Loads a CPU context
+/// Loads a CPU context
 void __KernelLoadContext(ThreadContext *ctx) {
     Core::g_app_core->SetReg(0, ctx->reg[0]);
     Core::g_app_core->SetReg(1, ctx->reg[1]);
@@ -593,59 +580,35 @@ void __KernelLoadContext(ThreadContext *ctx) {
     Core::g_app_core->SetCPSR(ctx->cpsr);
 }
 
+/// Switches thread context
 void __KernelSwitchContext(Thread *target, const char *reason) {
-    u32 oldPC = 0;
-    UID oldUID = 0;
-    const char *oldName = g_hle_current_thread_name != NULL ? g_hle_current_thread_name : "(none)";
-
+    u32 old_pc = 0;
+    UID old_uid = 0;
+    const char *old_name = g_hle_current_thread_name != NULL ? g_hle_current_thread_name : "(none)";
     Thread *cur = __GetCurrentThread();
+
     if (cur) { // It might just have been deleted.
         __KernelSaveContext(&cur->context);
-        oldPC = Core::g_app_core->GetPC();
-        oldUID = cur->GetUID();
+        old_pc = Core::g_app_core->GetPC();
+        old_uid = cur->GetUID();
 
         // Normally this is taken care of in __KernelNextThread().
         if (cur->IsRunning())
-            __KernelChangeReadyState(cur, oldUID, true);
+            __KernelChangeReadyState(cur, old_uid, true);
     }
-
     if (target) {
         __SetCurrentThread(target, target->GetUID(), target->nt.name);
         __KernelChangeReadyState(target, g_current_thread, false);
+
         target->nt.status = (target->nt.status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
 
         __KernelLoadContext(&target->context);
     } else {
         __SetCurrentThread(NULL, 0, NULL);
     }
-
-#if DEBUG_LEVEL <= MAX_LOGLEVEL || DEBUG_LOG == NOTICE_LOG
-    //bool fromIdle = oldUID == threadIdleID[0] || oldUID == threadIdleID[1];
-    //bool toIdle = currentThread == threadIdleID[0] || currentThread == threadIdleID[1];
-    //if (!(fromIdle && toIdle))
-    //{
-    //    u64 nowCycles = CoreTiming::GetTicks();
-    //    s64 consumedCycles = nowCycles - lastSwitchCycles;
-    //    lastSwitchCycles = nowCycles;
-
-    //    DEBUG_LOG(SCEKERNEL, "Context switch: %s -> %s (%i->%i, pc: %08x->%08x, %s) +%lldus",
-    //        oldName, hleCurrentThreadName,
-    //        oldUID, currentThread,
-    //        oldPC, currentMIPS->pc,
-    //        reason,
-    //        cyclesToUs(consumedCycles));
-    //}
-#endif
-
-    if (target) {
-        //// No longer waiting.
-        //target->nt.waitType = WAITTYPE_NONE;
-        //target->nt.waitID = 0;
-
-        //__KernelExecutePendingARMCalls(target, true);
-    }
 }
 
+/// Sets up the root (primary) thread of execution
 UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
     UID id;
 
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 38180cb9b..1731248cc 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include "common/common_types.h"
+#include "core/hle/kernel/kernel.h"
 
 enum ThreadStatus {
     THREADSTATUS_RUNNING    = 1,

From 0de78eb3c4407cfedb8779422d96b7ee73fc19ed Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 13 May 2014 23:18:28 -0400
Subject: [PATCH 12/72] fixed thread reset to not set stack address

---
 src/core/hle/kernel/thread.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 95ef2c173..c59d2a689 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -417,7 +417,6 @@ void ThreadContext::reset() {
     for (int i = 0; i < 16; i++) {
         reg[i] = 0;
     }
-    reg[13] = Memory::SCRATCHPAD_VADDR_END;
     cpsr = 0;
 }
 
@@ -464,6 +463,7 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
 void __KernelResetThread(Thread *t, int lowest_priority) {
     t->context.reset();
     t->context.pc = t->nt.entry_point;
+    t->context.reg[13] = t->nt.initial_stack;
 
     // If the thread would be better than lowestPriority, reset to its initial.  Yes, kinda odd...
     if (t->nt.current_priority < lowest_priority) {

From 4d7f3c74fd8bc86bf73b670355e2710558a66332 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Wed, 14 May 2014 20:49:02 -0400
Subject: [PATCH 13/72] added function stubs for EatCycles and ReSchedule

---
 src/core/hle/hle.cpp | 11 +++++++++++
 src/core/hle/hle.h   |  4 ++++
 2 files changed, 15 insertions(+)

diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index be151665b..452384571 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -37,6 +37,17 @@ void CallSyscall(u32 opcode) {
     }
 }
 
+void EatCycles(u32 cycles) {
+    // TODO: ImplementMe
+}
+
+void ReSchedule(const char *reason) {
+#ifdef _DEBUG
+    _dbg_assert_msg_(HLE, reason != 0 && strlen(reason) < 256, "ReSchedule: Invalid or too long reason.");
+#endif
+    // TODO: ImplementMe
+}
+
 void RegisterModule(std::string name, int num_functions, const FunctionDef* func_table) {
     ModuleDef module = {name, num_functions, func_table};
     g_module_db.push_back(module);
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h
index 42f37e29c..452546e1f 100644
--- a/src/core/hle/hle.h
+++ b/src/core/hle/hle.h
@@ -36,6 +36,10 @@ void RegisterModule(std::string name, int num_functions, const FunctionDef *func
 
 void CallSyscall(u32 opcode);
 
+void EatCycles(u32 cycles);
+
+void ReSchedule(const char *reason);
+
 void Init();
 
 void Shutdown();

From 9f5588725c9c16543f55ad05965086b8962a460f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Wed, 14 May 2014 20:49:27 -0400
Subject: [PATCH 14/72] 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index fb6ae8495..1c26fb388 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;
 }

From b99a5da65b76ce16e40fe05feb786aac11931904 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Wed, 14 May 2014 20:50:30 -0400
Subject: [PATCH 15/72] - added helper function for __KernelCreateThread

- added __KernelSwitchToThread for enabling a thread
- added __KernelRotateThreadReadyQueue
---
 src/core/hle/kernel/thread.cpp | 74 ++++++++++++++++++++++++++++++++--
 src/core/hle/kernel/thread.h   |  6 +++
 2 files changed, 76 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c59d2a689..b6d02aa12 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,6 +13,8 @@
 
 #include "core/core.h"
 #include "core/mem_map.h"
+#include "core/hle/hle.h"
+#include "core/hle/syscall.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/thread.h"
 
@@ -357,7 +359,7 @@ public:
     //void Cleanup() {
     //    // Callbacks are automatically deleted when their owning thread is deleted.
     //    for (auto it = callbacks.begin(), end = callbacks.end(); it != end; ++it)
-    //        kernelObjects.Destroy<Callback>(*it);
+    //        g_kernel_objects.Destroy<Callback>(*it);
 
     //    if (pushed_stacks.size() != 0)
     //    {
@@ -432,7 +434,7 @@ const char* g_hle_current_thread_name   = NULL;
 
 /// Creates a new thread
 Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, 
-    u32 entrypoint, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
+    u32 entry_point, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
 
     Thread *t = new Thread;
     id = g_kernel_objects.Create(t);
@@ -442,7 +444,7 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
 
     memset(&t->nt, 0xCD, sizeof(t->nt));
 
-    t->nt.entry_point = entrypoint;
+    t->nt.entry_point = entry_point;
     t->nt.native_size = sizeof(t->nt);
     t->nt.initial_priority = t->nt.current_priority = priority;
     t->nt.status = THREADSTATUS_DORMANT;
@@ -459,6 +461,18 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
     return t;
 }
 
+UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg, 
+    u32 stack_top, u32 processor_id, int stack_size) {
+    UID id;
+    __KernelCreateThread(id, module_id, name, priority, entry_point, arg, stack_top, processor_id, 
+        stack_size);
+    
+    HLE::EatCycles(32000);
+    HLE::ReSchedule("thread created");
+    
+    return id;
+}
+
 /// Resets the specified thread back to initial calling state
 void __KernelResetThread(Thread *t, int lowest_priority) {
     t->context.reset();
@@ -608,6 +622,31 @@ void __KernelSwitchContext(Thread *target, const char *reason) {
     }
 }
 
+bool __KernelSwitchToThread(UID thread_id, const char *reason) {
+    if (!reason) {
+        reason = "switch to thread";
+    }
+    if (g_current_thread == thread_id) {
+        return false;
+    }
+    u32 error;
+    Thread *t = g_kernel_objects.Get<Thread>(thread_id, error);
+    if (!t) {
+        ERROR_LOG(KERNEL, "__KernelSwitchToThread: %x doesn't exist", thread_id);
+        HLE::ReSchedule("switch to deleted thread");
+    } else if (t->IsReady() || t->IsRunning()) {
+        Thread *current = __GetCurrentThread();
+        if (current && current->IsRunning()) {
+            __KernelChangeReadyState(current, g_current_thread, true);
+        }
+        __KernelSwitchContext(t, reason);
+        return true;
+    } else {
+        HLE::ReSchedule("switch to waiting thread");
+    }
+    return false;
+}
+
 /// Sets up the root (primary) thread of execution
 UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
     UID id;
@@ -633,7 +672,7 @@ UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
     // NOTE(bunnei): Not sure this is really correct, ignore args for now...
     //Core::g_app_core->SetReg(0, args); 
     //Core::g_app_core->SetReg(13, (args + 0xf) & ~0xf); // Setup SP - probably not correct
-    //u32 location = Core::g_app_core->GetReg(13); // SP
+    //u32 location = Core::g_app_core->GetReg(13); // SP 
     //Core::g_app_core->SetReg(1, location);
     
     //if (argp)
@@ -644,6 +683,33 @@ UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
     return id;
 }
 
+int __KernelRotateThreadReadyQueue(int priority) {
+    Thread *cur = __GetCurrentThread();
+
+    // 0 is special, it means "my current priority."
+    if (priority == 0) {
+        priority = cur->nt.current_priority;
+    }
+    //if (priority <= 0x07 || priority > 0x77)
+    //    return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY;
+
+    if (!g_thread_ready_queue.empty(priority)) {
+        // In other words, yield to everyone else.
+        if (cur->nt.current_priority == priority) {
+            g_thread_ready_queue.push_back(priority, g_current_thread);
+            cur->nt.status = (cur->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY;
+
+        // Yield the next thread of this priority to all other threads of same priority.
+        } else {
+            g_thread_ready_queue.rotate(priority);
+        }
+    }
+    HLE::EatCycles(250);
+    HLE::ReSchedule("rotatethreadreadyqueue");
+
+    return 0;
+}
+
 void __KernelThreadingInit() {
 }
 
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 1731248cc..05468fb2e 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -30,6 +30,10 @@ class Thread;
 
 Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint,
     u32 arg, u32 stack_top, u32 processor_id, int stack_size=0x4000);
+
+UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg, 
+    u32 stack_top, u32 processor_id, int stack_size=0x4000);
+
 void __KernelResetThread(Thread *t, int lowest_priority);
 void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready);
 void __KernelChangeReadyState(UID thread_id, bool ready);
@@ -37,7 +41,9 @@ Thread* __KernelNextThread();
 void __KernelSaveContext(ThreadContext *ctx);
 void __KernelLoadContext(ThreadContext *ctx);
 void __KernelSwitchContext(Thread *target, const char *reason);
+bool __KernelSwitchToThread(UID thread_id, const char *reason);
 UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000);
+int __KernelRotateThreadReadyQueue(int priority=0);
 
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();

From cf2eb8e3d3876d5866bdcb5dfe2ae9deceea2cb4 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:19:34 -0400
Subject: [PATCH 16/72] added ThreadQueueList class to common (taken from
 PPSSPP)

---
 src/common/common.vcxproj         |   1 +
 src/common/common.vcxproj.filters |   1 +
 src/common/thread_queue_list.h    | 216 ++++++++++++++++++++++++++++++
 3 files changed, 218 insertions(+)
 create mode 100644 src/common/thread_queue_list.h

diff --git a/src/common/common.vcxproj b/src/common/common.vcxproj
index 5dc6ff790..86295a480 100644
--- a/src/common/common.vcxproj
+++ b/src/common/common.vcxproj
@@ -190,6 +190,7 @@
     <ClInclude Include="swap.h" />
     <ClInclude Include="symbols.h" />
     <ClInclude Include="thread.h" />
+    <ClInclude Include="thread_queue_list.h" />
     <ClInclude Include="thunk.h" />
     <ClInclude Include="timer.h" />
     <ClInclude Include="utf8.h" />
diff --git a/src/common/common.vcxproj.filters b/src/common/common.vcxproj.filters
index 268730228..84cfa8837 100644
--- a/src/common/common.vcxproj.filters
+++ b/src/common/common.vcxproj.filters
@@ -40,6 +40,7 @@
     <ClInclude Include="symbols.h" />
     <ClInclude Include="scm_rev.h" />
     <ClInclude Include="bit_field.h" />
+    <ClInclude Include="thread_queue_list.h" />
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="break_points.cpp" />
diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h
new file mode 100644
index 000000000..4a89572f6
--- /dev/null
+++ b/src/common/thread_queue_list.h
@@ -0,0 +1,216 @@
+// Copyright 2014 Citra Emulator Project / PPSSPP Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common.h"
+
+namespace Common {
+
+template<class IdType>
+struct ThreadQueueList {
+    // Number of queues (number of priority levels starting at 0.)
+    static const int NUM_QUEUES = 128;
+    
+    // Initial number of threads a single queue can handle.
+    static const int INITIAL_CAPACITY = 32;
+
+    struct Queue {
+        // Next ever-been-used queue (worse priority.)
+        Queue *next;
+        // First valid item in data.
+        int first;
+        // One after last valid item in data.
+        int end;
+        // A too-large array with room on the front and end.
+        IdType *data;
+        // Size of data array.
+        int capacity;
+    };
+
+    ThreadQueueList() {
+        memset(queues, 0, sizeof(queues));
+        first = invalid();
+    }
+
+    ~ThreadQueueList() {
+        for (int i = 0; i < NUM_QUEUES; ++i)
+        {
+            if (queues[i].data != NULL)
+                free(queues[i].data);
+        }
+    }
+
+    // Only for debugging, returns priority level.
+    int contains(const IdType uid) {
+        for (int i = 0; i < NUM_QUEUES; ++i)
+        {
+            if (queues[i].data == NULL)
+                continue;
+
+            Queue *cur = &queues[i];
+            for (int j = cur->first; j < cur->end; ++j)
+            {
+                if (cur->data[j] == uid)
+                    return i;
+            }
+        }
+
+        return -1;
+    }
+
+    inline IdType pop_first() {
+        Queue *cur = first;
+        while (cur != invalid())
+        {
+            if (cur->end - cur->first > 0)
+                return cur->data[cur->first++];
+            cur = cur->next;
+        }
+
+        //_dbg_assert_msg_(SCEKERNEL, false, "ThreadQueueList should not be empty.");
+        return 0;
+    }
+
+    inline IdType pop_first_better(u32 priority) {
+        Queue *cur = first;
+        Queue *stop = &queues[priority];
+        while (cur < stop)
+        {
+            if (cur->end - cur->first > 0)
+                return cur->data[cur->first++];
+            cur = cur->next;
+        }
+
+        return 0;
+    }
+
+    inline void push_front(u32 priority, const IdType threadID) {
+        Queue *cur = &queues[priority];
+        cur->data[--cur->first] = threadID;
+        if (cur->first == 0)
+            rebalance(priority);
+    }
+
+    inline void push_back(u32 priority, const IdType threadID) {
+        Queue *cur = &queues[priority];
+        cur->data[cur->end++] = threadID;
+        if (cur->end == cur->capacity)
+            rebalance(priority);
+    }
+
+    inline void remove(u32 priority, const IdType threadID) {
+        Queue *cur = &queues[priority];
+        //_dbg_assert_msg_(SCEKERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
+
+        for (int i = cur->first; i < cur->end; ++i)
+        {
+            if (cur->data[i] == threadID)
+            {
+                int remaining = --cur->end - i;
+                if (remaining > 0)
+                    memmove(&cur->data[i], &cur->data[i + 1], remaining * sizeof(IdType));
+                return;
+            }
+        }
+
+        // Wasn't there.
+    }
+
+    inline void rotate(u32 priority) {
+        Queue *cur = &queues[priority];
+        //_dbg_assert_msg_(SCEKERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
+
+        if (cur->end - cur->first > 1)
+        {
+            cur->data[cur->end++] = cur->data[cur->first++];
+            if (cur->end == cur->capacity)
+                rebalance(priority);
+        }
+    }
+
+    inline void clear() {
+        for (int i = 0; i < NUM_QUEUES; ++i)
+        {
+            if (queues[i].data != NULL)
+                free(queues[i].data);
+        }
+        memset(queues, 0, sizeof(queues));
+        first = invalid();
+    }
+
+    inline bool empty(u32 priority) const {
+        const Queue *cur = &queues[priority];
+        return cur->first == cur->end;
+    }
+
+    inline void prepare(u32 priority) {
+        Queue *cur = &queues[priority];
+        if (cur->next == NULL)
+            link(priority, INITIAL_CAPACITY);
+    }
+
+private:
+    Queue *invalid() const {
+        return (Queue *) -1;
+    }
+
+    void link(u32 priority, int size) {
+        //_dbg_assert_msg_(SCEKERNEL, queues[priority].data == NULL, "ThreadQueueList::Queue should only be initialized once.");
+
+        if (size <= INITIAL_CAPACITY)
+            size = INITIAL_CAPACITY;
+        else
+        {
+            int goal = size;
+            size = INITIAL_CAPACITY;
+            while (size < goal)
+                size *= 2;
+        }
+        Queue *cur = &queues[priority];
+        cur->data = (IdType *) malloc(sizeof(IdType) * size);
+        cur->capacity = size;
+        cur->first = size / 2;
+        cur->end = size / 2;
+
+        for (int i = (int) priority - 1; i >= 0; --i)
+        {
+            if (queues[i].next != NULL)
+            {
+                cur->next = queues[i].next;
+                queues[i].next = cur;
+                return;
+            }
+        }
+
+        cur->next = first;
+        first = cur;
+    }
+
+    void rebalance(u32 priority) {
+        Queue *cur = &queues[priority];
+        int size = cur->end - cur->first;
+        if (size >= cur->capacity - 2)  {
+            IdType *new_data = (IdType *)realloc(cur->data, cur->capacity * 2 * sizeof(IdType));
+            if (new_data != NULL)  {
+                cur->capacity *= 2;
+                cur->data = new_data;
+            }
+        }
+
+        int newFirst = (cur->capacity - size) / 2;
+        if (newFirst != cur->first) {
+            memmove(&cur->data[newFirst], &cur->data[cur->first], size * sizeof(IdType));
+            cur->first = newFirst;
+            cur->end = newFirst + size;
+        }
+    }
+
+    // The first queue that's ever been used.
+    Queue *first;
+    // The priority level queues of thread ids.
+    Queue queues[NUM_QUEUES];
+};
+
+} // namespace

From 367d63691fe810c83979fee04b181338f96cfb50 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:25:56 -0400
Subject: [PATCH 17/72] - added ThreadContext struct

- cleaned up CreateThread svc
---
 src/core/hle/syscall.cpp | 20 ++++++++++++--------
 src/core/hle/syscall.h   | 14 ++++++++++++++
 2 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index c697bc277..0700d9e82 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -9,6 +9,7 @@
 #include "core/hle/function_wrappers.h"
 #include "core/hle/syscall.h"
 #include "core/hle/service/service.h"
+#include "core/hle/kernel/thread.h"
 
 #include "common/symbols.h"
 
@@ -139,16 +140,19 @@ Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void*
     return 0;
 }
 
-Result CreateThread(void* thread, u32 threadpriority, u32 entrypoint, u32 arg, u32 stacktop, u32 processorid) {
-    std::string symbol_name = "unknown";
-    if (Symbols::HasSymbol(entrypoint)) {
-        TSymbol symbol = Symbols::GetSymbol(entrypoint);
-        symbol_name = symbol.name;
+Result CreateThread(void* thread, u32 thread_priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
+    std::string thread_name;
+    if (Symbols::HasSymbol(entry_point)) {
+        TSymbol symbol = Symbols::GetSymbol(entry_point);
+        thread_name = symbol.name;
+    } else {
+        char buff[100];
+        sprintf(buff, "%s", "unk-%08X", entry_point);
+        thread_name = buff;
     }
-    // stack top: 0x0056A4A0
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, "
-        "stacktop=0x%08X, threadpriority=0x%08X, processorid=0x%08X", entrypoint, 
-        symbol_name.c_str(), arg, stacktop, threadpriority, processorid);
+        "stacktop=0x%08X, threadpriority=0x%08X, processorid=0x%08X", entry_point, 
+        thread_name.c_str(), arg, stack_top, thread_priority, processor_id);
 
     return 0;
 }
diff --git a/src/core/hle/syscall.h b/src/core/hle/syscall.h
index 7a94e0136..15af5e138 100644
--- a/src/core/hle/syscall.h
+++ b/src/core/hle/syscall.h
@@ -6,6 +6,20 @@
 
 #include "common/common_types.h"
 
+////////////////////////////////////////////////////////////////////////////////////////////////////
+// SVC structures
+
+struct ThreadContext {
+    u32 cpu_registers[13];
+    u32 sp;
+    u32 lr;
+    u32 pc;
+    u32 cpsr;
+    u32 fpu_registers[32];
+    u32 fpscr;
+    u32 fpexc;
+};
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace Syscall
 

From a7cc430aa4da2962dcf08db2f6009fc272bdda70 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:26:28 -0400
Subject: [PATCH 18/72] 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 1c26fb388..f7145ddd8 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 0eb58210c..24d422682 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 <class T>
-    u32 Destroy(UID handle) {
+    u32 Destroy(Handle handle) {
         u32 error;
         if (Get<T>(handle, error)) {
             occupied[handle - HANDLE_OFFSET] = false;
@@ -51,10 +54,10 @@ public:
         return error;
     };
 
-    bool IsValid(UID handle);
+    bool IsValid(Handle handle);
 
     template <class T>
-    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 <class T>
-    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<T *>(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();

From 940330c6e12b3eefb9fb035f75f4b090c969cb75 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:27:08 -0400
Subject: [PATCH 19/72] completely gutted/refactored threading code to be
 simpler

---
 src/core/hle/kernel/thread.cpp | 894 ++++++++++-----------------------
 src/core/hle/kernel/thread.h   |  44 +-
 2 files changed, 255 insertions(+), 683 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index b6d02aa12..833a1b4ba 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -10,6 +10,7 @@
 #include <string>
 
 #include "common/common.h"
+#include "common/thread_queue_list.h"
 
 #include "core/core.h"
 #include "core/mem_map.h"
@@ -18,698 +19,309 @@
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/thread.h"
 
-struct ThreadQueueList {
-    // Number of queues (number of priority levels starting at 0.)
-    static const int NUM_QUEUES = 128;
-    // Initial number of threads a single queue can handle.
-    static const int INITIAL_CAPACITY = 32;
+// Enums
 
-    struct Queue {
-        // Next ever-been-used queue (worse priority.)
-        Queue *next;
-        // First valid item in data.
-        int first;
-        // One after last valid item in data.
-        int end;
-        // A too-large array with room on the front and end.
-        UID *data;
-        // Size of data array.
-        int capacity;
-    };
-
-    ThreadQueueList() {
-        memset(queues, 0, sizeof(queues));
-        first = invalid();
-    }
-
-    ~ThreadQueueList() {
-        for (int i = 0; i < NUM_QUEUES; ++i) {
-            if (queues[i].data != NULL) {
-                free(queues[i].data);
-            }
-        }
-    }
-
-    // Only for debugging, returns priority level.
-    int contains(const UID uid) {
-        for (int i = 0; i < NUM_QUEUES; ++i) {
-            if (queues[i].data == NULL) {
-                continue;
-            }
-            Queue *cur = &queues[i];
-            for (int j = cur->first; j < cur->end; ++j) {
-                if (cur->data[j] == uid) {
-                    return i;
-                }
-            }
-        }
-        return -1;
-    }
-
-    inline UID pop_first() {
-        Queue *cur = first;
-        while (cur != invalid()) {
-            if (cur->end - cur->first > 0) {
-                return cur->data[cur->first++];
-            }
-            cur = cur->next;
-        }
-
-        _dbg_assert_msg_(KERNEL, false, "ThreadQueueList should not be empty.");
-        return 0;
-    }
-
-    inline UID pop_first_better(u32 priority) {
-        Queue *cur = first;
-        Queue *stop = &queues[priority];
-        while (cur < stop) {
-            if (cur->end - cur->first > 0) {
-                return cur->data[cur->first++];
-            }
-            cur = cur->next;
-        }
-        return 0;
-    }
-
-    inline void push_front(u32 priority, const UID thread_id) {
-        Queue *cur = &queues[priority];
-        cur->data[--cur->first] = thread_id;
-        if (cur->first == 0) {
-            rebalance(priority);
-        }
-    }
-
-    inline void push_back(u32 priority, const UID thread_id)
-    {
-        Queue *cur = &queues[priority];
-        cur->data[cur->end++] = thread_id;
-        if (cur->end == cur->capacity) {
-            rebalance(priority);
-        }
-    }
-
-    inline void remove(u32 priority, const UID thread_id) {
-        Queue *cur = &queues[priority];
-        _dbg_assert_msg_(KERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
-
-        for (int i = cur->first; i < cur->end; ++i) {
-            if (cur->data[i] == thread_id) {
-                int remaining = --cur->end - i;
-                if (remaining > 0) {
-                    memmove(&cur->data[i], &cur->data[i + 1], remaining * sizeof(UID));
-                }
-                return;
-            }
-        }
-
-        // Wasn't there.
-    }
-
-    inline void rotate(u32 priority) {
-        Queue *cur = &queues[priority];
-        _dbg_assert_msg_(KERNEL, cur->next != NULL, "ThreadQueueList::Queue should already be linked up.");
-
-        if (cur->end - cur->first > 1) {
-            cur->data[cur->end++] = cur->data[cur->first++];
-            if (cur->end == cur->capacity) {
-                rebalance(priority);
-            }
-        }
-    }
-
-    inline void clear() {
-        for (int i = 0; i < NUM_QUEUES; ++i) {
-            if (queues[i].data != NULL) {
-                free(queues[i].data);
-            }
-        }
-        memset(queues, 0, sizeof(queues));
-        first = invalid();
-    }
-
-    inline bool empty(u32 priority) const {
-        const Queue *cur = &queues[priority];
-        return cur->first == cur->end;
-    }
-
-    inline void prepare(u32 priority) {
-        Queue *cur = &queues[priority];
-        if (cur->next == NULL) {
-            link(priority, INITIAL_CAPACITY);
-        }
-    }
-
-private:
-    Queue *invalid() const {
-        return (Queue *)-1;
-    }
-
-    void link(u32 priority, int size) {
-        _dbg_assert_msg_(KERNEL, queues[priority].data == NULL, "ThreadQueueList::Queue should only be initialized once.");
-
-        if (size <= INITIAL_CAPACITY) {
-            size = INITIAL_CAPACITY;
-        } else {
-            int goal = size;
-            size = INITIAL_CAPACITY;
-            while (size < goal)
-                size *= 2;
-        }
-        Queue *cur = &queues[priority];
-        cur->data = (UID*)malloc(sizeof(UID)* size);
-        cur->capacity = size;
-        cur->first = size / 2;
-        cur->end = size / 2;
-
-        for (int i = (int)priority - 1; i >= 0; --i) {
-            if (queues[i].next != NULL) {
-                cur->next = queues[i].next;
-                queues[i].next = cur;
-                return;
-            }
-        }
-
-        cur->next = first;
-        first = cur;
-    }
-
-    void rebalance(u32 priority) {
-        Queue *cur = &queues[priority];
-        int size = cur->end - cur->first;
-        if (size >= cur->capacity - 2) {
-            UID* new_data = (UID*)realloc(cur->data, cur->capacity * 2 * sizeof(UID));
-            if (new_data != NULL) {
-                cur->capacity *= 2;
-                cur->data = new_data;
-            }
-        }
-
-        int newFirst = (cur->capacity - size) / 2;
-        if (newFirst != cur->first) {
-            memmove(&cur->data[newFirst], &cur->data[cur->first], size * sizeof(UID));
-            cur->first = newFirst;
-            cur->end = newFirst + size;
-        }
-    }
-
-    // The first queue that's ever been used.
-    Queue* first;
-    // The priority level queues of thread ids.
-    Queue queues[NUM_QUEUES];
+enum ThreadPriority {
+    THREADPRIO_HIGHEST = 0,
+    THREADPRIO_DEFAULT = 16,
+    THREADPRIO_LOWEST = 31,
 };
 
-// Supposed to represent a real CTR struct... but not sure of the correct fields yet.
-struct NativeThread {
-    //u32         Pointer to vtable
-    //u32         Reference count
-    //KProcess*   Process the thread belongs to (virtual address)
-    //u32         Thread id
-    //u32*        ptr = *(KThread+0x8C) - 0xB0
-    //u32*        End-address of the page for this thread allocated in the 0xFF4XX000 region. Thus, 
-    //      if the beginning of this mapped page is 0xFF401000, this ptr would be 0xFF402000.
-    //KThread*    Previous ? (virtual address)
-    //KThread*    Next ? (virtual address)
+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
+};
 
-    u32_le native_size;
-    char name[KERNELOBJECT_MAX_NAME_LENGTH + 1];
-
-    // Threading stuff
-    u32_le status;
-    u32_le entry_point;
-    u32_le initial_stack;
-    u32_le stack_top;
-    u32_le stack_size;
+enum WaitType {
+    WAITTYPE_NONE,
+    WAITTYPE_SLEEP,
+    WAITTYPE_SEMA,
+    WAITTYPE_EVENTFLAG,
+    WAITTYPE_THREADEND,
+    WAITTYPE_VBLANK,
+    WAITTYPE_MUTEX,
+    WAITTYPE_SYNCH,
     
-    u32_le arg;
-    u32_le processor_id;
-
-    s32_le initial_priority;
-    s32_le current_priority;
+    NUM_WAITTYPES
 };
 
-struct ThreadWaitInfo {
-    u32 wait_value;
-    u32 timeout_ptr;
-};
+typedef s32 Handle;
 
 class Thread : public KernelObject {
 public:
-    /*const char *GetName() { return nt.name; }*/
-    const char *GetTypeName() { return "Thread"; }
-    //void GetQuickInfo(char *ptr, int size)
-    //{
-    //    sprintf(ptr, "pc= %08x sp= %08x %s %s %s %s %s %s (wt=%i wid=%i wv= %08x )",
-    //        context.pc, context.r[13], // 13 is stack pointer
-    //        (nt.status & THREADSTATUS_RUNNING) ? "RUN" : "",
-    //        (nt.status & THREADSTATUS_READY) ? "READY" : "",
-    //        (nt.status & THREADSTATUS_WAIT) ? "WAIT" : "",
-    //        (nt.status & THREADSTATUS_SUSPEND) ? "SUSPEND" : "",
-    //        (nt.status & THREADSTATUS_DORMANT) ? "DORMANT" : "",
-    //        (nt.status & THREADSTATUS_DEAD) ? "DEAD" : "",
-    //        nt.waitType,
-    //        nt.waitID,
-    //        waitInfo.waitValue);
-    //}
 
-    //static u32 GetMissingErrorCode() { return SCE_KERNEL_ERROR_UNKNOWN_THID; }
+    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; }
 
-    bool SetupStack(u32 stack_top, int stack_size) {
-        current_stack.start = stack_top; 
-        nt.initial_stack = current_stack.start;
-        nt.stack_size = stack_size;
-        return true;
-    }
-
-    //bool FillStack() {
-    //    // Fill the stack.
-    //    if ((nt.attr & PSP_THREAD_ATTR_NO_FILLSTACK) == 0) {
-    //        Memory::Memset(current_stack.start, 0xFF, nt.stack_size);
-    //    }
-    //    context.r[MIPS_REG_SP] = current_stack.start + nt.stack_size;
-    //    current_stack.end = context.r[MIPS_REG_SP];
-    //    // The k0 section is 256 bytes at the top of the stack.
-    //    context.r[MIPS_REG_SP] -= 256;
-    //    context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP];
-    //    u32 k0 = context.r[MIPS_REG_K0];
-    //    Memory::Memset(k0, 0, 0x100);
-    //    Memory::Write_U32(GetUID(), k0 + 0xc0);
-    //    Memory::Write_U32(nt.initialStack, k0 + 0xc8);
-    //    Memory::Write_U32(0xffffffff, k0 + 0xf8);
-    //    Memory::Write_U32(0xffffffff, k0 + 0xfc);
-    //    // After k0 comes the arguments, which is done by sceKernelStartThread().
-
-    //    Memory::Write_U32(GetUID(), nt.initialStack);
-    //    return true;
-    //}
-
-    //void FreeStack() {
-    //    if (current_stack.start != 0) {
-    //        DEBUG_LOG(KERNEL, "Freeing thread stack %s", nt.name);
-
-    //        if ((nt.attr & PSP_THREAD_ATTR_CLEAR_STACK) != 0 && nt.initialStack != 0) {
-    //            Memory::Memset(nt.initialStack, 0, nt.stack_size);
-    //        }
-
-    //        if (nt.attr & PSP_THREAD_ATTR_KERNEL) {
-    //            kernelMemory.Free(current_stack.start);
-    //        }
-    //        else {
-    //            userMemory.Free(current_stack.start);
-    //        }
-    //        current_stack.start = 0;
-    //    }
-    //}
-
-    //bool PushExtendedStack(u32 size) {
-    //    u32 stack = userMemory.Alloc(size, true, (std::string("extended/") + nt.name).c_str());
-    //    if (stack == (u32)-1)
-    //        return false;
-
-    //    pushed_stacks.push_back(current_stack);
-    //    current_stack.start = stack;
-    //    current_stack.end = stack + size;
-    //    nt.initialStack = current_stack.start;
-    //    nt.stack_size = current_stack.end - current_stack.start;
-
-    //    // We still drop the thread_id at the bottom and fill it, but there's no k0.
-    //    Memory::Memset(current_stack.start, 0xFF, nt.stack_size);
-    //    Memory::Write_U32(GetUID(), nt.initialStack);
-    //    return true;
-    //}
-
-    //bool PopExtendedStack() {
-    //    if (pushed_stacks.size() == 0) {
-    //        return false;
-    //    }
-    //    userMemory.Free(current_stack.start);
-    //    current_stack = pushed_stacks.back();
-    //    pushed_stacks.pop_back();
-    //    nt.initialStack = current_stack.start;
-    //    nt.stack_size = current_stack.end - current_stack.start;
-    //    return true;
-    //}
-
-    Thread() {
-        current_stack.start = 0;
-    }
-
-    // Can't use a destructor since savestates will call that too.
-    //void Cleanup() {
-    //    // Callbacks are automatically deleted when their owning thread is deleted.
-    //    for (auto it = callbacks.begin(), end = callbacks.end(); it != end; ++it)
-    //        g_kernel_objects.Destroy<Callback>(*it);
-
-    //    if (pushed_stacks.size() != 0)
-    //    {
-    //        WARN_LOG(KERNEL, "Thread ended within an extended stack");
-    //        for (size_t i = 0; i < pushed_stacks.size(); ++i)
-    //            userMemory.Free(pushed_stacks[i].start);
-    //    }
-    //    FreeStack();
-    //}
-
-    void setReturnValue(u32 retval);
-    void setReturnValue(u64 retval);
-    void resumeFromWait();
-    //bool isWaitingFor(WaitType type, int id);
-    //int getWaitID(WaitType type);
-    ThreadWaitInfo getWaitInfo();
-
-    // Utils
-    inline bool IsRunning() const { return (nt.status & THREADSTATUS_RUNNING) != 0; }
-    inline bool IsStopped() const { return (nt.status & THREADSTATUS_DORMANT) != 0; }
-    inline bool IsReady() const { return (nt.status & THREADSTATUS_READY) != 0; }
-    inline bool IsWaiting() const { return (nt.status & THREADSTATUS_WAIT) != 0; }
-    inline bool IsSuspended() const { return (nt.status & THREADSTATUS_SUSPEND) != 0; }
-
-    NativeThread nt;
-
-    ThreadWaitInfo waitInfo;
-    UID moduleId;
-
-    //bool isProcessingCallbacks;
-    //u32 currentMipscallId;
-    //UID currentCallbackId;
+    inline bool IsRunning() const { return (status & THREADSTATUS_RUNNING) != 0; }
+    inline bool IsStopped() const { return (status & THREADSTATUS_DORMANT) != 0; }
+    inline bool IsReady() const { return (status & THREADSTATUS_READY) != 0; }
+    inline bool IsWaiting() const { return (status & THREADSTATUS_WAIT) != 0; }
+    inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; }
 
     ThreadContext context;
 
-    std::vector<UID> callbacks;
+    u32 status;
+    u32 entry_point;
+    u32 stack_top;
+    u32 stack_size;
 
-    std::list<u32> pending_calls;
+    s32 initial_priority;
+    s32 current_priority;
 
-    struct StackInfo {
-        u32 start;
-        u32 end;
-    };
-    // This is a stack of... stacks, since sceKernelExtendThreadStack() can recurse.
-    // These are stacks that aren't "active" right now, but will pop off once the func returns.
-    std::vector<StackInfo> pushed_stacks;
+    s32 processor_id;
 
-    StackInfo current_stack;
+    WaitType wait_type;
 
-    // For thread end.
-    std::vector<UID> waiting_threads;
-    // Key is the callback id it was for, or if no callback, the thread id.
-    std::map<UID, u64> paused_waits;
+    char name[KERNELOBJECT_MAX_NAME_LENGTH+1];
 };
 
-void ThreadContext::reset() {
-    for (int i = 0; i < 16; i++) {
-        reg[i] = 0;
-    }
-    cpsr = 0;
-}
-
 // Lists all thread ids that aren't deleted/etc.
-std::vector<UID> g_thread_queue;
+std::vector<Handle> g_thread_queue;
 
-// Lists only ready thread ids
-ThreadQueueList g_thread_ready_queue;
+// Lists only ready thread ids.
+Common::ThreadQueueList<Handle> g_thread_ready_queue;
 
-UID         g_current_thread            = 0;
-Thread*     g_current_thread_ptr        = NULL;
-const char* g_hle_current_thread_name   = NULL;
+Handle g_current_thread_handle;
 
-/// Creates a new thread
-Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, 
-    u32 entry_point, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
+Thread* g_current_thread;
 
-    Thread *t = new Thread;
-    id = g_kernel_objects.Create(t);
 
-    g_thread_queue.push_back(id);
-    g_thread_ready_queue.prepare(priority);
-
-    memset(&t->nt, 0xCD, sizeof(t->nt));
-
-    t->nt.entry_point = entry_point;
-    t->nt.native_size = sizeof(t->nt);
-    t->nt.initial_priority = t->nt.current_priority = priority;
-    t->nt.status = THREADSTATUS_DORMANT;
-    t->nt.initial_stack = t->nt.stack_top = stack_top;
-    t->nt.stack_size = stack_size;
-    t->nt.processor_id = processor_id;
-
-    strncpy(t->nt.name, name, KERNELOBJECT_MAX_NAME_LENGTH);
-    t->nt.name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
-
-    t->nt.stack_size = stack_size;
-    t->SetupStack(stack_top, stack_size);
-
-    return t;
-}
-
-UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg, 
-    u32 stack_top, u32 processor_id, int stack_size) {
-    UID id;
-    __KernelCreateThread(id, module_id, name, priority, entry_point, arg, stack_top, processor_id, 
-        stack_size);
-    
-    HLE::EatCycles(32000);
-    HLE::ReSchedule("thread created");
-    
-    return id;
-}
-
-/// Resets the specified thread back to initial calling state
-void __KernelResetThread(Thread *t, int lowest_priority) {
-    t->context.reset();
-    t->context.pc = t->nt.entry_point;
-    t->context.reg[13] = t->nt.initial_stack;
-
-    // If the thread would be better than lowestPriority, reset to its initial.  Yes, kinda odd...
-    if (t->nt.current_priority < lowest_priority) {
-        t->nt.current_priority = t->nt.initial_priority;
-    }
-
-    memset(&t->waitInfo, 0, sizeof(t->waitInfo));
-}
-
-/// Returns the current executing thread
 inline Thread *__GetCurrentThread() {
-    return g_current_thread_ptr;
+    return g_current_thread;
 }
 
-/// Sets the current executing thread
-inline void __SetCurrentThread(Thread *thread, UID thread_id, const char *name) {
-    g_current_thread = thread_id;
-    g_current_thread_ptr = thread;
-    g_hle_current_thread_name = name;
+inline void __SetCurrentThread(Thread *t) {
+    g_current_thread = t;
+    g_current_thread_handle = t->GetHandle();
 }
 
-// TODO: Use __KernelChangeThreadState instead?  It has other affects...
-void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready) {
-    // Passing the id as a parameter is just an optimization, if it's wrong it will cause havoc.
-    _dbg_assert_msg_(KERNEL, thread->GetUID() == thread_id, "Incorrect thread_id");
-    int prio = thread->nt.current_priority;
-
-    if (thread->IsReady()) {
-        if (!ready)
-            g_thread_ready_queue.remove(prio, thread_id);
-    } else if (ready) {
-        if (thread->IsRunning()) {
-            g_thread_ready_queue.push_front(prio, thread_id);
-        } else {
-            g_thread_ready_queue.push_back(prio, thread_id);
-        }
-        thread->nt.status = THREADSTATUS_READY;
-    }
-}
-
-void __KernelChangeReadyState(UID thread_id, bool ready) {
-    u32 error;
-    Thread *thread = g_kernel_objects.Get<Thread>(thread_id, error);
-    if (thread) {
-        __KernelChangeReadyState(thread, thread_id, ready);
-    } else {
-        WARN_LOG(KERNEL, "Trying to change the ready state of an unknown thread?");
-    }
-}
-
-/// Returns NULL if the current thread is fine.
-Thread* __KernelNextThread() {
-    UID best_thread;
-
-    // If the current thread is running, it's a valid candidate.
-    Thread *cur = __GetCurrentThread();
-    if (cur && cur->IsRunning()) {
-        best_thread = g_thread_ready_queue.pop_first_better(cur->nt.current_priority);
-        if (best_thread != 0) {
-            __KernelChangeReadyState(cur, g_current_thread, true);
-        }
-    } else {
-        best_thread = g_thread_ready_queue.pop_first();
-    }
-    // Assume g_thread_ready_queue has not become corrupt.
-    if (best_thread != 0) {
-        return g_kernel_objects.GetFast<Thread>(best_thread);
-    } else {
-        return NULL;
-    }
-}
+////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /// Saves the current CPU context
-void __KernelSaveContext(ThreadContext *ctx) {
-    ctx->reg[0] = Core::g_app_core->GetReg(0);
-    ctx->reg[1] = Core::g_app_core->GetReg(1);
-    ctx->reg[2] = Core::g_app_core->GetReg(2);
-    ctx->reg[3] = Core::g_app_core->GetReg(3);
-    ctx->reg[4] = Core::g_app_core->GetReg(4);
-    ctx->reg[5] = Core::g_app_core->GetReg(5);
-    ctx->reg[6] = Core::g_app_core->GetReg(6);
-    ctx->reg[7] = Core::g_app_core->GetReg(7);
-    ctx->reg[8] = Core::g_app_core->GetReg(8);
-    ctx->reg[9] = Core::g_app_core->GetReg(9);
-    ctx->reg[10] = Core::g_app_core->GetReg(10);
-    ctx->reg[11] = Core::g_app_core->GetReg(11);
-    ctx->reg[12] = Core::g_app_core->GetReg(12);
-    ctx->reg[13] = Core::g_app_core->GetReg(13);
-    ctx->reg[14] = Core::g_app_core->GetReg(14);
-    ctx->reg[15] = Core::g_app_core->GetReg(15);
-    ctx->pc = Core::g_app_core->GetPC();
-    ctx->cpsr = Core::g_app_core->GetCPSR();
+void __KernelSaveContext(ThreadContext &ctx) {
+    ctx.cpu_registers[0] = Core::g_app_core->GetReg(0);
+    ctx.cpu_registers[1] = Core::g_app_core->GetReg(1);
+    ctx.cpu_registers[2] = Core::g_app_core->GetReg(2);
+    ctx.cpu_registers[3] = Core::g_app_core->GetReg(3);
+    ctx.cpu_registers[4] = Core::g_app_core->GetReg(4);
+    ctx.cpu_registers[5] = Core::g_app_core->GetReg(5);
+    ctx.cpu_registers[6] = Core::g_app_core->GetReg(6);
+    ctx.cpu_registers[7] = Core::g_app_core->GetReg(7);
+    ctx.cpu_registers[8] = Core::g_app_core->GetReg(8);
+    ctx.cpu_registers[9] = Core::g_app_core->GetReg(9);
+    ctx.cpu_registers[10] = Core::g_app_core->GetReg(10);
+    ctx.cpu_registers[11] = Core::g_app_core->GetReg(11);
+    ctx.cpu_registers[12] = Core::g_app_core->GetReg(12);
+    ctx.sp = Core::g_app_core->GetReg(13);
+    ctx.lr = Core::g_app_core->GetReg(14);
+    ctx.pc = Core::g_app_core->GetPC();
+    ctx.cpsr = Core::g_app_core->GetCPSR();
 }
 
 /// Loads a CPU context
-void __KernelLoadContext(ThreadContext *ctx) {
-    Core::g_app_core->SetReg(0, ctx->reg[0]);
-    Core::g_app_core->SetReg(1, ctx->reg[1]);
-    Core::g_app_core->SetReg(2, ctx->reg[2]);
-    Core::g_app_core->SetReg(3, ctx->reg[3]);
-    Core::g_app_core->SetReg(4, ctx->reg[4]);
-    Core::g_app_core->SetReg(5, ctx->reg[5]);
-    Core::g_app_core->SetReg(6, ctx->reg[6]);
-    Core::g_app_core->SetReg(7, ctx->reg[7]);
-    Core::g_app_core->SetReg(8, ctx->reg[8]);
-    Core::g_app_core->SetReg(9, ctx->reg[9]);
-    Core::g_app_core->SetReg(10, ctx->reg[10]);
-    Core::g_app_core->SetReg(11, ctx->reg[11]);
-    Core::g_app_core->SetReg(12, ctx->reg[12]);
-    Core::g_app_core->SetReg(13, ctx->reg[13]);
-    Core::g_app_core->SetReg(14, ctx->reg[14]);
-    Core::g_app_core->SetReg(15, ctx->reg[15]);
-    Core::g_app_core->SetPC(ctx->pc);
-    Core::g_app_core->SetCPSR(ctx->cpsr);
+void __KernelLoadContext(const ThreadContext &ctx) {
+    Core::g_app_core->SetReg(0, ctx.cpu_registers[0]);
+    Core::g_app_core->SetReg(1, ctx.cpu_registers[1]);
+    Core::g_app_core->SetReg(2, ctx.cpu_registers[2]);
+    Core::g_app_core->SetReg(3, ctx.cpu_registers[3]);
+    Core::g_app_core->SetReg(4, ctx.cpu_registers[4]);
+    Core::g_app_core->SetReg(5, ctx.cpu_registers[5]);
+    Core::g_app_core->SetReg(6, ctx.cpu_registers[6]);
+    Core::g_app_core->SetReg(7, ctx.cpu_registers[7]);
+    Core::g_app_core->SetReg(8, ctx.cpu_registers[8]);
+    Core::g_app_core->SetReg(9, ctx.cpu_registers[9]);
+    Core::g_app_core->SetReg(10, ctx.cpu_registers[10]);
+    Core::g_app_core->SetReg(11, ctx.cpu_registers[11]);
+    Core::g_app_core->SetReg(12, ctx.cpu_registers[12]);
+    Core::g_app_core->SetReg(13, ctx.sp);
+    Core::g_app_core->SetReg(14, ctx.lr);
+    //Core::g_app_core->SetReg(15, ctx.pc);
+
+    Core::g_app_core->SetPC(ctx.pc);
+    Core::g_app_core->SetCPSR(ctx.cpsr);
 }
 
-/// Switches thread context
-void __KernelSwitchContext(Thread *target, const char *reason) {
-    u32 old_pc = 0;
-    UID old_uid = 0;
-    const char *old_name = g_hle_current_thread_name != NULL ? g_hle_current_thread_name : "(none)";
-    Thread *cur = __GetCurrentThread();
+/// Resets a thread
+void __KernelResetThread(Thread *t, s32 lowest_priority) {
+    memset(&t->context, 0, sizeof(ThreadContext));
 
-    if (cur) { // It might just have been deleted.
-        __KernelSaveContext(&cur->context);
-        old_pc = Core::g_app_core->GetPC();
-        old_uid = cur->GetUID();
-
-        // Normally this is taken care of in __KernelNextThread().
-        if (cur->IsRunning())
-            __KernelChangeReadyState(cur, old_uid, true);
-    }
-    if (target) {
-        __SetCurrentThread(target, target->GetUID(), target->nt.name);
-        __KernelChangeReadyState(target, g_current_thread, false);
-
-        target->nt.status = (target->nt.status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
-
-        __KernelLoadContext(&target->context);
-    } else {
-        __SetCurrentThread(NULL, 0, NULL);
+    t->context.pc = t->entry_point;
+    t->context.sp = t->stack_top;
+    
+    if (t->current_priority < lowest_priority) {
+        t->current_priority = t->initial_priority;
     }
+        
+    t->wait_type = WAITTYPE_NONE;
 }
 
-bool __KernelSwitchToThread(UID thread_id, const char *reason) {
-    if (!reason) {
-        reason = "switch to thread";
-    }
-    if (g_current_thread == thread_id) {
-        return false;
-    }
-    u32 error;
-    Thread *t = g_kernel_objects.Get<Thread>(thread_id, error);
-    if (!t) {
-        ERROR_LOG(KERNEL, "__KernelSwitchToThread: %x doesn't exist", thread_id);
-        HLE::ReSchedule("switch to deleted thread");
-    } else if (t->IsReady() || t->IsRunning()) {
-        Thread *current = __GetCurrentThread();
-        if (current && current->IsRunning()) {
-            __KernelChangeReadyState(current, g_current_thread, true);
+/// Creates a new thread
+Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority, s32 processor_id, u32 stack_top, int stack_size=0x4000) {
+    static u32 _handle_count = 1;
+    
+    Thread *t = new Thread;
+    
+    handle = (_handle_count++);
+    
+    g_thread_queue.push_back(handle);
+    g_thread_ready_queue.prepare(priority);
+    
+    t->status = THREADSTATUS_DORMANT;
+    t->entry_point = entry_point;
+    t->stack_top = stack_top;
+    t->stack_size = stack_size;
+    t->initial_priority = t->current_priority = priority;
+    t->processor_id = processor_id;
+    t->wait_type = WAITTYPE_NONE;
+    
+    strncpy(t->name, name, KERNELOBJECT_MAX_NAME_LENGTH);
+    t->name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
+    
+    return t;
+}
+
+/// Change a thread to "ready" state
+void __KernelChangeReadyState(Thread *t, bool ready) {
+    Handle handle = t->GetHandle();
+    if (t->IsReady()) {
+        if (!ready) {
+            g_thread_ready_queue.remove(t->current_priority, handle);
         }
-        __KernelSwitchContext(t, reason);
-        return true;
-    } else {
-        HLE::ReSchedule("switch to waiting thread");
-    }
-    return false;
-}
-
-/// Sets up the root (primary) thread of execution
-UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
-    UID id;
-
-    Thread *thread = __KernelCreateThread(id, module_id, "root", prio, Core::g_app_core->GetPC(),
-        arg, Memory::SCRATCHPAD_VADDR_END, 0xFFFFFFFE, stack_size=stack_size);
-
-    if (thread->current_stack.start == 0) {
-        ERROR_LOG(KERNEL, "Unable to allocate stack for root thread.");
-    }
-    __KernelResetThread(thread, 0);
-
-    Thread *prev_thread = __GetCurrentThread();
-    if (prev_thread && prev_thread->IsRunning())
-        __KernelChangeReadyState(g_current_thread, true);
-    __SetCurrentThread(thread, id, "root");
-    thread->nt.status = THREADSTATUS_RUNNING; // do not schedule
-
-    strcpy(thread->nt.name, "root");
-
-    __KernelLoadContext(&thread->context);
-    
-    // NOTE(bunnei): Not sure this is really correct, ignore args for now...
-    //Core::g_app_core->SetReg(0, args); 
-    //Core::g_app_core->SetReg(13, (args + 0xf) & ~0xf); // Setup SP - probably not correct
-    //u32 location = Core::g_app_core->GetReg(13); // SP 
-    //Core::g_app_core->SetReg(1, location);
-    
-    //if (argp)
-    //    Memory::Memcpy(location, argp, args);
-    //// Let's assume same as starting a new thread, 64 bytes for safety/kernel.
-    //Core::g_app_core->SetReg(13, Core::g_app_core->GetReg(13) - 64);
-
-    return id;
-}
-
-int __KernelRotateThreadReadyQueue(int priority) {
-    Thread *cur = __GetCurrentThread();
-
-    // 0 is special, it means "my current priority."
-    if (priority == 0) {
-        priority = cur->nt.current_priority;
-    }
-    //if (priority <= 0x07 || priority > 0x77)
-    //    return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY;
-
-    if (!g_thread_ready_queue.empty(priority)) {
-        // In other words, yield to everyone else.
-        if (cur->nt.current_priority == priority) {
-            g_thread_ready_queue.push_back(priority, g_current_thread);
-            cur->nt.status = (cur->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY;
-
-        // Yield the next thread of this priority to all other threads of same priority.
+    }  else if (ready) {
+        if (t->IsRunning()) {
+            g_thread_ready_queue.push_front(t->current_priority, handle);
         } else {
-            g_thread_ready_queue.rotate(priority);
+            g_thread_ready_queue.push_back(t->current_priority, handle);
+        }
+        t->status = THREADSTATUS_READY;
+    }
+}
+
+/// Changes a threads state
+void __KernelChangeThreadState(Thread *t, ThreadStatus new_status) {
+    if (!t || t->status == new_status) {
+        return;
+    }
+    __KernelChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0);
+    t->status = new_status;
+    
+    if (new_status == THREADSTATUS_WAIT) {
+        if (t->wait_type == WAITTYPE_NONE) {
+            printf("ERROR: Waittype none not allowed here\n");
         }
     }
-    HLE::EatCycles(250);
-    HLE::ReSchedule("rotatethreadreadyqueue");
-
-    return 0;
 }
 
+/// 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 g_kernel_objects.GetFast<Thread>(next);
+}
+
+/// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields)
+void __KernelCallThread(Thread *t) {
+    // Stop waiting
+    if (t->wait_type != WAITTYPE_NONE) {
+        t->wait_type = WAITTYPE_NONE;
+    }
+    __KernelChangeThreadState(t, THREADSTATUS_READY);
+}
+
+/// Sets up the primary application thread
+Handle __KernelSetupMainThread(s32 priority, int stack_size) {
+    Handle handle;
+    
+    // Initialize new "main" thread
+    Thread *t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 
+        0xFFFFFFFE, Memory::SCRATCHPAD_VADDR_END, stack_size);
+    
+    __KernelResetThread(t, 0);
+    
+    // If running another thread already, set it to "ready" state
+    Thread *cur = __GetCurrentThread();
+    if (cur && cur->IsRunning()) {
+        __KernelChangeReadyState(cur, true);
+    }
+    
+    // Run new "main" thread
+    __SetCurrentThread(t);
+    t->status = THREADSTATUS_RUNNING;
+    __KernelLoadContext(t->context);
+
+    return handle;
+}
+
+/// 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);
+    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();
+    if (next > 0) {
+        __KernelSwitchContext(next, reason);
+    }
+}
+
+
 void __KernelThreadingInit() {
 }
 
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 05468fb2e..cca4e85fd 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -7,50 +7,10 @@
 #include "common/common_types.h"
 #include "core/hle/kernel/kernel.h"
 
-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
-};
-
-struct ThreadContext {
-    void reset();
-
-    u32 reg[16];
-    u32 cpsr;
-    u32 pc;
-};
-
 class Thread;
 
-Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint,
-    u32 arg, u32 stack_top, u32 processor_id, int stack_size=0x4000);
-
-UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg, 
-    u32 stack_top, u32 processor_id, int stack_size=0x4000);
-
-void __KernelResetThread(Thread *t, int lowest_priority);
-void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready);
-void __KernelChangeReadyState(UID thread_id, bool ready);
-Thread* __KernelNextThread();
-void __KernelSaveContext(ThreadContext *ctx);
-void __KernelLoadContext(ThreadContext *ctx);
-void __KernelSwitchContext(Thread *target, const char *reason);
-bool __KernelSwitchToThread(UID thread_id, const char *reason);
-UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000);
-int __KernelRotateThreadReadyQueue(int priority=0);
+/// Sets up the primary application thread
+Handle __KernelSetupMainThread(s32 priority, int stack_size=0x4000);
 
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();
-
-//const char *__KernelGetThreadName(SceUID threadID);
-//
-//void __KernelSaveContext(ThreadContext *ctx);
-//void __KernelLoadContext(ThreadContext *ctx);
-
-//void __KernelSwitchContext(Thread *target, const char *reason);
\ No newline at end of file

From 3c240abf10c7f4f47cc6a8ad2ba6ee060abaa96b Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:54:57 -0400
Subject: [PATCH 20/72] added ability to load AXF files (same as ELF)

---
 src/citra_qt/main.cpp | 2 +-
 src/core/loader.cpp   | 3 +++
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/citra_qt/main.cpp b/src/citra_qt/main.cpp
index 76e0c68c3..9be982909 100644
--- a/src/citra_qt/main.cpp
+++ b/src/citra_qt/main.cpp
@@ -142,7 +142,7 @@ void GMainWindow::BootGame(const char* filename)
 
 void GMainWindow::OnMenuLoadFile()
 {
-    QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS homebrew (*.elf *.dat *.bin)"));
+    QString filename = QFileDialog::getOpenFileName(this, tr("Load file"), QString(), tr("3DS homebrew (*.elf *.axf *.dat *.bin)"));
     if (filename.size())
        BootGame(filename.toLatin1().data());
 }
diff --git a/src/core/loader.cpp b/src/core/loader.cpp
index a1f5dcdb5..444b75feb 100644
--- a/src/core/loader.cpp
+++ b/src/core/loader.cpp
@@ -187,6 +187,9 @@ FileType IdentifyFile(std::string &filename) {
     else if (!strcasecmp(extension.c_str(), ".elf")) {
         return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
     }
+    else if (!strcasecmp(extension.c_str(), ".axf")) {
+        return FILETYPE_CTR_ELF; // TODO(bunnei): Do some filetype checking :p
+    }
     else if (!strcasecmp(extension.c_str(), ".bin")) {
         return FILETYPE_CTR_BIN;
     }

From 4910b6f3369f33a2dc6728e4156a62368c2c9cb1 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 18:56:28 -0400
Subject: [PATCH 21/72] added memory mapped region for system mem - sdk demos
 load a segment here on ELF load

---
 src/core/mem_map.cpp       |  3 +++
 src/core/mem_map.h         |  7 +++++++
 src/core/mem_map_funcs.cpp | 14 +++++++++++++-
 3 files changed, 23 insertions(+), 1 deletion(-)

diff --git a/src/core/mem_map.cpp b/src/core/mem_map.cpp
index 59560b87d..c45746be9 100644
--- a/src/core/mem_map.cpp
+++ b/src/core/mem_map.cpp
@@ -17,6 +17,7 @@ u8*    g_base                   = NULL;         ///< The base pointer to the aut
 MemArena g_arena;                               ///< The MemArena class
 
 u8* g_exefs_code                = NULL;         ///< ExeFS:/.code is loaded here
+u8* g_system_mem                = NULL;         ///< System memory
 u8* g_heap                      = NULL;         ///< Application heap (main memory)
 u8* g_heap_gsp                  = NULL;         ///< GSP heap (main memory)
 u8* g_vram                      = NULL;         ///< Video memory (VRAM) pointer
@@ -27,6 +28,7 @@ u8* g_physical_bootrom          = NULL;         ///< Bootrom physical memory
 u8* g_uncached_bootrom          = NULL;
 
 u8* g_physical_exefs_code       = NULL;         ///< Phsical ExeFS:/.code is loaded here
+u8* g_physical_system_mem       = NULL;         ///< System physical memory
 u8* g_physical_fcram            = NULL;         ///< Main physical memory (FCRAM)
 u8* g_physical_heap_gsp         = NULL;         ///< GSP heap physical memory
 u8* g_physical_vram             = NULL;         ///< Video physical memory (VRAM)
@@ -39,6 +41,7 @@ static MemoryView g_views[] = {
     {&g_vram,       &g_physical_vram,       VRAM_VADDR,             VRAM_SIZE,          0},
     {&g_heap,       &g_physical_fcram,      HEAP_VADDR,             HEAP_SIZE,          MV_IS_PRIMARY_RAM},
     {&g_shared_mem, &g_physical_shared_mem, SHARED_MEMORY_VADDR,    SHARED_MEMORY_SIZE, 0},
+    {&g_system_mem, &g_physical_system_mem, SYSTEM_MEMORY_VADDR,    SYSTEM_MEMORY_SIZE,    0},
     {&g_kernel_mem, &g_physical_kernel_mem, KERNEL_MEMORY_VADDR,    KERNEL_MEMORY_SIZE, 0},
     {&g_heap_gsp,   &g_physical_heap_gsp,   HEAP_GSP_VADDR,         HEAP_GSP_SIZE,      0},
 };
diff --git a/src/core/mem_map.h b/src/core/mem_map.h
index af2212a5f..12d497ef3 100644
--- a/src/core/mem_map.h
+++ b/src/core/mem_map.h
@@ -47,6 +47,12 @@ enum {
     EXEFS_CODE_VADDR_END    = (EXEFS_CODE_VADDR + EXEFS_CODE_SIZE),
     EXEFS_CODE_MASK         = 0x03FFFFFF,
 
+    // Region of FCRAM used by system
+    SYSTEM_MEMORY_SIZE      = 0x02C00000,   ///< 44MB
+    SYSTEM_MEMORY_VADDR     = 0x04000000,
+    SYSTEM_MEMORY_VADDR_END = (SYSTEM_MEMORY_VADDR + SYSTEM_MEMORY_SIZE),
+    SYSTEM_MEMORY_MASK      = 0x03FFFFFF,
+
     HEAP_SIZE               = FCRAM_SIZE,   ///< Application heap size
     //HEAP_PADDR              = HEAP_GSP_SIZE,
     //HEAP_PADDR_END          = (HEAP_PADDR + HEAP_SIZE),
@@ -116,6 +122,7 @@ extern u8* g_heap;          ///< Application heap (main memory)
 extern u8* g_vram;          ///< Video memory (VRAM)
 extern u8* g_shared_mem;    ///< Shared memory
 extern u8* g_kernel_mem;    ///< Kernel memory
+extern u8* g_system_mem;    ///< System memory
 extern u8* g_exefs_code;    ///< ExeFS:/.code is loaded here
 
 void Init();
diff --git a/src/core/mem_map_funcs.cpp b/src/core/mem_map_funcs.cpp
index 8ab647714..86e9eaa20 100644
--- a/src/core/mem_map_funcs.cpp
+++ b/src/core/mem_map_funcs.cpp
@@ -73,6 +73,10 @@ inline void _Read(T &var, const u32 addr) {
     } else if ((vaddr >= SHARED_MEMORY_VADDR)  && (vaddr < SHARED_MEMORY_VADDR_END)) {
         var = *((const T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK]);
 
+    // System memory
+    } else if ((vaddr >= SYSTEM_MEMORY_VADDR)  && (vaddr < SYSTEM_MEMORY_VADDR_END)) {
+        var = *((const T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK]);
+
     // Config memory
     } else if ((vaddr >= CONFIG_MEMORY_VADDR)  && (vaddr < CONFIG_MEMORY_VADDR_END)) {
         ConfigMem::Read<T>(var, vaddr);
@@ -115,6 +119,10 @@ inline void _Write(u32 addr, const T data) {
     } else if ((vaddr >= SHARED_MEMORY_VADDR)  && (vaddr < SHARED_MEMORY_VADDR_END)) {
         *(T*)&g_shared_mem[vaddr & SHARED_MEMORY_MASK] = data;
 
+    // System memory
+    } else if ((vaddr >= SYSTEM_MEMORY_VADDR)  && (vaddr < SYSTEM_MEMORY_VADDR_END)) {
+         *(T*)&g_system_mem[vaddr & SYSTEM_MEMORY_MASK] = data;
+
     // VRAM
     } else if ((vaddr >= VRAM_VADDR)  && (vaddr < VRAM_VADDR_END)) {
         *(T*)&g_vram[vaddr & VRAM_MASK] = data;
@@ -153,9 +161,13 @@ u8 *GetPointer(const u32 addr) {
         return g_heap + (vaddr & HEAP_MASK);
 
     // Shared memory
-    } else if ((vaddr > SHARED_MEMORY_VADDR)  && (vaddr < SHARED_MEMORY_VADDR_END)) {
+    } else if ((vaddr >= SHARED_MEMORY_VADDR)  && (vaddr < SHARED_MEMORY_VADDR_END)) {
         return g_shared_mem + (vaddr & SHARED_MEMORY_MASK);
 
+    // System memory
+    } else if ((vaddr >= SYSTEM_MEMORY_VADDR)  && (vaddr < SYSTEM_MEMORY_VADDR_END)) {
+         return g_system_mem + (vaddr & SYSTEM_MEMORY_MASK);
+
     // VRAM
     } else if ((vaddr > VRAM_VADDR)  && (vaddr < VRAM_VADDR_END)) {
         return g_vram + (vaddr & VRAM_MASK);

From 4fba4f36bf20c2721e2602c450eafcc1117ac643 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 15 May 2014 20:17:30 -0400
Subject: [PATCH 22/72] - added SVC stubs for QueryMemory and GetThreadId

- added SVC structs MemoryInfo and PageInfo
---
 src/core/hle/function_wrappers.h |  5 +++++
 src/core/hle/syscall.cpp         | 16 ++++++++++++++--
 src/core/hle/syscall.h           | 11 +++++++++++
 3 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 83be7648b..61790e5a3 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -734,6 +734,11 @@ template<int func(void*, u32)> void WrapI_VU(){
     RETURN(retval);
 }
 
+template<int func(void*, void*, u32)> void WrapI_VVU(){
+    u32 retval = func(Memory::GetPointer(PARAM(0)), Memory::GetPointer(PARAM(1)), PARAM(2));
+    RETURN(retval);
+}
+
 template<int func(void*, u32, void*, int)> void WrapI_VUVI(){
     u32 retval = func(Memory::GetPointer(PARAM(0)), PARAM(1), Memory::GetPointer(PARAM(2)), PARAM(3));
     RETURN(retval);
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 0700d9e82..0765bce7a 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -169,10 +169,22 @@ Result ReleaseMutex(Handle handle) {
     return 0;
 }
 
+Result GetThreadId(void* thread_id, u32 thread) {
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetThreadId called thread=0x%08X", thread);
+    return 0;
+}
+
+Result QueryMemory(void *_info, void *_out, u32 addr) {
+    MemoryInfo* info = (MemoryInfo*) _info;
+    PageInfo* out = (PageInfo*) _out;
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) QueryMemory called addr=0x%08X", addr);
+    return 0;
+}
+
 const HLE::FunctionDef Syscall_Table[] = {
     {0x00,  NULL,                                       "Unknown"},
     {0x01,  WrapI_VUUUUU<ControlMemory>,                "ControlMemory"},
-    {0x02,  NULL,                                       "QueryMemory"},
+    {0x02,  WrapI_VVU<QueryMemory>,                     "QueryMemory"},
     {0x03,  NULL,                                       "ExitProcess"},
     {0x04,  NULL,                                       "GetProcessAffinityMask"},
     {0x05,  NULL,                                       "SetProcessAffinityMask"},
@@ -225,7 +237,7 @@ const HLE::FunctionDef Syscall_Table[] = {
     {0x34,  NULL,                                       "OpenThread"},
     {0x35,  NULL,                                       "GetProcessId"},
     {0x36,  NULL,                                       "GetProcessIdOfThread"},
-    {0x37,  NULL,                                       "GetThreadId"},
+    {0x37,  WrapI_VU<GetThreadId>,                      "GetThreadId"},
     {0x38,  WrapI_VU<GetResourceLimit>,                 "GetResourceLimit"},
     {0x39,  NULL,                                       "GetResourceLimitLimitValues"},
     {0x3A,  WrapI_VUVI<GetResourceLimitCurrentValues>,  "GetResourceLimitCurrentValues"},
diff --git a/src/core/hle/syscall.h b/src/core/hle/syscall.h
index 15af5e138..17f190266 100644
--- a/src/core/hle/syscall.h
+++ b/src/core/hle/syscall.h
@@ -9,6 +9,17 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // SVC structures
 
+struct MemoryInfo {
+    u32 base_address;
+    u32 size;
+    u32 permission;
+    u32 state;
+};
+
+struct PageInfo {
+    u32 flags;
+};
+
 struct ThreadContext {
     u32 cpu_registers[13];
     u32 sp;

From 540a693eae210d090b87426ead8cfac5893a9ef8 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 16 May 2014 23:23:56 -0400
Subject: [PATCH 23/72] updated APT_U::GetLockHandle to return a valid handle

---
 src/core/hle/service/apt.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
index 709ac5493..ddb975607 100644
--- a/src/core/hle/service/apt.cpp
+++ b/src/core/hle/service/apt.cpp
@@ -19,7 +19,11 @@ void Initialize(Service::Interface* self) {
 
 void GetLockHandle(Service::Interface* self) {
     u32* cmd_buff = Service::GetCommandBuffer();
-    cmd_buff[5] = 0x00000000; // TODO: This should be an actual mutex handle
+    u32 flags = cmd_buff[1];
+
+    // TODO: This should be an actual mutex handle. Games will check that this is not non-zero 
+    // (NULL), and fail if such. A faked non-zero value will at least enable further booting. 
+    cmd_buff[5] = 0xDEADBEEF;
 }
 
 const Interface::FunctionInfo FunctionTable[] = {

From 4faed70b40ae44a0a5c63366ad4e6dfa6340e73f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 16 May 2014 23:24:39 -0400
Subject: [PATCH 24/72] add kernel.* and thread.* to VS filters

---
 src/core/core.vcxproj.filters | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index edf34ce2f..6aedeb54b 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -31,6 +31,9 @@
     <Filter Include="arm\interpreter\mmu">
       <UniqueIdentifier>{13ef9860-2ba0-47e9-a93d-b4052adab269}</UniqueIdentifier>
     </Filter>
+    <Filter Include="hle\kernel">
+      <UniqueIdentifier>{8089d94b-5faa-43dc-854b-ffd2fa2e7fe3}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="arm\disassembler\arm_disasm.cpp">
@@ -153,6 +156,12 @@
     <ClCompile Include="arm\interpreter\mmu\maverick.cpp">
       <Filter>arm\interpreter\mmu</Filter>
     </ClCompile>
+    <ClCompile Include="hle\kernel\kernel.cpp">
+      <Filter>hle\kernel</Filter>
+    </ClCompile>
+    <ClCompile Include="hle\kernel\thread.cpp">
+      <Filter>hle\kernel</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -274,6 +283,12 @@
     <ClInclude Include="arm\interpreter\mmu\sa_mmu.h">
       <Filter>arm\interpreter\mmu</Filter>
     </ClInclude>
+    <ClInclude Include="hle\kernel\kernel.h">
+      <Filter>hle\kernel</Filter>
+    </ClInclude>
+    <ClInclude Include="hle\kernel\thread.h">
+      <Filter>hle\kernel</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />

From 39ee75fc8d2a3291195448696f6a9bda8b1d58ad Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 16 May 2014 23:25:16 -0400
Subject: [PATCH 25/72] added stubbed GetProcSemaphore - does nothing but
 avoids an exception

---
 src/core/hle/service/srv.cpp | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 071741444..303a943d4 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -16,6 +16,12 @@ void Initialize(Service::Interface* self) {
     NOTICE_LOG(OSHLE, "SRV::Sync - Initialize");
 }
 
+void GetProcSemaphore(Service::Interface* self) {
+    // Get process semaphore?
+    u32* cmd_buff = Service::GetCommandBuffer();
+    cmd_buff[3] = 0xDEADBEEF; // Return something... 0 == NULL, raises an exception
+}
+
 void GetServiceHandle(Service::Interface* self) {
     Syscall::Result res = 0;
     u32* cmd_buff = Service::GetCommandBuffer();
@@ -39,7 +45,7 @@ void GetServiceHandle(Service::Interface* self) {
 
 const Interface::FunctionInfo FunctionTable[] = {
     {0x00010002, Initialize,        "Initialize"},
-    {0x00020000, NULL,              "GetProcSemaphore"},
+    {0x00020000, GetProcSemaphore,  "GetProcSemaphore"},
     {0x00030100, NULL,              "RegisterService"},
     {0x000400C0, NULL,              "UnregisterService"},
     {0x00050100, GetServiceHandle,  "GetServiceHandle"},

From 7cdb70505944b2ed456d7f5376594e05f3b3357f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Fri, 16 May 2014 23:48:15 -0400
Subject: [PATCH 26/72] - replaced KERNELOBJECT_MAX_NAME_LENGTH with
 KERNEL_MAX_NAME_LENGTH

- added KERNEL_DEFAULT_STACK_SIZE definition (0x4000)
---
 src/core/hle/kernel/kernel.h   | 5 ++---
 src/core/hle/kernel/thread.cpp | 9 +++++----
 src/core/hle/kernel/thread.h   | 6 +++++-
 3 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 24d422682..2608eecc9 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -16,11 +16,10 @@ enum KernelIDType {
 };
 
 enum {
-    KERNELOBJECT_MAX_NAME_LENGTH = 255,
+    KERNEL_MAX_NAME_LENGTH      = 0x100,
+    KERNEL_DEFAULT_STACK_SIZE   = 0x4000,
 };
 
-#define KERNELOBJECT_MAX_NAME_LENGTH 31
-
 class KernelObjectPool;
 
 class KernelObject {
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 833a1b4ba..76a73747d 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -81,7 +81,7 @@ public:
 
     WaitType wait_type;
 
-    char name[KERNELOBJECT_MAX_NAME_LENGTH+1];
+    char name[KERNEL_MAX_NAME_LENGTH+1];
 };
 
 // Lists all thread ids that aren't deleted/etc.
@@ -165,7 +165,8 @@ void __KernelResetThread(Thread *t, s32 lowest_priority) {
 }
 
 /// Creates a new thread
-Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority, s32 processor_id, u32 stack_top, int stack_size=0x4000) {
+Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority, 
+    s32 processor_id, u32 stack_top, int stack_size) {
     static u32 _handle_count = 1;
     
     Thread *t = new Thread;
@@ -183,8 +184,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, KERNELOBJECT_MAX_NAME_LENGTH);
-    t->name[KERNELOBJECT_MAX_NAME_LENGTH] = '\0';
+    strncpy(t->name, name, KERNEL_MAX_NAME_LENGTH);
+    t->name[KERNEL_MAX_NAME_LENGTH] = '\0';
     
     return t;
 }
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index cca4e85fd..add6107d7 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -9,8 +9,12 @@
 
 class Thread;
 
+/// Creates a new thread
+Thread *__KernelCreateThread(Handle &handle, 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=0x4000);
+Handle __KernelSetupMainThread(s32 priority, int stack_size=KERNEL_DEFAULT_STACK_SIZE);
 
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();

From 43bc2ac724e1e1340827dd777ec4dbb6b94b4603 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 00:53:41 -0400
Subject: [PATCH 27/72] added MIN, MAX, and CLAMP macros to common_funcs

---
 src/common/common_funcs.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index f8d10eb3e..dca4dc47f 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -22,6 +22,11 @@ template<> struct CompileTimeAssert<true> {};
 #define b32(x)  (b16(x) | (b16(x) >>16) )
 #define ROUND_UP_POW2(x)    (b32(x - 1) + 1)
 
+#define MIN(a, b)   ((a)<(b)?(a):(b))
+#define MAX(a, b)   ((a)>(b)?(a):(b))
+
+#define CLAMP(x, min, max)  (((x) > max) ? max : (((x) < min) ? min : (x)))
+
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
 
 #ifndef _WIN32

From 14ae026386cf3f984d60401e2104165c3ca3266b Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 00:56:00 -0400
Subject: [PATCH 28/72] - added enum ThreadProcessorId

- reorganized some kernel thread functions
- added placeholder __KernelWaitThread_Synchronization function
---
 src/core/hle/kernel/thread.cpp | 141 +++++++++++++++++++++------------
 src/core/hle/kernel/thread.h   |  19 ++++-
 2 files changed, 107 insertions(+), 53 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 76a73747d..b967b3c62 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -21,20 +21,14 @@
 
 // Enums
 
-enum ThreadPriority {
-    THREADPRIO_HIGHEST = 0,
-    THREADPRIO_DEFAULT = 16,
-    THREADPRIO_LOWEST = 31,
-};
-
 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
+    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 {
@@ -46,8 +40,6 @@ enum WaitType {
     WAITTYPE_VBLANK,
     WAITTYPE_MUTEX,
     WAITTYPE_SYNCH,
-    
-    NUM_WAITTYPES
 };
 
 typedef s32 Handle;
@@ -164,32 +156,6 @@ void __KernelResetThread(Thread *t, s32 lowest_priority) {
     t->wait_type = WAITTYPE_NONE;
 }
 
-/// Creates a new thread
-Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority, 
-    s32 processor_id, u32 stack_top, int stack_size) {
-    static u32 _handle_count = 1;
-    
-    Thread *t = new Thread;
-    
-    handle = (_handle_count++);
-    
-    g_thread_queue.push_back(handle);
-    g_thread_ready_queue.prepare(priority);
-    
-    t->status = THREADSTATUS_DORMANT;
-    t->entry_point = entry_point;
-    t->stack_top = stack_top;
-    t->stack_size = stack_size;
-    t->initial_priority = t->current_priority = priority;
-    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';
-    
-    return t;
-}
-
 /// Change a thread to "ready" state
 void __KernelChangeReadyState(Thread *t, bool ready) {
     Handle handle = t->GetHandle();
@@ -222,6 +188,79 @@ 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) {
+    // Stop waiting
+    if (t->wait_type != WAITTYPE_NONE) {
+        t->wait_type = WAITTYPE_NONE;
+    }
+    __KernelChangeThreadState(t, THREADSTATUS_READY);
+}
+
+/// Creates a new thread
+Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority,
+    s32 processor_id, u32 stack_top, int stack_size) {
+
+    Thread *t = new Thread;
+    
+    handle = g_kernel_objects.Create(t);
+    
+    g_thread_queue.push_back(handle);
+    g_thread_ready_queue.prepare(priority);
+    
+    t->status = THREADSTATUS_DORMANT;
+    t->entry_point = entry_point;
+    t->stack_top = stack_top;
+    t->stack_size = stack_size;
+    t->initial_priority = t->current_priority = priority;
+    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';
+    
+    return t;
+}
+
+/// 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) {
+    if (name == NULL) {
+        ERROR_LOG(KERNEL, "__KernelCreateThread(): NULL name");
+        return -1;
+    }
+    if ((u32)stack_size < 0x200) {
+        ERROR_LOG(KERNEL, "__KernelCreateThread(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",
+            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);
+        return -1;
+    }
+    Handle handle;
+    Thread *t = __KernelCreateThread(handle, name, entry_point, priority, processor_id, stack_top, 
+        stack_size);
+
+    HLE::EatCycles(32000);
+
+    // This won't schedule to the new thread, but it may to one woken from eating cycles.
+    // Technically, this should not eat all at once, and reschedule in the middle, but that's hard.
+    HLE::ReSchedule("thread created");
+
+    __KernelCallThread(t);
+    
+    return handle;
+}
+
 /// Switches CPU context to that of the specified thread
 void __KernelSwitchContext(Thread* t, const char *reason) {
     Thread *cur = __GetCurrentThread();
@@ -262,22 +301,13 @@ Thread *__KernelNextThread() {
     return g_kernel_objects.GetFast<Thread>(next);
 }
 
-/// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields)
-void __KernelCallThread(Thread *t) {
-    // Stop waiting
-    if (t->wait_type != WAITTYPE_NONE) {
-        t->wait_type = WAITTYPE_NONE;
-    }
-    __KernelChangeThreadState(t, THREADSTATUS_READY);
-}
-
 /// Sets up the primary application thread
 Handle __KernelSetupMainThread(s32 priority, int stack_size) {
     Handle handle;
     
     // Initialize new "main" thread
     Thread *t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 
-        0xFFFFFFFE, Memory::SCRATCHPAD_VADDR_END, stack_size);
+        THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
     
     __KernelResetThread(t, 0);
     
@@ -322,6 +352,15 @@ void __KernelReschedule(const char *reason) {
     }
 }
 
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+/// Wait thread - on WaitSynchronization
+void __KernelWaitThread_Synchronization() {
+    // TODO(bunnei): Just a placeholder function for now... FixMe
+    __KernelWaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called");
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void __KernelThreadingInit() {
 }
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index add6107d7..8138be26f 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -9,8 +9,20 @@
 
 class Thread;
 
-/// Creates a new thread
-Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority, 
+enum ThreadPriority {
+    THREADPRIO_HIGHEST      = 0,
+    THREADPRIO_DEFAULT      = 16,
+    THREADPRIO_LOWEST       = 31,
+};
+
+enum ThreadProcessorId {
+    THREADPROCESSORID_0     = 0xFFFFFFFE,
+    THREADPROCESSORID_1     = 0xFFFFFFFD,
+    THREADPROCESSORID_ALL   = 0xFFFFFFFC,
+};
+
+/// 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);
 
 /// Sets up the primary application thread
@@ -18,3 +30,6 @@ Handle __KernelSetupMainThread(s32 priority, int stack_size=KERNEL_DEFAULT_STACK
 
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();
+
+/// Wait thread - on WaitSynchronization
+void __KernelWaitThread_Synchronization();

From cfea5fdd5878968e8a1de99b86966c57d0fc5697 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 13:47:44 -0400
Subject: [PATCH 29/72] cleanups to SVC CreateThread

---
 src/core/hle/syscall.cpp | 23 +++++++++++++++--------
 1 file changed, 15 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 0765bce7a..0c78b19fb 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -6,6 +6,9 @@
 
 #include "core/mem_map.h"
 
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/thread.h"
+
 #include "core/hle/function_wrappers.h"
 #include "core/hle/syscall.h"
 #include "core/hle/service/service.h"
@@ -140,19 +143,23 @@ Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void*
     return 0;
 }
 
-Result CreateThread(void* thread, u32 thread_priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
-    std::string thread_name;
+Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 stack_top, 
+    u32 processor_id) {
+    std::string name;
     if (Symbols::HasSymbol(entry_point)) {
         TSymbol symbol = Symbols::GetSymbol(entry_point);
-        thread_name = symbol.name;
+        name = symbol.name;
     } else {
         char buff[100];
-        sprintf(buff, "%s", "unk-%08X", entry_point);
-        thread_name = buff;
+        sprintf(buff, "%s", "unknown-%08X", entry_point);
+        name = buff;
     }
-    DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, "
-        "stacktop=0x%08X, threadpriority=0x%08X, processorid=0x%08X", entry_point, 
-        thread_name.c_str(), arg, stack_top, thread_priority, processor_id);
+    DEBUG_LOG(SVC, "CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
+        "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, 
+        stack_top);
 
     return 0;
 }

From 09b8e8fb6afbbcc3dd6127ee02f7ac1611eb85aa Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 13:47:55 -0400
Subject: [PATCH 30/72] changed a comment

---
 src/core/hle/kernel/thread.cpp | 2 +-
 src/core/hle/kernel/thread.h   | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index b967b3c62..d0bc9c8d8 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -354,7 +354,7 @@ void __KernelReschedule(const char *reason) {
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-/// Wait thread - on WaitSynchronization
+/// Put current thread in a wait state - on WaitSynchronization
 void __KernelWaitThread_Synchronization() {
     // TODO(bunnei): Just a placeholder function for now... FixMe
     __KernelWaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called");
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 8138be26f..0d0f46500 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -31,5 +31,5 @@ Handle __KernelSetupMainThread(s32 priority, int stack_size=KERNEL_DEFAULT_STACK
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();
 
-/// Wait thread - on WaitSynchronization
+/// Put current thread in a wait state - on WaitSynchronization
 void __KernelWaitThread_Synchronization();

From fbc04ad0c7c2bafde1b7b50957799c7bbab8f77b Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 13:48:27 -0400
Subject: [PATCH 31/72] ignore thumbemu 0xDEADCODE debugging catch on MCR

---
 src/core/arm/interpreter/armemu.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index 32e315f4b..aa1ff17bb 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -4478,8 +4478,7 @@ ARMul_Emulate26 (ARMul_State * state)
                                  isize) &
                                 R15PCBITS));
 #endif
-                    }
-                    else
+                    } else if (instr != 0xDEADC0DE) // thumbemu uses 0xDEADCODE for debugging to catch non updates 
                         ARMul_MCR (state, instr,
                                DEST);
                 }

From 6a6c7eeccbf2e9a766ad6b942f25b3ef6e008944 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sat, 17 May 2014 23:37:25 -0400
Subject: [PATCH 32/72] added stubbed function for WaitSynchronizationN

---
 src/core/hle/function_wrappers.h |  7 ++++++-
 src/core/hle/syscall.cpp         | 16 +++++++++++++---
 2 files changed, 19 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/function_wrappers.h b/src/core/hle/function_wrappers.h
index 61790e5a3..24cc74fc6 100644
--- a/src/core/hle/function_wrappers.h
+++ b/src/core/hle/function_wrappers.h
@@ -750,6 +750,11 @@ template<int func(void*, u32, u32, u32, u32, u32)> void WrapI_VUUUUU(){
 }
 
 template<int func(u32, s64)> void WrapI_US64() {
-    int retval = func(PARAM(0), PARAM64(2));
+    int retval = func(PARAM(0), PARAM64(1));
+    RETURN(retval);
+}
+
+template<int func(void*, void*, u32, u32, s64)> void WrapI_VVUUS64() {
+    int retval = func(Memory::GetPointer(PARAM(0)), Memory::GetPointer(PARAM(1)), PARAM(2), PARAM(3), PARAM(4));
     RETURN(retval);
 }
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 0c78b19fb..728679378 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -104,10 +104,20 @@ Result CloseHandle(Handle handle) {
 }
 
 /// Wait for a handle to synchronize, timeout after the specified nanoseconds
-Result WaitSynchronization1(Handle handle, s64 nanoseconds) {
+Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
     // ImplementMe
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", 
-        handle, nanoseconds);
+        handle, nano_seconds);
+    return 0;
+}
+
+/// Wait for the given handles to synchronize, timeout after the specified nanoseconds
+Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wait_all, s64 nano_seconds) {
+    s32* out = (s32*)_out;
+    Handle* handles = (Handle*)_handles;
+    // ImplementMe
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%d, nanoseconds=%d", 
+        handle_count, wait_all, nano_seconds);    
     return 0;
 }
 
@@ -226,7 +236,7 @@ const HLE::FunctionDef Syscall_Table[] = {
     {0x22,  NULL,                                       "ArbitrateAddress"},
     {0x23,  WrapI_U<CloseHandle>,                       "CloseHandle"},
     {0x24,  WrapI_US64<WaitSynchronization1>,           "WaitSynchronization1"},
-    {0x25,  NULL,                                       "WaitSynchronizationN"},
+    {0x25,  WrapI_VVUUS64<WaitSynchronizationN>,        "WaitSynchronizationN"},
     {0x26,  NULL,                                       "SignalAndWait"},
     {0x27,  NULL,                                       "DuplicateHandle"},
     {0x28,  NULL,                                       "GetSystemTick"},

From 8fba88d5d59ad4cd89a343e1562a314874bd88a4 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 17:52:02 -0400
Subject: [PATCH 33/72] - added stub for CreateEvent

- changed some stubbed SVCs to return unique handle names for debugging purposes
---
 src/core/hle/syscall.cpp | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 728679378..047d8c40f 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -3,6 +3,9 @@
 // Refer to the license.txt file included.  
 
 #include <map>
+#include <string>
+
+#include "common/symbols.h"
 
 #include "core/mem_map.h"
 
@@ -14,8 +17,6 @@
 #include "core/hle/service/service.h"
 #include "core/hle/kernel/thread.h"
 
-#include "common/symbols.h"
-
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace Syscall
 
@@ -81,7 +82,6 @@ Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherper
 
 /// Connect to an OS service given the port name, returns the handle to the port to out
 Result ConnectToPort(void* out, const char* port_name) {
-    
     Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
     Core::g_app_core->SetReg(1, service->GetUID());
     DEBUG_LOG(SVC, "ConnectToPort called port_name=%s", port_name);
@@ -116,8 +116,13 @@ Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wa
     s32* out = (s32*)_out;
     Handle* handles = (Handle*)_handles;
     // ImplementMe
-    DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%d, nanoseconds=%d", 
-        handle_count, wait_all, nano_seconds);    
+    
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d %s", 
+        handle_count, (wait_all ? "true" : "false"), nano_seconds);
+    
+    for (int i = 0; i < handle_count; i++) {
+        DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]);
+    }
     return 0;
 }
 
@@ -125,7 +130,7 @@ Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wa
 Result CreateAddressArbiter(void* arbiter) {
     // ImplementMe
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateAddressArbiter called");
-    Core::g_app_core->SetReg(1, 0xDEADBEEF);
+    Core::g_app_core->SetReg(1, 0xFABBDADD);
     return 0;
 }
 
@@ -170,7 +175,8 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st
 
     Handle handle = __KernelCreateThread(name.c_str(), entry_point, priority, processor_id, 
         stack_top);
-
+    Core::g_app_core->SetReg(1, 0xFEEDDEAF);
+    
     return 0;
 }
 
@@ -178,6 +184,7 @@ Result CreateMutex(void* _mutex, u32 initial_locked) {
     Handle* mutex = (Handle*)_mutex;
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateMutex called initial_locked=%s", 
         initial_locked ? "true" : "false");
+    Core::g_app_core->SetReg(1, 0xF00D0BAD);
     return 0;
 }
 
@@ -198,6 +205,13 @@ Result QueryMemory(void *_info, void *_out, u32 addr) {
     return 0;
 }
 
+Result CreateEvent(void* _event, u32 reset_type) {
+    Handle* event = (Handle*)_event;
+    DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateEvent called reset_type=0x%08X", reset_type);
+    Core::g_app_core->SetReg(1, 0xBADC0DE0);
+    return 0;
+}
+
 const HLE::FunctionDef Syscall_Table[] = {
     {0x00,  NULL,                                       "Unknown"},
     {0x01,  WrapI_VUUUUU<ControlMemory>,                "ControlMemory"},
@@ -222,7 +236,7 @@ const HLE::FunctionDef Syscall_Table[] = {
     {0x14,  WrapI_U<ReleaseMutex>,                      "ReleaseMutex"},
     {0x15,  NULL,                                       "CreateSemaphore"},
     {0x16,  NULL,                                       "ReleaseSemaphore"},
-    {0x17,  NULL,                                       "CreateEvent"},
+    {0x17,  WrapI_VU<CreateEvent>,                      "CreateEvent"},
     {0x18,  NULL,                                       "SignalEvent"},
     {0x19,  NULL,                                       "ClearEvent"},
     {0x1A,  NULL,                                       "CreateTimer"},

From 772abad77803809d8ee857efc0d7e29c36c6b2cb Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 18:12:29 -0400
Subject: [PATCH 34/72] - moved Handle/Result definitions to kernel.h

- added ResetType enum
---
 src/core/hle/kernel/kernel.h   |  3 ++-
 src/core/hle/kernel/thread.cpp |  2 --
 src/core/hle/service/service.h | 12 +++++++-----
 src/core/hle/service/srv.cpp   |  2 +-
 src/core/hle/service/srv.h     |  2 +-
 src/core/hle/syscall.h         | 12 ++++++++----
 6 files changed, 19 insertions(+), 14 deletions(-)

diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 2608eecc9..d4bb28c72 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -6,7 +6,8 @@
 
 #include "common/common_types.h"
 
-typedef s32 Handle;
+typedef u32 Handle;
+typedef s32 Result;
 
 enum KernelIDType {
     KERNEL_ID_TYPE_THREAD       = 1,
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index d0bc9c8d8..634218e8b 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -42,8 +42,6 @@ enum WaitType {
     WAITTYPE_SYNCH,
 };
 
-typedef s32 Handle;
-
 class Thread : public KernelObject {
 public:
 
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index b260a290a..026e3d5de 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -11,6 +11,8 @@
 #include "common/common.h"
 #include "common/common_types.h"
 #include "core/mem_map.h"
+
+#include "core/hle/kernel/kernel.h"
 #include "core/hle/syscall.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -70,14 +72,14 @@ public:
     }
 
     /// Allocates a new handle for the service
-    Syscall::Handle NewHandle() {
-        Syscall::Handle handle = (m_handles.size() << 16) | m_uid;
+    Handle NewHandle() {
+        Handle handle = (m_handles.size() << 16) | m_uid;
         m_handles.push_back(handle);
         return handle;
     }
 
     /// Frees a handle from the service
-    void DeleteHandle(Syscall::Handle handle) {
+    void DeleteHandle(Handle handle) {
         for(auto iter = m_handles.begin(); iter != m_handles.end(); ++iter) {
             if(*iter == handle) {
                 m_handles.erase(iter);
@@ -90,7 +92,7 @@ public:
      * Called when svcSendSyncRequest is called, loads command buffer and executes comand
      * @return Return result of svcSendSyncRequest passed back to user app
      */
-    Syscall::Result Sync() {
+    Result Sync() {
         u32* cmd_buff = GetCommandBuffer();
         auto itr = m_functions.find(cmd_buff[0]);
 
@@ -124,7 +126,7 @@ protected:
 private:
     u32 m_uid;
     
-    std::vector<Syscall::Handle>    m_handles;
+    std::vector<Handle>    m_handles;
     std::map<u32, FunctionInfo>     m_functions;
 };
 
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index 303a943d4..a3d041176 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -23,7 +23,7 @@ void GetProcSemaphore(Service::Interface* self) {
 }
 
 void GetServiceHandle(Service::Interface* self) {
-    Syscall::Result res = 0;
+    Result res = 0;
     u32* cmd_buff = Service::GetCommandBuffer();
 
     std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize);
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h
index 760c976b4..f465ebc06 100644
--- a/src/core/hle/service/srv.h
+++ b/src/core/hle/service/srv.h
@@ -30,7 +30,7 @@ public:
      * Called when svcSendSyncRequest is called, loads command buffer and executes comand
      * @return Return result of svcSendSyncRequest passed back to user app
      */
-    Syscall::Result Sync();
+    Result Sync();
 
 };
 
diff --git a/src/core/hle/syscall.h b/src/core/hle/syscall.h
index 17f190266..3da349ed5 100644
--- a/src/core/hle/syscall.h
+++ b/src/core/hle/syscall.h
@@ -7,7 +7,7 @@
 #include "common/common_types.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-// SVC structures
+// SVC types
 
 struct MemoryInfo {
     u32 base_address;
@@ -31,14 +31,18 @@ struct ThreadContext {
     u32 fpexc;
 };
 
+enum ResetType {
+    RESETTYPE_ONESHOT,
+    RESETTYPE_STICKY,
+    RESETTYPE_PULSE,
+    RESETTYPE_MAX_BIT = (1u << 31),
+};
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace Syscall
 
 namespace Syscall {
 
-typedef u32 Handle;
-typedef s32 Result;
-
 void Register();
 
 } // namespace

From 725d240bf7b9cb48de7a66f8696695ef7aabc889 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 18:24:24 -0400
Subject: [PATCH 35/72] renamed "UID" to "Handle" where appropriate

---
 src/core/hle/service/service.cpp | 16 ++++++++--------
 src/core/hle/service/service.h   | 22 ++++++++++------------
 src/core/hle/service/srv.cpp     |  4 ++--
 src/core/hle/syscall.cpp         |  4 ++--
 4 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index e6605a398..5601e59a1 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -32,27 +32,27 @@ Manager::~Manager() {
 /// Add a service to the manager (does not create it though)
 void Manager::AddService(Interface* service) {
     int index = m_services.size();
-    u32 new_uid = GetUIDFromIndex(index);
+    Handle handle = GetHandleFromIndex(index);
 
     m_services.push_back(service);
 
-    m_port_map[service->GetPortName()] = new_uid;
-    service->m_uid = new_uid;
+    m_port_map[service->GetPortName()] = handle;
+    service->m_handle = handle;
 }
 
 /// Removes a service from the manager, also frees memory
 void Manager::DeleteService(std::string port_name) {
     auto service = FetchFromPortName(port_name);
 
-    m_services.erase(m_services.begin() + GetIndexFromUID(service->m_uid));
+    m_services.erase(m_services.begin() + GetIndexFromHandle(service->m_handle));
     m_port_map.erase(port_name);
 
     delete service;
 }
 
-/// Get a Service Interface from its UID
-Interface* Manager::FetchFromUID(u32 uid) {
-    int index = GetIndexFromUID(uid);
+/// Get a Service Interface from its Handle
+Interface* Manager::FetchFromHandle(Handle handle) {
+    int index = GetIndexFromHandle(handle);
     if (index < (int)m_services.size()) {
         return m_services[index];
     }
@@ -65,7 +65,7 @@ Interface* Manager::FetchFromPortName(std::string port_name) {
     if (itr == m_port_map.end()) {
         return NULL;
     }
-    return FetchFromUID(itr->second);
+    return FetchFromHandle(itr->second);
 }
 
 
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 026e3d5de..c3dbd202f 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -20,8 +20,6 @@
 
 namespace Service {
 
-typedef s32 NativeUID;                          ///< Native handle for a service
-
 static const int kMaxPortSize           = 0x08; ///< Maximum size of a port name (8 characters)
 static const int kCommandHeaderOffset   = 0x80; ///< Offset into command buffer of header
 
@@ -56,11 +54,11 @@ public:
     };
 
     /**
-     * Gets the UID for the serice
-     * @return UID of service in native format
+     * Gets the Handle for the serice
+     * @return Handle of service in native format
      */
-    NativeUID GetUID() const {
-        return (NativeUID)m_uid;
+    Handle GetHandle() const {
+        return m_handle;
     }
 
     /**
@@ -73,7 +71,7 @@ public:
 
     /// Allocates a new handle for the service
     Handle NewHandle() {
-        Handle handle = (m_handles.size() << 16) | m_uid;
+        Handle handle = (m_handles.size() << 16) | m_handle;
         m_handles.push_back(handle);
         return handle;
     }
@@ -124,7 +122,7 @@ protected:
     }
 
 private:
-    u32 m_uid;
+    u32 m_handle;
     
     std::vector<Handle>    m_handles;
     std::map<u32, FunctionInfo>     m_functions;
@@ -145,7 +143,7 @@ public:
     void DeleteService(std::string port_name);
 
     /// Get a Service Interface from its UID
-    Interface* FetchFromUID(u32 uid);
+    Interface* FetchFromHandle(u32 uid);
 
     /// Get a Service Interface from its port
     Interface* FetchFromPortName(std::string port_name);
@@ -153,13 +151,13 @@ public:
 private:
 
     /// Convert an index into m_services vector into a UID
-    static u32 GetUIDFromIndex(const int index) {
+    static Handle GetHandleFromIndex(const int index) {
         return index | 0x10000000;
     }
 
     /// Convert a UID into an index into m_services
-    static int GetIndexFromUID(const u32 uid) {
-        return uid & 0x0FFFFFFF;
+    static int GetIndexFromHandle(const Handle handle) {
+        return handle & 0x0FFFFFFF;
     }
 
     std::vector<Interface*>     m_services;
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp
index a3d041176..ff6da8f1c 100644
--- a/src/core/hle/service/srv.cpp
+++ b/src/core/hle/service/srv.cpp
@@ -30,10 +30,10 @@ void GetServiceHandle(Service::Interface* self) {
     Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
 
     NOTICE_LOG(OSHLE, "SRV::Sync - GetHandle - port: %s, handle: 0x%08X", port_name.c_str(), 
-        service->GetUID());
+        service->GetHandle());
 
     if (NULL != service) {
-        cmd_buff[3] = service->GetUID();
+        cmd_buff[3] = service->GetHandle();
     } else {
         ERROR_LOG(OSHLE, "Service %s does not exist", port_name.c_str());
         res = -1;
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 047d8c40f..1d7daf95c 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -83,7 +83,7 @@ Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherper
 /// Connect to an OS service given the port name, returns the handle to the port to out
 Result ConnectToPort(void* out, const char* port_name) {
     Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
-    Core::g_app_core->SetReg(1, service->GetUID());
+    Core::g_app_core->SetReg(1, service->GetHandle());
     DEBUG_LOG(SVC, "ConnectToPort called port_name=%s", port_name);
     return 0;
 }
@@ -91,7 +91,7 @@ Result ConnectToPort(void* out, const char* port_name) {
 /// Synchronize to an OS service
 Result SendSyncRequest(Handle session) {
     DEBUG_LOG(SVC, "SendSyncRequest called session=0x%08X");
-    Service::Interface* service = Service::g_manager->FetchFromUID(session);
+    Service::Interface* service = Service::g_manager->FetchFromHandle(session);
     service->Sync();
     return 0;
 }

From eab6fd01d7d2e9b7434a8c5654d424cb563c3784 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 21:43:29 -0400
Subject: [PATCH 36/72] - updated service(s) to be KernelObject's

- various cleanups
---
 src/core/hle/kernel/kernel.h     |  9 +++---
 src/core/hle/service/apt.h       |  2 +-
 src/core/hle/service/gsp.h       |  2 +-
 src/core/hle/service/hid.h       |  2 +-
 src/core/hle/service/service.cpp | 22 +++++---------
 src/core/hle/service/service.h   | 51 ++++++++++----------------------
 src/core/hle/service/srv.h       |  2 +-
 7 files changed, 31 insertions(+), 59 deletions(-)

diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index d4bb28c72..8f2b7b36d 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -10,10 +10,11 @@ typedef u32 Handle;
 typedef s32 Result;
 
 enum KernelIDType {
-    KERNEL_ID_TYPE_THREAD       = 1,
-    KERNEL_ID_TYPE_SEMAPHORE    = 2,
-    KERNEL_ID_TYPE_MUTEX        = 3,
-    KERNEL_ID_TYPE_EVENT        = 4,
+    KERNEL_ID_TYPE_THREAD,
+    KERNEL_ID_TYPE_SEMAPHORE,
+    KERNEL_ID_TYPE_MUTEX,
+    KERNEL_ID_TYPE_EVENT,
+    KERNEL_ID_TYPE_SERVICE,
 };
 
 enum {
diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h
index 4c7dd07e7..dca3097ed 100644
--- a/src/core/hle/service/apt.h
+++ b/src/core/hle/service/apt.h
@@ -29,7 +29,7 @@ public:
      * Gets the string port name used by CTROS for the service
      * @return Port name of service
      */
-    std::string GetPortName() const {
+    const char *GetPortName() const {
         return "APT:U";
     }
 };
diff --git a/src/core/hle/service/gsp.h b/src/core/hle/service/gsp.h
index 5ba09ab70..eb5786cd1 100644
--- a/src/core/hle/service/gsp.h
+++ b/src/core/hle/service/gsp.h
@@ -23,7 +23,7 @@ public:
      * Gets the string port name used by CTROS for the service
      * @return Port name of service
      */
-    std::string GetPortName() const {
+    const char *GetPortName() const {
         return "gsp::Gpu";
     }
 
diff --git a/src/core/hle/service/hid.h b/src/core/hle/service/hid.h
index b17fcfa86..81c29eb2e 100644
--- a/src/core/hle/service/hid.h
+++ b/src/core/hle/service/hid.h
@@ -25,7 +25,7 @@ public:
      * Gets the string port name used by CTROS for the service
      * @return Port name of service
      */
-    std::string GetPortName() const {
+    const char *GetPortName() const {
         return "hid:USER";
     }
 
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 5601e59a1..b3e414e0f 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -7,12 +7,15 @@
 #include "common/string_util.h"
 
 #include "core/hle/hle.h"
+
 #include "core/hle/service/service.h"
 #include "core/hle/service/apt.h"
 #include "core/hle/service/gsp.h"
 #include "core/hle/service/hid.h"
 #include "core/hle/service/srv.h"
 
+#include "core/hle/kernel/kernel.h"
+
 namespace Service {
 
 Manager* g_manager = NULL;  ///< Service manager
@@ -31,32 +34,21 @@ Manager::~Manager() {
 
 /// Add a service to the manager (does not create it though)
 void Manager::AddService(Interface* service) {
-    int index = m_services.size();
-    Handle handle = GetHandleFromIndex(index);
-
+    m_port_map[service->GetPortName()] = g_kernel_objects.Create(service);
     m_services.push_back(service);
-
-    m_port_map[service->GetPortName()] = handle;
-    service->m_handle = handle;
 }
 
 /// Removes a service from the manager, also frees memory
 void Manager::DeleteService(std::string port_name) {
-    auto service = FetchFromPortName(port_name);
-
-    m_services.erase(m_services.begin() + GetIndexFromHandle(service->m_handle));
+    Interface* service = FetchFromPortName(port_name);
+    m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end());
     m_port_map.erase(port_name);
-
     delete service;
 }
 
 /// Get a Service Interface from its Handle
 Interface* Manager::FetchFromHandle(Handle handle) {
-    int index = GetIndexFromHandle(handle);
-    if (index < (int)m_services.size()) {
-        return m_services[index];
-    }
-    return NULL;
+    return g_kernel_objects.GetFast<Interface>(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 c3dbd202f..35735a00b 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -4,6 +4,7 @@
 
 #pragma once
 
+#include <algorithm>
 #include <vector>
 #include <map>
 #include <string>
@@ -35,15 +36,15 @@ inline static u32* GetCommandBuffer(const int offset=0) {
 class Manager;
 
 /// Interface to a CTROS service
-class Interface : NonCopyable {
+class Interface  : public KernelObject {
     friend class Manager;
 public:
+    
+    const char *GetName() { return GetPortName(); }
+    const char *GetTypeName() { return GetPortName(); }
 
-    Interface() {
-    }
-
-    virtual ~Interface() {
-    }
+    static KernelIDType GetStaticIDType() { return KERNEL_ID_TYPE_THREAD; }
+    KernelIDType GetIDType() const { return KERNEL_ID_TYPE_THREAD; }
 
     typedef void (*Function)(Interface*);
 
@@ -53,37 +54,24 @@ public:
         std::string name;
     };
 
-    /**
-     * Gets the Handle for the serice
-     * @return Handle of service in native format
-     */
-    Handle GetHandle() const {
-        return m_handle;
-    }
-
     /**
      * Gets the string name used by CTROS for a service
      * @return Port name of service
      */
-    virtual std::string GetPortName() const {
+    virtual const char *GetPortName() const {
         return "[UNKNOWN SERVICE PORT]";
     }
 
     /// Allocates a new handle for the service
     Handle NewHandle() {
-        Handle handle = (m_handles.size() << 16) | m_handle;
+        Handle handle = (m_handles.size() << 16) | 0;//m_handle;
         m_handles.push_back(handle);
         return handle;
     }
 
     /// Frees a handle from the service
     void DeleteHandle(Handle handle) {
-        for(auto iter = m_handles.begin(); iter != m_handles.end(); ++iter) {
-            if(*iter == handle) {
-                m_handles.erase(iter);
-                break;
-            }
-        }
+        m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
     }
 
     /**
@@ -96,12 +84,12 @@ public:
 
         if (itr == m_functions.end()) {
             ERROR_LOG(OSHLE, "Unknown/unimplemented function: port = %s, command = 0x%08X!", 
-                GetPortName().c_str(), cmd_buff[0]);
+                GetPortName(), cmd_buff[0]);
             return -1;
         }
         if (itr->second.func == NULL) {
             ERROR_LOG(OSHLE, "Unimplemented function: port = %s, name = %s!", 
-                GetPortName().c_str(), itr->second.name.c_str());
+                GetPortName(), itr->second.name.c_str());
             return -1;
         } 
 
@@ -122,10 +110,10 @@ protected:
     }
 
 private:
-    u32 m_handle;
-    
+
     std::vector<Handle>    m_handles;
     std::map<u32, FunctionInfo>     m_functions;
+
 };
 
 /// Simple class to manage accessing services from ports and UID handles
@@ -150,18 +138,9 @@ public:
 
 private:
 
-    /// Convert an index into m_services vector into a UID
-    static Handle GetHandleFromIndex(const int index) {
-        return index | 0x10000000;
-    }
-
-    /// Convert a UID into an index into m_services
-    static int GetIndexFromHandle(const Handle handle) {
-        return handle & 0x0FFFFFFF;
-    }
-
     std::vector<Interface*>     m_services;
     std::map<std::string, u32>  m_port_map;
+
 };
 
 /// Initialize ServiceManager
diff --git a/src/core/hle/service/srv.h b/src/core/hle/service/srv.h
index f465ebc06..1e35032ba 100644
--- a/src/core/hle/service/srv.h
+++ b/src/core/hle/service/srv.h
@@ -22,7 +22,7 @@ public:
      * Gets the string name used by CTROS for the service
      * @return Port name of service
      */
-    std::string GetPortName() const {
+    const char *GetPortName() const {
         return "srv:";
     }
 

From 16d55842c561dea86ef79049abb00dafa76b08ef Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 21:43:41 -0400
Subject: [PATCH 37/72] fix warning

---
 src/core/hle/syscall.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 1d7daf95c..84c247ae3 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -120,7 +120,7 @@ Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wa
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d %s", 
         handle_count, (wait_all ? "true" : "false"), nano_seconds);
     
-    for (int i = 0; i < handle_count; i++) {
+    for (u32 i = 0; i < handle_count; i++) {
         DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]);
     }
     return 0;

From 112904b832210d7b8d165988643acae2f68793e7 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 22:09:08 -0400
Subject: [PATCH 38/72] - renamed NewHandle to CreateHandle

- updated CreateHandle/DeleteHandle to use KernelObject's
---
 src/core/hle/service/gsp.cpp   |  4 +---
 src/core/hle/service/service.h | 12 +++++++-----
 2 files changed, 8 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/service/gsp.cpp b/src/core/hle/service/gsp.cpp
index 12c7dabcd..50cee2c41 100644
--- a/src/core/hle/service/gsp.cpp
+++ b/src/core/hle/service/gsp.cpp
@@ -27,7 +27,7 @@ union GX_CmdBufferHeader {
     // <=15 when writing a command to shared memory. This is incremented by the application when 
     // writing a command to shared memory, after increasing this value TriggerCmdReqQueue is only 
     // used if this field is value 1.
-    BitField<8,8,u32>  number_commands;
+    BitField<8,8,u32>   number_commands;
 
 };
 
@@ -101,9 +101,7 @@ void RegisterInterruptRelayQueue(Service::Interface* self) {
     u32* cmd_buff = Service::GetCommandBuffer();
     u32 flags = cmd_buff[1];
     u32 event_handle = cmd_buff[3]; // TODO(bunnei): Implement event handling
-    
     cmd_buff[2] = g_thread_id;          // ThreadID
-    cmd_buff[4] = self->NewHandle();
 }
 
 /// This triggers handling of the GX command written to the command buffer in shared memory.
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 35735a00b..450a439fe 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -63,14 +63,16 @@ public:
     }
 
     /// Allocates a new handle for the service
-    Handle NewHandle() {
-        Handle handle = (m_handles.size() << 16) | 0;//m_handle;
+    Handle CreateHandle(KernelObject *obj) {
+        Handle handle = g_kernel_objects.Create(obj);
         m_handles.push_back(handle);
         return handle;
     }
 
     /// Frees a handle from the service
-    void DeleteHandle(Handle handle) {
+    template <class T>
+    void DeleteHandle(const Handle handle) {
+        g_kernel_objects.Destroy<T>(handle);
         m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
     }
 
@@ -111,8 +113,8 @@ protected:
 
 private:
 
-    std::vector<Handle>    m_handles;
-    std::map<u32, FunctionInfo>     m_functions;
+    std::vector<Handle>         m_handles;
+    std::map<u32, FunctionInfo> m_functions;
 
 };
 

From 088a2de9a6f593460dcd532c4a217e0c0fc4fd72 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Sun, 18 May 2014 22:24:26 -0400
Subject: [PATCH 39/72] renamed "session" to "handle"

---
 src/core/hle/syscall.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/core/hle/syscall.cpp b/src/core/hle/syscall.cpp
index 84c247ae3..9a1235246 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/syscall.cpp
@@ -89,9 +89,9 @@ Result ConnectToPort(void* out, const char* port_name) {
 }
 
 /// Synchronize to an OS service
-Result SendSyncRequest(Handle session) {
-    DEBUG_LOG(SVC, "SendSyncRequest called session=0x%08X");
-    Service::Interface* service = Service::g_manager->FetchFromHandle(session);
+Result SendSyncRequest(Handle handle) {
+    DEBUG_LOG(SVC, "SendSyncRequest called handle=0x%08X");
+    Service::Interface* service = Service::g_manager->FetchFromHandle(handle);
     service->Sync();
     return 0;
 }

From 29930ac1101ca12213169d9a21c45efa0d07a374 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Mon, 19 May 2014 22:19:10 -0400
Subject: [PATCH 40/72] VFP: disable DBG messages because they spam the console
 with unimportant skyeye junk

---
 src/core/arm/interpreter/vfp/vfp.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/arm/interpreter/vfp/vfp.h b/src/core/arm/interpreter/vfp/vfp.h
index f738a615b..bbf4caeb0 100644
--- a/src/core/arm/interpreter/vfp/vfp.h
+++ b/src/core/arm/interpreter/vfp/vfp.h
@@ -21,7 +21,7 @@
 #ifndef __VFP_H__
 #define __VFP_H__
 
-#define DBG(...) DEBUG_LOG(ARM11, __VA_ARGS__)
+#define DBG(...) //DEBUG_LOG(ARM11, __VA_ARGS__)
 
 #define vfpdebug //printf
 

From f5a119a3678fb8bc70a846a166a0993fe4a98c46 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Mon, 19 May 2014 22:19:48 -0400
Subject: [PATCH 41/72] thread: added declaration for __KernelReschedule to be
 used by syscall module

---
 src/core/hle/kernel/thread.h | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 0d0f46500..eca84c718 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -28,6 +28,9 @@ Handle __KernelCreateThread(const char *name, u32 entry_point, s32 priority,
 /// Sets up the primary application thread
 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);
+
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();
 

From 0886dc70ed3eb3c30fcbe0039d53a5c780a6c4b9 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Mon, 19 May 2014 22:21:17 -0400
Subject: [PATCH 42/72] apt: changed stubbed handle to be something other than
 0xDEADBEEF (used as a magic value in other places) so that I can track how it
 propagates through the app code

---
 src/core/hle/service/apt.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
index ddb975607..1f6a70eab 100644
--- a/src/core/hle/service/apt.cpp
+++ b/src/core/hle/service/apt.cpp
@@ -23,7 +23,7 @@ void GetLockHandle(Service::Interface* self) {
 
     // TODO: This should be an actual mutex handle. Games will check that this is not non-zero 
     // (NULL), and fail if such. A faked non-zero value will at least enable further booting. 
-    cmd_buff[5] = 0xDEADBEEF;
+    cmd_buff[5] = 0x12345678;
 }
 
 const Interface::FunctionInfo FunctionTable[] = {

From 44336329eddd7dbe1f76144e9a1e95e5f76ed372 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 18:13:25 -0400
Subject: [PATCH 43/72] - 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index f7145ddd8..b1fdffde5 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();
-}
+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);
 
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 8f2b7b36d..19edb7b57 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 <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);
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 634218e8b..2955d6f5b 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<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))) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index eca84c718..207a5227b 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 b3e414e0f..08d0c43ff 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<Interface>(handle);
+    return Kernel::g_object_pool.GetFast<Interface>(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 450a439fe..f334dbcb8 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 <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());
     }
 

From f654a03f1f23bea8fe5bf7194614ce6e947d0c5c Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 18:20:35 -0400
Subject: [PATCH 44/72] thread: whitespace change - fixed * and & placement

---
 src/core/hle/kernel/thread.cpp | 50 +++++++++++++++++-----------------
 src/core/hle/kernel/thread.h   |  4 +--
 2 files changed, 27 insertions(+), 27 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 2955d6f5b..cfc5327a3 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -45,8 +45,8 @@ enum WaitType {
 class Thread : public Kernel::Object {
 public:
 
-    const char *GetName() { return name; }
-    const char *GetTypeName() { return "Thread"; }
+    const char* GetName() { return name; }
+    const char* GetTypeName() { return "Thread"; }
 
     static Kernel::HandleType GetStaticHandleType() {  return Kernel::HandleType::Thread; }
     Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Thread; }
@@ -85,11 +85,11 @@ Handle g_current_thread_handle;
 Thread* g_current_thread;
 
 
-inline Thread *__GetCurrentThread() {
+inline Thread* __GetCurrentThread() {
     return g_current_thread;
 }
 
-inline void __SetCurrentThread(Thread *t) {
+inline void __SetCurrentThread(Thread* t) {
     g_current_thread = t;
     g_current_thread_handle = t->GetHandle();
 }
@@ -97,7 +97,7 @@ inline void __SetCurrentThread(Thread *t) {
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /// Saves the current CPU context
-void __KernelSaveContext(ThreadContext &ctx) {
+void __KernelSaveContext(ThreadContext& ctx) {
     ctx.cpu_registers[0] = Core::g_app_core->GetReg(0);
     ctx.cpu_registers[1] = Core::g_app_core->GetReg(1);
     ctx.cpu_registers[2] = Core::g_app_core->GetReg(2);
@@ -118,7 +118,7 @@ void __KernelSaveContext(ThreadContext &ctx) {
 }
 
 /// Loads a CPU context
-void __KernelLoadContext(const ThreadContext &ctx) {
+void __KernelLoadContext(const ThreadContext& ctx) {
     Core::g_app_core->SetReg(0, ctx.cpu_registers[0]);
     Core::g_app_core->SetReg(1, ctx.cpu_registers[1]);
     Core::g_app_core->SetReg(2, ctx.cpu_registers[2]);
@@ -141,7 +141,7 @@ void __KernelLoadContext(const ThreadContext &ctx) {
 }
 
 /// Resets a thread
-void __KernelResetThread(Thread *t, s32 lowest_priority) {
+void __KernelResetThread(Thread* t, s32 lowest_priority) {
     memset(&t->context, 0, sizeof(ThreadContext));
 
     t->context.pc = t->entry_point;
@@ -155,7 +155,7 @@ void __KernelResetThread(Thread *t, s32 lowest_priority) {
 }
 
 /// Change a thread to "ready" state
-void __KernelChangeReadyState(Thread *t, bool ready) {
+void __KernelChangeReadyState(Thread* t, bool ready) {
     Handle handle = t->GetHandle();
     if (t->IsReady()) {
         if (!ready) {
@@ -172,7 +172,7 @@ void __KernelChangeReadyState(Thread *t, bool ready) {
 }
 
 /// Changes a threads state
-void __KernelChangeThreadState(Thread *t, ThreadStatus new_status) {
+void __KernelChangeThreadState(Thread* t, ThreadStatus new_status) {
     if (!t || t->status == new_status) {
         return;
     }
@@ -187,7 +187,7 @@ 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 __KernelCallThread(Thread* t) {
     // Stop waiting
     if (t->wait_type != WAITTYPE_NONE) {
         t->wait_type = WAITTYPE_NONE;
@@ -196,10 +196,10 @@ void __KernelCallThread(Thread *t) {
 }
 
 /// Creates a new thread
-Thread *__KernelCreateThread(Handle &handle, const char *name, u32 entry_point, s32 priority,
+Thread* __KernelCreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority,
     s32 processor_id, u32 stack_top, int stack_size) {
 
-    Thread *t = new Thread;
+    Thread* t = new Thread;
     
     handle = Kernel::g_object_pool.Create(t);
     
@@ -221,7 +221,7 @@ 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 __KernelCreateThread(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");
@@ -245,7 +245,7 @@ Handle __KernelCreateThread(const char *name, u32 entry_point, s32 priority, s32
         return -1;
     }
     Handle handle;
-    Thread *t = __KernelCreateThread(handle, name, entry_point, priority, processor_id, stack_top, 
+    Thread* t = __KernelCreateThread(handle, name, entry_point, priority, processor_id, stack_top, 
         stack_size);
 
     HLE::EatCycles(32000);
@@ -260,8 +260,8 @@ Handle __KernelCreateThread(const char *name, u32 entry_point, s32 priority, s32
 }
 
 /// Switches CPU context to that of the specified thread
-void __KernelSwitchContext(Thread* t, const char *reason) {
-    Thread *cur = __GetCurrentThread();
+void __KernelSwitchContext(Thread* t, const char* reason) {
+    Thread* cur = __GetCurrentThread();
     
     // Save context for current thread
     if (cur) {
@@ -284,9 +284,9 @@ void __KernelSwitchContext(Thread* t, const char *reason) {
 }
 
 /// Gets the next thread that is ready to be run by priority
-Thread *__KernelNextThread() {
+Thread* __KernelNextThread() {
     Handle next;
-    Thread *cur = __GetCurrentThread();
+    Thread* cur = __GetCurrentThread();
     
     if (cur && cur->IsRunning()) {
         next = g_thread_ready_queue.pop_first_better(cur->current_priority);
@@ -304,13 +304,13 @@ Handle __KernelSetupMainThread(s32 priority, int stack_size) {
     Handle handle;
     
     // Initialize new "main" thread
-    Thread *t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 
+    Thread* t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority, 
         THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
     
     __KernelResetThread(t, 0);
     
     // If running another thread already, set it to "ready" state
-    Thread *cur = __GetCurrentThread();
+    Thread* cur = __GetCurrentThread();
     if (cur && cur->IsRunning()) {
         __KernelChangeReadyState(cur, true);
     }
@@ -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 = Kernel::g_object_pool.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))) {
@@ -336,15 +336,15 @@ void __KernelResumeThreadFromWait(Handle handle) {
 }
 
 /// Puts a thread in the wait state for the given type/reason
-void __KernelWaitCurThread(WaitType wait_type, const char *reason) {
-    Thread *t = __GetCurrentThread();
+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 __KernelReschedule(const char* reason) {
+    Thread* next = __KernelNextThread();
     if (next > 0) {
         __KernelSwitchContext(next, reason);
     }
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 207a5227b..72e9a416d 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -22,14 +22,14 @@ enum ThreadProcessorId {
 };
 
 /// Creates a new thread - wrapper for external user
-Handle __KernelCreateThread(const char *name, u32 entry_point, s32 priority, 
+Handle __KernelCreateThread(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);
 
 /// Reschedules to the next available thread (call after current thread is suspended)
-void __KernelReschedule(const char *reason);
+void __KernelReschedule(const char* reason);
 
 void __KernelThreadingInit();
 void __KernelThreadingShutdown();

From 143bba20453036f0a4bcc74dad10d99605a84732 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 18:28:38 -0400
Subject: [PATCH 45/72] renamed "syscall" module to "svc" (more accurate
 naming)

---
 src/core/CMakeLists.txt               |  2 +-
 src/core/core.vcxproj                 |  4 ++--
 src/core/core.vcxproj.filters         | 12 ++++++------
 src/core/hle/hle.cpp                  | 14 +++++++-------
 src/core/hle/hle.h                    |  2 +-
 src/core/hle/kernel/thread.cpp        |  2 +-
 src/core/hle/service/service.h        |  2 +-
 src/core/hle/{syscall.cpp => svc.cpp} | 12 +++++++-----
 src/core/hle/{syscall.h => svc.h}     |  4 ++--
 9 files changed, 28 insertions(+), 26 deletions(-)
 rename src/core/hle/{syscall.cpp => svc.cpp} (98%)
 rename src/core/hle/{syscall.h => svc.h} (95%)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b0597db38..e006502da 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -33,7 +33,7 @@ set(SRCS    core.cpp
             hle/hle.cpp
             hle/config_mem.cpp
             hle/coprocessor.cpp
-            hle/syscall.cpp
+            hle/svc.cpp
             hle/kernel/kernel.cpp
             hle/kernel/thread.cpp
             hle/service/apt.cpp
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index f077154ee..6eb58a636 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -175,7 +175,7 @@
     <ClCompile Include="hle\service\hid.cpp" />
     <ClCompile Include="hle\service\service.cpp" />
     <ClCompile Include="hle\service\srv.cpp" />
-    <ClCompile Include="hle\syscall.cpp" />
+    <ClCompile Include="hle\svc.cpp" />
     <ClCompile Include="hw\hw.cpp" />
     <ClCompile Include="hw\lcd.cpp" />
     <ClCompile Include="hw\ndma.cpp" />
@@ -223,7 +223,7 @@
     <ClInclude Include="hle\service\hid.h" />
     <ClInclude Include="hle\service\service.h" />
     <ClInclude Include="hle\service\srv.h" />
-    <ClInclude Include="hle\syscall.h" />
+    <ClInclude Include="hle\svc.h" />
     <ClInclude Include="hw\hw.h" />
     <ClInclude Include="hw\lcd.h" />
     <ClInclude Include="hw\ndma.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index 6aedeb54b..fc4e35edb 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -84,9 +84,6 @@
     <ClCompile Include="hle\hle.cpp">
       <Filter>hle</Filter>
     </ClCompile>
-    <ClCompile Include="hle\syscall.cpp">
-      <Filter>hle</Filter>
-    </ClCompile>
     <ClCompile Include="hle\service\service.cpp">
       <Filter>hle\service</Filter>
     </ClCompile>
@@ -162,6 +159,9 @@
     <ClCompile Include="hle\kernel\thread.cpp">
       <Filter>hle\kernel</Filter>
     </ClCompile>
+    <ClCompile Include="hle\svc.cpp">
+      <Filter>hle</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -226,9 +226,6 @@
     <ClInclude Include="hle\service\service.h">
       <Filter>hle\service</Filter>
     </ClInclude>
-    <ClInclude Include="hle\syscall.h">
-      <Filter>hle</Filter>
-    </ClInclude>
     <ClInclude Include="hle\service\apt.h">
       <Filter>hle\service</Filter>
     </ClInclude>
@@ -289,6 +286,9 @@
     <ClInclude Include="hle\kernel\thread.h">
       <Filter>hle\kernel</Filter>
     </ClInclude>
+    <ClInclude Include="hle\svc.h">
+      <Filter>hle</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp
index 452384571..080c36abf 100644
--- a/src/core/hle/hle.cpp
+++ b/src/core/hle/hle.cpp
@@ -6,7 +6,7 @@
 
 #include "core/mem_map.h"
 #include "core/hle/hle.h"
-#include "core/hle/syscall.h"
+#include "core/hle/svc.h"
 #include "core/hle/service/service.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -15,17 +15,17 @@ namespace HLE {
 
 static std::vector<ModuleDef> g_module_db;
 
-const FunctionDef* GetSyscallInfo(u32 opcode) {
+const FunctionDef* GetSVCInfo(u32 opcode) {
     u32 func_num = opcode & 0xFFFFFF; // 8 bits
     if (func_num > 0xFF) {
-        ERROR_LOG(HLE,"Unknown syscall: 0x%02X", func_num); 
+        ERROR_LOG(HLE,"Unknown SVC: 0x%02X", func_num); 
         return NULL;
     }
     return &g_module_db[0].func_table[func_num];
 }
 
-void CallSyscall(u32 opcode) {
-    const FunctionDef *info = GetSyscallInfo(opcode);
+void CallSVC(u32 opcode) {
+    const FunctionDef *info = GetSVCInfo(opcode);
 
     if (!info) {
         return;
@@ -33,7 +33,7 @@ void CallSyscall(u32 opcode) {
     if (info->func) {
         info->func();
     } else {
-        ERROR_LOG(HLE, "Unimplemented SysCall function %s(..)", info->name.c_str());
+        ERROR_LOG(HLE, "Unimplemented SVC function %s(..)", info->name.c_str());
     }
 }
 
@@ -54,7 +54,7 @@ void RegisterModule(std::string name, int num_functions, const FunctionDef* func
 }
 
 void RegisterAllModules() {
-    Syscall::Register();
+    SVC::Register();
 }
 
 void Init() {
diff --git a/src/core/hle/hle.h b/src/core/hle/hle.h
index 452546e1f..c075147c3 100644
--- a/src/core/hle/hle.h
+++ b/src/core/hle/hle.h
@@ -34,7 +34,7 @@ struct ModuleDef {
 
 void RegisterModule(std::string name, int num_functions, const FunctionDef *func_table);
 
-void CallSyscall(u32 opcode);
+void CallSVC(u32 opcode);
 
 void EatCycles(u32 cycles);
 
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index cfc5327a3..136fff021 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -15,7 +15,7 @@
 #include "core/core.h"
 #include "core/mem_map.h"
 #include "core/hle/hle.h"
-#include "core/hle/syscall.h"
+#include "core/hle/svc.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/thread.h"
 
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index f334dbcb8..eba730efb 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -14,7 +14,7 @@
 #include "core/mem_map.h"
 
 #include "core/hle/kernel/kernel.h"
-#include "core/hle/syscall.h"
+#include "core/hle/svc.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace Service
diff --git a/src/core/hle/syscall.cpp b/src/core/hle/svc.cpp
similarity index 98%
rename from src/core/hle/syscall.cpp
rename to src/core/hle/svc.cpp
index 9a1235246..a9141699c 100644
--- a/src/core/hle/syscall.cpp
+++ b/src/core/hle/svc.cpp
@@ -13,14 +13,14 @@
 #include "core/hle/kernel/thread.h"
 
 #include "core/hle/function_wrappers.h"
-#include "core/hle/syscall.h"
+#include "core/hle/svc.h"
 #include "core/hle/service/service.h"
 #include "core/hle/kernel/thread.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace Syscall
+// Namespace SVC
 
-namespace Syscall {
+namespace SVC {
 
 enum ControlMemoryOperation {
     MEMORY_OPERATION_HEAP       = 0x00000003,
@@ -123,6 +123,8 @@ 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");
+
     return 0;
 }
 
@@ -212,7 +214,7 @@ Result CreateEvent(void* _event, u32 reset_type) {
     return 0;
 }
 
-const HLE::FunctionDef Syscall_Table[] = {
+const HLE::FunctionDef SVC_Table[] = {
     {0x00,  NULL,                                       "Unknown"},
     {0x01,  WrapI_VUUUUU<ControlMemory>,                "ControlMemory"},
     {0x02,  WrapI_VVU<QueryMemory>,                     "QueryMemory"},
@@ -342,7 +344,7 @@ const HLE::FunctionDef Syscall_Table[] = {
 };
 
 void Register() {
-    HLE::RegisterModule("SyscallTable", ARRAY_SIZE(Syscall_Table), Syscall_Table);
+    HLE::RegisterModule("SVC_Table", ARRAY_SIZE(SVC_Table), SVC_Table);
 }
 
 } // namespace
diff --git a/src/core/hle/syscall.h b/src/core/hle/svc.h
similarity index 95%
rename from src/core/hle/syscall.h
rename to src/core/hle/svc.h
index 3da349ed5..5c35977d1 100644
--- a/src/core/hle/syscall.h
+++ b/src/core/hle/svc.h
@@ -39,9 +39,9 @@ enum ResetType {
 };
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
-// Namespace Syscall
+// Namespace SVC
 
-namespace Syscall {
+namespace SVC {
 
 void Register();
 

From 49dc2ce8ac4fc37a008fa28e0771c8c74c576b05 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 18:50:16 -0400
Subject: [PATCH 46/72] ARM_Interface: added SaveContext and LoadContext
 functions for HLE thread switching

---
 src/core/arm/arm_interface.h                 | 16 ++++++++-
 src/core/arm/interpreter/arm_interpreter.cpp | 36 +++++++++++++++++++
 src/core/arm/interpreter/arm_interpreter.h   | 12 +++++++
 src/core/hle/kernel/thread.cpp               | 38 ++------------------
 4 files changed, 65 insertions(+), 37 deletions(-)

diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 5c382ebbd..52bc82115 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -7,6 +7,8 @@
 #include "common/common.h"
 #include "common/common_types.h"
 
+#include "core/hle/svc.h"
+
 /// Generic ARM11 CPU interface
 class ARM_Interface : NonCopyable {
 public:
@@ -75,6 +77,18 @@ public:
      */
     virtual u64 GetTicks() const = 0;
 
+    /**
+     * Saves the current CPU context
+     * @param ctx Thread context to save
+     */
+    virtual void SaveContext(ThreadContext& ctx) = 0;
+
+    /**
+     * Loads a CPU context
+     * @param ctx Thread context to load
+     */
+    virtual void LoadContext(const ThreadContext& ctx) = 0;
+
     /// Getter for m_num_instructions
     u64 GetNumInstructions() {
         return m_num_instructions;
@@ -90,6 +104,6 @@ protected:
 
 private:
 
-    u64 m_num_instructions;                     ///< Number of instructions executed
+    u64 m_num_instructions; ///< Number of instructions executed
 
 };
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index c21ff0464..b8c46cdfc 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -101,3 +101,39 @@ void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
     m_state->NumInstrsToExecute = num_instructions;
     ARMul_Emulate32(m_state);
 }
+
+/**
+ * Saves the current CPU context
+ * @param ctx Thread context to save
+ * @todo Do we need to save Reg[15] and NextInstr?
+ */
+void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
+    memcpy(ctx.cpu_registers, m_state->Reg, sizeof(ctx.cpu_registers));
+    memcpy(ctx.fpu_registers, m_state->ExtReg, sizeof(ctx.fpu_registers));
+
+    ctx.sp = m_state->Reg[13];
+    ctx.lr = m_state->Reg[14];
+    ctx.pc = m_state->pc;
+    ctx.cpsr = m_state->Cpsr;
+    
+    ctx.fpscr = m_state->VFP[1];
+    ctx.fpexc = m_state->VFP[2];
+}
+
+/**
+ * Loads a CPU context
+ * @param ctx Thread context to load
+ * @param Do we need to load Reg[15] and NextInstr?
+ */
+void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
+    memcpy(m_state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
+    memcpy(m_state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+
+    m_state->Reg[13] = ctx.sp;
+    m_state->Reg[14] = ctx.lr;
+    m_state->pc = ctx.pc;
+    m_state->Cpsr = ctx.cpsr;
+
+    m_state->VFP[1] = ctx.fpscr;
+    m_state->VFP[2] = ctx.fpexc;
+}
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 474ba3e45..15240568c 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -60,6 +60,18 @@ public:
      */
     u64 GetTicks() const;
 
+    /**
+     * Saves the current CPU context
+     * @param ctx Thread context to save
+     */
+    void SaveContext(ThreadContext& ctx);
+
+    /**
+     * Loads a CPU context
+     * @param ctx Thread context to load
+     */
+    void LoadContext(const ThreadContext& ctx);
+
 protected:
 
     /**
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 136fff021..b3d306c53 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -98,46 +98,12 @@ inline void __SetCurrentThread(Thread* t) {
 
 /// Saves the current CPU context
 void __KernelSaveContext(ThreadContext& ctx) {
-    ctx.cpu_registers[0] = Core::g_app_core->GetReg(0);
-    ctx.cpu_registers[1] = Core::g_app_core->GetReg(1);
-    ctx.cpu_registers[2] = Core::g_app_core->GetReg(2);
-    ctx.cpu_registers[3] = Core::g_app_core->GetReg(3);
-    ctx.cpu_registers[4] = Core::g_app_core->GetReg(4);
-    ctx.cpu_registers[5] = Core::g_app_core->GetReg(5);
-    ctx.cpu_registers[6] = Core::g_app_core->GetReg(6);
-    ctx.cpu_registers[7] = Core::g_app_core->GetReg(7);
-    ctx.cpu_registers[8] = Core::g_app_core->GetReg(8);
-    ctx.cpu_registers[9] = Core::g_app_core->GetReg(9);
-    ctx.cpu_registers[10] = Core::g_app_core->GetReg(10);
-    ctx.cpu_registers[11] = Core::g_app_core->GetReg(11);
-    ctx.cpu_registers[12] = Core::g_app_core->GetReg(12);
-    ctx.sp = Core::g_app_core->GetReg(13);
-    ctx.lr = Core::g_app_core->GetReg(14);
-    ctx.pc = Core::g_app_core->GetPC();
-    ctx.cpsr = Core::g_app_core->GetCPSR();
+    Core::g_app_core->SaveContext(ctx);
 }
 
 /// Loads a CPU context
 void __KernelLoadContext(const ThreadContext& ctx) {
-    Core::g_app_core->SetReg(0, ctx.cpu_registers[0]);
-    Core::g_app_core->SetReg(1, ctx.cpu_registers[1]);
-    Core::g_app_core->SetReg(2, ctx.cpu_registers[2]);
-    Core::g_app_core->SetReg(3, ctx.cpu_registers[3]);
-    Core::g_app_core->SetReg(4, ctx.cpu_registers[4]);
-    Core::g_app_core->SetReg(5, ctx.cpu_registers[5]);
-    Core::g_app_core->SetReg(6, ctx.cpu_registers[6]);
-    Core::g_app_core->SetReg(7, ctx.cpu_registers[7]);
-    Core::g_app_core->SetReg(8, ctx.cpu_registers[8]);
-    Core::g_app_core->SetReg(9, ctx.cpu_registers[9]);
-    Core::g_app_core->SetReg(10, ctx.cpu_registers[10]);
-    Core::g_app_core->SetReg(11, ctx.cpu_registers[11]);
-    Core::g_app_core->SetReg(12, ctx.cpu_registers[12]);
-    Core::g_app_core->SetReg(13, ctx.sp);
-    Core::g_app_core->SetReg(14, ctx.lr);
-    //Core::g_app_core->SetReg(15, ctx.pc);
-
-    Core::g_app_core->SetPC(ctx.pc);
-    Core::g_app_core->SetCPSR(ctx.cpsr);
+    Core::g_app_core->LoadContext(ctx);
 }
 
 /// Resets a thread

From 001280245685ade50326301409e8aee28602504d Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 18:52:54 -0400
Subject: [PATCH 47/72] ARM_Interpreter/ARM_Interface: Fixed member variable
 naming to be consistent with style guide

---
 src/core/arm/arm_interface.h                 | 10 +--
 src/core/arm/interpreter/arm_interpreter.cpp | 78 ++++++++++----------
 src/core/arm/interpreter/arm_interpreter.h   |  2 +-
 3 files changed, 45 insertions(+), 45 deletions(-)

diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h
index 52bc82115..b73786ccd 100644
--- a/src/core/arm/arm_interface.h
+++ b/src/core/arm/arm_interface.h
@@ -13,7 +13,7 @@
 class ARM_Interface : NonCopyable {
 public:
     ARM_Interface() {
-        m_num_instructions = 0;
+        num_instructions = 0;
     }
 
     ~ARM_Interface() {
@@ -25,7 +25,7 @@ public:
      */
     void Run(int num_instructions) {
         ExecuteInstructions(num_instructions);
-        m_num_instructions += num_instructions;
+        num_instructions += num_instructions;
     }
 
     /// Step CPU by one instruction
@@ -89,9 +89,9 @@ public:
      */
     virtual void LoadContext(const ThreadContext& ctx) = 0;
 
-    /// Getter for m_num_instructions
+    /// Getter for num_instructions
     u64 GetNumInstructions() {
-        return m_num_instructions;
+        return num_instructions;
     }
 
 protected:
@@ -104,6 +104,6 @@ protected:
 
 private:
 
-    u64 m_num_instructions; ///< Number of instructions executed
+    u64 num_instructions; ///< Number of instructions executed
 
 };
diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index b8c46cdfc..a9ec94820 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -9,30 +9,30 @@ const static cpu_config_t s_arm11_cpu_info = {
 };
 
 ARM_Interpreter::ARM_Interpreter()  {
-    m_state = new ARMul_State;
+    state = new ARMul_State;
 
     ARMul_EmulateInit();
-    ARMul_NewState(m_state);
+    ARMul_NewState(state);
 
-    m_state->abort_model = 0;
-    m_state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
-    m_state->bigendSig = LOW;
+    state->abort_model = 0;
+    state->cpu = (cpu_config_t*)&s_arm11_cpu_info;
+    state->bigendSig = LOW;
 
-    ARMul_SelectProcessor(m_state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
-    m_state->lateabtSig = LOW;
-    mmu_init(m_state);
+    ARMul_SelectProcessor(state, ARM_v6_Prop | ARM_v5_Prop | ARM_v5e_Prop);
+    state->lateabtSig = LOW;
+    mmu_init(state);
 
     // Reset the core to initial state
-    ARMul_Reset(m_state);
-    m_state->NextInstr = 0;
-    m_state->Emulate = 3;
+    ARMul_Reset(state);
+    state->NextInstr = 0;
+    state->Emulate = 3;
 
-    m_state->pc = m_state->Reg[15] = 0x00000000;
-    m_state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
+    state->pc = state->Reg[15] = 0x00000000;
+    state->Reg[13] = 0x10000000; // Set stack pointer to the top of the stack
 }
 
 ARM_Interpreter::~ARM_Interpreter() {
-    delete m_state;
+    delete state;
 }
 
 /**
@@ -40,7 +40,7 @@ ARM_Interpreter::~ARM_Interpreter() {
  * @param addr Address to set PC to
  */
 void ARM_Interpreter::SetPC(u32 pc) {
-    m_state->pc = m_state->Reg[15] = pc;
+    state->pc = state->Reg[15] = pc;
 }
 
 /*
@@ -48,7 +48,7 @@ void ARM_Interpreter::SetPC(u32 pc) {
  * @return Returns current PC
  */
 u32 ARM_Interpreter::GetPC() const {
-    return m_state->pc;
+    return state->pc;
 }
 
 /**
@@ -57,7 +57,7 @@ u32 ARM_Interpreter::GetPC() const {
  * @return Returns the value in the register
  */
 u32 ARM_Interpreter::GetReg(int index) const {
-    return m_state->Reg[index];
+    return state->Reg[index];
 }
 
 /**
@@ -66,7 +66,7 @@ u32 ARM_Interpreter::GetReg(int index) const {
  * @param value Value to set register to
  */
 void ARM_Interpreter::SetReg(int index, u32 value) {
-    m_state->Reg[index] = value;
+    state->Reg[index] = value;
 }
 
 /**
@@ -74,7 +74,7 @@ void ARM_Interpreter::SetReg(int index, u32 value) {
  * @return Returns the value of the CPSR register
  */
 u32 ARM_Interpreter::GetCPSR() const {
-    return m_state->Cpsr;
+    return state->Cpsr;
 }
 
 /**
@@ -82,7 +82,7 @@ u32 ARM_Interpreter::GetCPSR() const {
  * @param cpsr Value to set CPSR to
  */
 void ARM_Interpreter::SetCPSR(u32 cpsr) {
-    m_state->Cpsr = cpsr;
+    state->Cpsr = cpsr;
 }
 
 /**
@@ -90,7 +90,7 @@ void ARM_Interpreter::SetCPSR(u32 cpsr) {
  * @return Returns number of clock ticks
  */
 u64 ARM_Interpreter::GetTicks() const {
-    return ARMul_Time(m_state);
+    return ARMul_Time(state);
 }
 
 /**
@@ -98,8 +98,8 @@ u64 ARM_Interpreter::GetTicks() const {
  * @param num_instructions Number of instructions to executes
  */
 void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
-    m_state->NumInstrsToExecute = num_instructions;
-    ARMul_Emulate32(m_state);
+    state->NumInstrsToExecute = num_instructions;
+    ARMul_Emulate32(state);
 }
 
 /**
@@ -108,16 +108,16 @@ void ARM_Interpreter::ExecuteInstructions(int num_instructions) {
  * @todo Do we need to save Reg[15] and NextInstr?
  */
 void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
-    memcpy(ctx.cpu_registers, m_state->Reg, sizeof(ctx.cpu_registers));
-    memcpy(ctx.fpu_registers, m_state->ExtReg, sizeof(ctx.fpu_registers));
+    memcpy(ctx.cpu_registers, state->Reg, sizeof(ctx.cpu_registers));
+    memcpy(ctx.fpu_registers, state->ExtReg, sizeof(ctx.fpu_registers));
 
-    ctx.sp = m_state->Reg[13];
-    ctx.lr = m_state->Reg[14];
-    ctx.pc = m_state->pc;
-    ctx.cpsr = m_state->Cpsr;
+    ctx.sp = state->Reg[13];
+    ctx.lr = state->Reg[14];
+    ctx.pc = state->pc;
+    ctx.cpsr = state->Cpsr;
     
-    ctx.fpscr = m_state->VFP[1];
-    ctx.fpexc = m_state->VFP[2];
+    ctx.fpscr = state->VFP[1];
+    ctx.fpexc = state->VFP[2];
 }
 
 /**
@@ -126,14 +126,14 @@ void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
  * @param Do we need to load Reg[15] and NextInstr?
  */
 void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
-    memcpy(m_state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
-    memcpy(m_state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
+    memcpy(state->Reg, ctx.cpu_registers, sizeof(ctx.cpu_registers));
+    memcpy(state->ExtReg, ctx.fpu_registers, sizeof(ctx.fpu_registers));
 
-    m_state->Reg[13] = ctx.sp;
-    m_state->Reg[14] = ctx.lr;
-    m_state->pc = ctx.pc;
-    m_state->Cpsr = ctx.cpsr;
+    state->Reg[13] = ctx.sp;
+    state->Reg[14] = ctx.lr;
+    state->pc = ctx.pc;
+    state->Cpsr = ctx.cpsr;
 
-    m_state->VFP[1] = ctx.fpscr;
-    m_state->VFP[2] = ctx.fpexc;
+    state->VFP[1] = ctx.fpscr;
+    state->VFP[2] = ctx.fpexc;
 }
diff --git a/src/core/arm/interpreter/arm_interpreter.h b/src/core/arm/interpreter/arm_interpreter.h
index 15240568c..6a531e497 100644
--- a/src/core/arm/interpreter/arm_interpreter.h
+++ b/src/core/arm/interpreter/arm_interpreter.h
@@ -82,6 +82,6 @@ protected:
 
 private:
 
-    ARMul_State* m_state;
+    ARMul_State* state;
 
 };

From 75c6d2a8fa3547946227094af6c179e5ccba0e1e Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 19:37:46 -0400
Subject: [PATCH 48/72] 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b1fdffde5..45e36173c 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 b3d306c53..7b4f0ea47 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<Handle> g_thread_queue;
 Common::ThreadQueueList<Handle> 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<Thread>(next);
+}
+
+/// Resumes a thread from waiting by marking it as "ready"
+void __ResumeThreadFromWait(Handle handle) {
+    u32 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))) {
+            __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<Thread>(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<Thread>(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 72e9a416d..2c0199273 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 a9141699c..6f0f099c6 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);
     

From bed4e920fa17c6ab1e1cfde1f3ee81d0ca4aaff9 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 21:00:10 -0400
Subject: [PATCH 49/72] thread: exposed ResumeThreadFromWait function for use
 in other kernel modules

---
 src/core/hle/kernel/thread.cpp | 16 ++++++++--------
 src/core/hle/kernel/thread.h   |  3 +++
 2 files changed, 11 insertions(+), 8 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 7b4f0ea47..af9188faa 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -200,8 +200,15 @@ Thread* __NextThread() {
     return Kernel::g_object_pool.GetFast<Thread>(next);
 }
 
+/// 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)));
+}
+
 /// Resumes a thread from waiting by marking it as "ready"
-void __ResumeThreadFromWait(Handle handle) {
+void ResumeThreadFromWait(Handle handle) {
     u32 error;
     Thread* t = Kernel::g_object_pool.Get<Thread>(handle, error);
     if (t) {
@@ -212,13 +219,6 @@ void __ResumeThreadFromWait(Handle handle) {
     }
 }
 
-/// 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* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority,
     s32 processor_id, u32 stack_top, int stack_size) {
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 2c0199273..bb48ddc79 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -31,6 +31,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);
 
+/// Resumes a thread from waiting by marking it as "ready"
+void ResumeThreadFromWait(Handle handle);
+
 /// Gets the current thread
 Handle GetCurrentThread();
 

From 203541da119cad61096fda20b3ff8a8cb5906fd6 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 21:02:35 -0400
Subject: [PATCH 50/72] thread: added correct lowest thread priority, added a
 thread priority check, and added some comments

---
 src/core/hle/kernel/thread.cpp |  3 +++
 src/core/hle/kernel/thread.h   | 13 +++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index af9188faa..294e03ca6 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -223,6 +223,9 @@ void ResumeThreadFromWait(Handle handle) {
 Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority,
     s32 processor_id, u32 stack_top, int stack_size) {
 
+    _assert_msg_(KERNEL, (priority >= THREADPRIO_HIGHEST && priority <= THREADPRIO_LOWEST), 
+        "CreateThread priority=%d, outside of allowable range!", priority)
+
     Thread* t = new Thread;
     
     handle = Kernel::g_object_pool.Create(t);
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index bb48ddc79..0d1fe19bf 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -8,15 +8,16 @@
 #include "core/hle/kernel/kernel.h"
 
 enum ThreadPriority {
-    THREADPRIO_HIGHEST      = 0,
-    THREADPRIO_DEFAULT      = 16,
-    THREADPRIO_LOWEST       = 31,
+    THREADPRIO_HIGHEST      = 0,    ///< Highest thread priority
+    THREADPRIO_DEFAULT      = 16,   ///< Default thread priority for userland apps
+    THREADPRIO_LOW          = 31,   ///< Low range of thread priority for userland apps
+    THREADPRIO_LOWEST       = 63,   ///< Thread priority max checked by svcCreateThread
 };
 
 enum ThreadProcessorId {
-    THREADPROCESSORID_0     = 0xFFFFFFFE,
-    THREADPROCESSORID_1     = 0xFFFFFFFD,
-    THREADPROCESSORID_ALL   = 0xFFFFFFFC,
+    THREADPROCESSORID_0     = 0xFFFFFFFE,   ///< Enables core appcode
+    THREADPROCESSORID_1     = 0xFFFFFFFD,   ///< Enables core syscore
+    THREADPROCESSORID_ALL   = 0xFFFFFFFC,   ///< Enables both cores
 };
 
 namespace Kernel {

From 22eb9a8981c9b4283e37f7d403c598402339ed7f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 22:25:40 -0400
Subject: [PATCH 51/72] armemu: missed rename of "Syscall" to "SVC"

---
 src/core/arm/interpreter/armemu.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/arm/interpreter/armemu.cpp b/src/core/arm/interpreter/armemu.cpp
index aa1ff17bb..e5dc7bd44 100644
--- a/src/core/arm/interpreter/armemu.cpp
+++ b/src/core/arm/interpreter/armemu.cpp
@@ -4548,7 +4548,7 @@ ARMul_Emulate26 (ARMul_State * state)
                 //    ARMul_OSHandleSWI (state, BITS (0, 23));
                 //    break;
                 //}
-                HLE::CallSyscall(instr);
+                HLE::CallSVC(instr);
                 ARMul_Abort (state, ARMul_SWIV);
                 break;
             }

From a721a4eb33a06b532e36e5a49578abd8338d0d28 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 22:26:40 -0400
Subject: [PATCH 52/72] arm: removed include of windows.h from armdefs.h to
 arminit.c (only module that uses it)

---
 src/core/arm/interpreter/armdefs.h   | 4 ----
 src/core/arm/interpreter/arminit.cpp | 3 +++
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/src/core/arm/interpreter/armdefs.h b/src/core/arm/interpreter/armdefs.h
index 5b2abc7f7..d8eae4d3f 100644
--- a/src/core/arm/interpreter/armdefs.h
+++ b/src/core/arm/interpreter/armdefs.h
@@ -24,10 +24,6 @@
 
 #include "common/platform.h"
 
-#if EMU_PLATFORM == PLATFORM_WINDOWS
-#include <windows.h>
-#endif
-
 //teawater add for arm2x86 2005.02.14-------------------------------------------
 // koodailar remove it for mingw 2005.12.18----------------
 //anthonylee modify it for portable 2007.01.30
diff --git a/src/core/arm/interpreter/arminit.cpp b/src/core/arm/interpreter/arminit.cpp
index 2c771cdda..e05667bea 100644
--- a/src/core/arm/interpreter/arminit.cpp
+++ b/src/core/arm/interpreter/arminit.cpp
@@ -17,8 +17,11 @@
 
 
 #include "common/platform.h"
+
 #if EMU_PLATFORM == PLATFORM_LINUX
 #include <unistd.h>
+#elif EMU_PLATFORM == PLATFORM_WINDOWS
+#include <windows.h>
 #endif
 
 #include <math.h>

From 9bf7ce535a604d5523bfc14ea8057477ce1a4e0f Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 22:27:12 -0400
Subject: [PATCH 53/72] service: removed redundant include of common_types.h

---
 src/core/hle/service/service.h | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index eba730efb..716669bed 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -10,7 +10,6 @@
 #include <string>
 
 #include "common/common.h"
-#include "common/common_types.h"
 #include "core/mem_map.h"
 
 #include "core/hle/kernel/kernel.h"

From 1c5802c35a668cbb326cb497708bde341cd63f6d Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 22:27:46 -0400
Subject: [PATCH 54/72] kernel: fixed include, in general include "common.h"
 not "common_types.h"

---
 src/core/hle/kernel/kernel.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 19edb7b57..180339914 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,7 +4,7 @@
 
 #pragma once
 
-#include "common/common_types.h"
+#include "common/common.h"
 
 typedef u32 Handle;
 typedef s32 Result;

From 08e6a9bf896b386a339fccc65066ee51c8592b9c Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 22:57:54 -0400
Subject: [PATCH 55/72] svc: added some comments

---
 src/core/hle/svc.cpp | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 6f0f099c6..3674a08c5 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -10,6 +10,7 @@
 #include "core/mem_map.h"
 
 #include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/mutex.h"
 #include "core/hle/kernel/thread.h"
 
 #include "core/hle/function_wrappers.h"
@@ -160,6 +161,7 @@ Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void*
     return 0;
 }
 
+/// Creates a new thread
 Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 stack_top, 
     u32 processor_id) {
     std::string name;
@@ -182,6 +184,7 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st
     return 0;
 }
 
+/// Create a mutex
 Result CreateMutex(void* _mutex, u32 initial_locked) {
     Handle* mutex = (Handle*)_mutex;
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateMutex called initial_locked=%s", 
@@ -190,16 +193,19 @@ Result CreateMutex(void* _mutex, u32 initial_locked) {
     return 0;
 }
 
+/// Release a mutex
 Result ReleaseMutex(Handle handle) {
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) ReleaseMutex called handle=0x%08X", handle);
     return 0;
 }
 
+/// Get current thread ID
 Result GetThreadId(void* thread_id, u32 thread) {
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) GetThreadId called thread=0x%08X", thread);
     return 0;
 }
 
+/// Query memory
 Result QueryMemory(void *_info, void *_out, u32 addr) {
     MemoryInfo* info = (MemoryInfo*) _info;
     PageInfo* out = (PageInfo*) _out;
@@ -207,6 +213,7 @@ Result QueryMemory(void *_info, void *_out, u32 addr) {
     return 0;
 }
 
+/// Create an event
 Result CreateEvent(void* _event, u32 reset_type) {
     Handle* event = (Handle*)_event;
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateEvent called reset_type=0x%08X", reset_type);

From 978e1d4653cd12a68d6bfa05af57edb1645da0f5 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 23:03:45 -0400
Subject: [PATCH 56/72] mutex: initial commit of HLE module

---
 src/core/CMakeLists.txt       |   1 +
 src/core/core.vcxproj         |   2 +
 src/core/core.vcxproj.filters |   6 ++
 src/core/hle/kernel/mutex.cpp | 122 ++++++++++++++++++++++++++++++++++
 src/core/hle/kernel/mutex.h   |  26 ++++++++
 src/core/hle/service/apt.cpp  |  10 ++-
 src/core/hle/svc.cpp          |   9 +--
 7 files changed, 166 insertions(+), 10 deletions(-)
 create mode 100644 src/core/hle/kernel/mutex.cpp
 create mode 100644 src/core/hle/kernel/mutex.h

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index e006502da..6ad308798 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -35,6 +35,7 @@ set(SRCS    core.cpp
             hle/coprocessor.cpp
             hle/svc.cpp
             hle/kernel/kernel.cpp
+            hle/kernel/mutex.cpp
             hle/kernel/thread.cpp
             hle/service/apt.cpp
             hle/service/gsp.cpp
diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj
index 6eb58a636..f271d336e 100644
--- a/src/core/core.vcxproj
+++ b/src/core/core.vcxproj
@@ -169,6 +169,7 @@
     <ClCompile Include="hle\coprocessor.cpp" />
     <ClCompile Include="hle\hle.cpp" />
     <ClCompile Include="hle\kernel\kernel.cpp" />
+    <ClCompile Include="hle\kernel\mutex.cpp" />
     <ClCompile Include="hle\kernel\thread.cpp" />
     <ClCompile Include="hle\service\apt.cpp" />
     <ClCompile Include="hle\service\gsp.cpp" />
@@ -217,6 +218,7 @@
     <ClInclude Include="hle\function_wrappers.h" />
     <ClInclude Include="hle\hle.h" />
     <ClInclude Include="hle\kernel\kernel.h" />
+    <ClInclude Include="hle\kernel\mutex.h" />
     <ClInclude Include="hle\kernel\thread.h" />
     <ClInclude Include="hle\service\apt.h" />
     <ClInclude Include="hle\service\gsp.h" />
diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index fc4e35edb..f664debec 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -162,6 +162,9 @@
     <ClCompile Include="hle\svc.cpp">
       <Filter>hle</Filter>
     </ClCompile>
+    <ClCompile Include="hle\kernel\mutex.cpp">
+      <Filter>hle\kernel</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">
@@ -289,6 +292,9 @@
     <ClInclude Include="hle\svc.h">
       <Filter>hle</Filter>
     </ClInclude>
+    <ClInclude Include="hle\kernel\mutex.h">
+      <Filter>hle\kernel</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <Text Include="CMakeLists.txt" />
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
new file mode 100644
index 000000000..2b2cff4ea
--- /dev/null
+++ b/src/core/hle/kernel/mutex.cpp
@@ -0,0 +1,122 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#include <map>
+#include <vector>
+
+#include "common/common.h"
+
+#include "core/hle/kernel/kernel.h"
+#include "core/hle/kernel/thread.h"
+
+namespace Kernel {
+
+class Mutex : public Object {
+public:
+    const char* GetTypeName() { return "Mutex"; }
+
+    static Kernel::HandleType GetStaticHandleType() {  return Kernel::HandleType::Mutex; }
+    Kernel::HandleType GetHandleType() const { return Kernel::HandleType::Mutex; }
+
+    bool initial_locked;                        ///< Initial lock state when mutex was created
+    bool locked;                                ///< Current locked state
+    Handle lock_thread;                         ///< Handle to thread that currently has mutex
+    std::vector<Handle> waiting_threads;        ///< Threads that are waiting for the mutex
+};
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+typedef std::multimap<Handle, Handle> MutexMap;
+static MutexMap g_mutex_held_locks;
+
+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 __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) {
+        if ((*iter).second == handle) {
+            g_mutex_held_locks.erase(iter);
+            break;
+        }
+    }
+    mutex->lock_thread = -1;
+}
+
+bool __LockMutex(Mutex* mutex) {
+    // Mutex alread locked?
+    if (mutex->locked) {
+        return false;
+    }
+    __MutexAcquireLock(mutex);
+    return true;
+}
+
+bool __ReleaseMutexForThread(Mutex* mutex, Handle thread) {
+    __MutexAcquireLock(mutex, thread);
+    Kernel::ResumeThreadFromWait(thread);
+    return true;
+}
+
+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);
+        mutex->waiting_threads.erase(iter);
+    }
+    // Reset mutex lock thread handle, nothing is waiting
+    if (!woke_threads) {
+        mutex->locked = false;
+        mutex->lock_thread = -1;
+    }
+    return woke_threads;
+}
+
+/**
+ * Releases a mutex
+ * @param handle Handle to mutex to release
+ */
+Result ReleaseMutex(Handle handle) {
+    Mutex* mutex = Kernel::g_object_pool.GetFast<Mutex>(handle);
+    if (!__ReleaseMutex(mutex)) {
+        return -1;
+    }
+    return 0;
+}
+
+/**
+ * Creates a mutex
+ * @param handle Reference to handle for the newly created mutex
+ * @param initial_locked Specifies if the mutex should be locked initially
+ */
+Result CreateMutex(Handle& handle, bool initial_locked) {
+    Mutex* mutex = new Mutex;
+    handle = Kernel::g_object_pool.Create(mutex);
+
+    mutex->locked = mutex->initial_locked = initial_locked;
+
+    // Acquire mutex with current thread if initialized as locked...
+    if (mutex->locked) {
+        __MutexAcquireLock(mutex);
+
+    // Otherwise, reset lock thread handle
+    } else {
+        mutex->lock_thread = -1;
+    }
+    return 0;
+}
+
+} // namespace
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
new file mode 100644
index 000000000..1f843e979
--- /dev/null
+++ b/src/core/hle/kernel/mutex.h
@@ -0,0 +1,26 @@
+// Copyright 2014 Citra Emulator Project
+// Licensed under GPLv2
+// Refer to the license.txt file included.  
+
+#pragma once
+
+#include "common/common_types.h"
+
+#include "core/hle/kernel/kernel.h"
+
+namespace Kernel {
+
+/**
+ * Releases a mutex
+ * @param handle Handle to mutex to release
+ */
+Result ReleaseMutex(Handle handle);
+
+/**
+ * Creates a mutex
+ * @param handle Reference to handle for the newly created mutex
+ * @param initial_locked Specifies if the mutex should be locked initially
+ */
+Result CreateMutex(Handle& handle, bool initial_locked);
+
+} // namespace
diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
index 1f6a70eab..ecec4da00 100644
--- a/src/core/hle/service/apt.cpp
+++ b/src/core/hle/service/apt.cpp
@@ -3,9 +3,10 @@
 // Refer to the license.txt file included.
 
 
-#include "common/log.h"
+#include "common/common.h"
 
 #include "core/hle/hle.h"
+#include "core/hle/kernel/mutex.h"
 #include "core/hle/service/apt.h"
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -19,11 +20,8 @@ void Initialize(Service::Interface* self) {
 
 void GetLockHandle(Service::Interface* self) {
     u32* cmd_buff = Service::GetCommandBuffer();
-    u32 flags = cmd_buff[1];
-
-    // TODO: This should be an actual mutex handle. Games will check that this is not non-zero 
-    // (NULL), and fail if such. A faked non-zero value will at least enable further booting. 
-    cmd_buff[5] = 0x12345678;
+    u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
+    cmd_buff[1] = Kernel::CreateMutex(cmd_buff[5], false);
 }
 
 const Interface::FunctionInfo FunctionTable[] = {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 3674a08c5..73ab073f5 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -187,15 +187,16 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st
 /// Create a mutex
 Result CreateMutex(void* _mutex, u32 initial_locked) {
     Handle* mutex = (Handle*)_mutex;
-    DEBUG_LOG(SVC, "(UNIMPLEMENTED) CreateMutex called initial_locked=%s", 
-        initial_locked ? "true" : "false");
-    Core::g_app_core->SetReg(1, 0xF00D0BAD);
+    DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s", initial_locked ? "true" : "false");
+    Kernel::CreateMutex(*mutex, (bool)initial_locked);
+    Core::g_app_core->SetReg(1, *mutex);
     return 0;
 }
 
 /// Release a mutex
 Result ReleaseMutex(Handle handle) {
-    DEBUG_LOG(SVC, "(UNIMPLEMENTED) ReleaseMutex called handle=0x%08X", handle);
+    DEBUG_LOG(SVC, "ReleaseMutex called handle=0x%08X", handle);
+    Kernel::ReleaseMutex(handle);
     return 0;
 }
 

From eb537c560a33db9955413a96afd3b98203a729fe Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 23:23:58 -0400
Subject: [PATCH 57/72] mutex: refactored the interface to code to return a
 Mutex* handle

---
 src/core/hle/kernel/mutex.cpp | 14 ++++++++++++--
 src/core/hle/kernel/mutex.h   |  2 +-
 src/core/hle/service/apt.cpp  |  3 ++-
 src/core/hle/svc.cpp          |  2 +-
 4 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 2b2cff4ea..7cf3439e9 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -102,7 +102,7 @@ Result ReleaseMutex(Handle handle) {
  * @param handle Reference to handle for the newly created mutex
  * @param initial_locked Specifies if the mutex should be locked initially
  */
-Result CreateMutex(Handle& handle, bool initial_locked) {
+Mutex* CreateMutex(Handle& handle, bool initial_locked) {
     Mutex* mutex = new Mutex;
     handle = Kernel::g_object_pool.Create(mutex);
 
@@ -116,7 +116,17 @@ Result CreateMutex(Handle& handle, bool initial_locked) {
     } else {
         mutex->lock_thread = -1;
     }
-    return 0;
+    return mutex;
+}
+
+/**
+ * Creates a mutex
+ * @param initial_locked Specifies if the mutex should be locked initially
+ */
+Handle CreateMutex(bool initial_locked) {
+    Handle handle;
+    Mutex* mutex = CreateMutex(handle, initial_locked);
+    return handle;
 }
 
 } // namespace
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index 1f843e979..871e2e562 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -21,6 +21,6 @@ Result ReleaseMutex(Handle handle);
  * @param handle Reference to handle for the newly created mutex
  * @param initial_locked Specifies if the mutex should be locked initially
  */
-Result CreateMutex(Handle& handle, bool initial_locked);
+Handle CreateMutex(bool initial_locked);
 
 } // namespace
diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
index ecec4da00..b01f35ac5 100644
--- a/src/core/hle/service/apt.cpp
+++ b/src/core/hle/service/apt.cpp
@@ -21,7 +21,8 @@ void Initialize(Service::Interface* self) {
 void GetLockHandle(Service::Interface* self) {
     u32* cmd_buff = Service::GetCommandBuffer();
     u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
-    cmd_buff[1] = Kernel::CreateMutex(cmd_buff[5], false);
+    cmd_buff[1] = 0; // No error
+    cmd_buff[5] = Kernel::CreateMutex(false);
 }
 
 const Interface::FunctionInfo FunctionTable[] = {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 73ab073f5..ffacdfb86 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -188,7 +188,7 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st
 Result CreateMutex(void* _mutex, u32 initial_locked) {
     Handle* mutex = (Handle*)_mutex;
     DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s", initial_locked ? "true" : "false");
-    Kernel::CreateMutex(*mutex, (bool)initial_locked);
+    *mutex = Kernel::CreateMutex((initial_locked != 0));
     Core::g_app_core->SetReg(1, *mutex);
     return 0;
 }

From 706584f007f48cd319fe7511969f914843951088 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Tue, 20 May 2014 23:36:35 -0400
Subject: [PATCH 58/72] svc: enabled use of newly created kernel thread handle

---
 src/core/hle/svc.cpp | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index ffacdfb86..6f6f5b2f5 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -162,8 +162,7 @@ Result GetResourceLimitCurrentValues(void* _values, Handle resource_limit, void*
 }
 
 /// Creates a new thread
-Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 stack_top, 
-    u32 processor_id) {
+Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
     std::string name;
     if (Symbols::HasSymbol(entry_point)) {
         TSymbol symbol = Symbols::GetSymbol(entry_point);
@@ -177,9 +176,10 @@ 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 = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id, 
+    Handle thread = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id,
         stack_top);
-    Core::g_app_core->SetReg(1, 0xFEEDDEAF);
+
+    Core::g_app_core->SetReg(1, thread);
     
     return 0;
 }
@@ -231,7 +231,7 @@ const HLE::FunctionDef SVC_Table[] = {
     {0x05,  NULL,                                       "SetProcessAffinityMask"},
     {0x06,  NULL,                                       "GetProcessIdealProcessor"},
     {0x07,  NULL,                                       "SetProcessIdealProcessor"},
-    {0x08,  WrapI_VUUUUU<CreateThread>,                 "CreateThread"},
+    {0x08,  WrapI_UUUUU<CreateThread>,                  "CreateThread"},
     {0x09,  NULL,                                       "ExitThread"},
     {0x0A,  NULL,                                       "SleepThread"},
     {0x0B,  NULL,                                       "GetThreadPriority"},

From 06e3c3d55a6e8e58295bd9e7bebecdc777145b20 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Wed, 21 May 2014 21:41:40 -0400
Subject: [PATCH 59/72] svc: added Kernel::Reschedule to svc
 WaitSynchronization1, updated log messages to include newly created handles

---
 src/core/hle/svc.cpp | 11 +++++++----
 1 file changed, 7 insertions(+), 4 deletions(-)

diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 6f6f5b2f5..14d512b99 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -109,6 +109,7 @@ Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
     // ImplementMe
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", 
         handle, nano_seconds);
+    Kernel::Reschedule("WaitSynchronization1");
     return 0;
 }
 
@@ -172,14 +173,15 @@ Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 p
         sprintf(buff, "%s", "unknown-%08X", entry_point);
         name = buff;
     }
-    DEBUG_LOG(SVC, "CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
-        "threadpriority=0x%08X, processorid=0x%08X", entry_point, name.c_str(), arg, stack_top,
-        priority, processor_id);
 
     Handle thread = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id,
         stack_top);
 
     Core::g_app_core->SetReg(1, thread);
+
+    DEBUG_LOG(SVC, "CreateThread called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
+        "threadpriority=0x%08X, processorid=0x%08X : created handle 0x%08X", entry_point, 
+        name.c_str(), arg, stack_top, priority, processor_id, thread);
     
     return 0;
 }
@@ -187,9 +189,10 @@ Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 p
 /// Create a mutex
 Result CreateMutex(void* _mutex, u32 initial_locked) {
     Handle* mutex = (Handle*)_mutex;
-    DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s", initial_locked ? "true" : "false");
     *mutex = Kernel::CreateMutex((initial_locked != 0));
     Core::g_app_core->SetReg(1, *mutex);
+    DEBUG_LOG(SVC, "CreateMutex called initial_locked=%s : created handle 0x%08X", 
+        initial_locked ? "true" : "false", *mutex);
     return 0;
 }
 

From 6a78be5930fd5eabbea740a5cf17efa5a7f1bc98 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Wed, 21 May 2014 21:42:18 -0400
Subject: [PATCH 60/72] thread: fixed bug where result of __NextThread was not
 being properly checked when NULL

---
 src/core/hle/kernel/thread.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 294e03ca6..ef705e327 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -194,7 +194,7 @@ Thread* __NextThread() {
     } else  {
         next = g_thread_ready_queue.pop_first();
     }
-    if (next < 0) {
+    if (next == 0) {
         return NULL;
     }
     return Kernel::g_object_pool.GetFast<Thread>(next);

From 481d936d34c595b994f48b00819bb2c4bcfa7e57 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 18:47:42 -0400
Subject: [PATCH 61/72] arm_interpreter: fixed load context to currently resume
 a thread

---
 src/core/arm/interpreter/arm_interpreter.cpp | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/core/arm/interpreter/arm_interpreter.cpp b/src/core/arm/interpreter/arm_interpreter.cpp
index a9ec94820..17f787b86 100644
--- a/src/core/arm/interpreter/arm_interpreter.cpp
+++ b/src/core/arm/interpreter/arm_interpreter.cpp
@@ -115,7 +115,7 @@ void ARM_Interpreter::SaveContext(ThreadContext& ctx) {
     ctx.lr = state->Reg[14];
     ctx.pc = state->pc;
     ctx.cpsr = state->Cpsr;
-    
+
     ctx.fpscr = state->VFP[1];
     ctx.fpexc = state->VFP[2];
 }
@@ -136,4 +136,7 @@ void ARM_Interpreter::LoadContext(const ThreadContext& ctx) {
 
     state->VFP[1] = ctx.fpscr;
     state->VFP[2] = ctx.fpexc;
+
+    state->Reg[15] = ctx.pc;
+    state->NextInstr = RESUME;
 }

From 9fddba68435f6e276bfb40c793f1ca0f8b984ec9 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 18:48:14 -0400
Subject: [PATCH 62/72] APT_U: added a debug log on calling GetLockHandle

---
 src/core/hle/service/apt.cpp | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp
index b01f35ac5..32759a087 100644
--- a/src/core/hle/service/apt.cpp
+++ b/src/core/hle/service/apt.cpp
@@ -23,6 +23,7 @@ void GetLockHandle(Service::Interface* self) {
     u32 flags = cmd_buff[1]; // TODO(bunnei): Figure out the purpose of the flag field
     cmd_buff[1] = 0; // No error
     cmd_buff[5] = Kernel::CreateMutex(false);
+    DEBUG_LOG(KERNEL, "APT_U::GetLockHandle called : created handle 0x%08X", cmd_buff[5]);
 }
 
 const Interface::FunctionInfo FunctionTable[] = {

From 14bd37c5dc67c7777d4bea8d996bf2dfd8c7bdcc Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 18:50:36 -0400
Subject: [PATCH 63/72] 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(-)

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,22 +300,20 @@ 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);
+
+        // 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);
     }
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 
-/// 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");
-}
-
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
 void ThreadingInit() {
 }
 
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);
 

From ac21e8f2db8fbedeacbcef2989e8dbad524b9d44 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 18:51:55 -0400
Subject: [PATCH 64/72] core: moved armcopro.cpp to correct filter folder
 (arm/interpreter)

---
 src/core/core.vcxproj.filters | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters
index f664debec..b6c1d5b93 100644
--- a/src/core/core.vcxproj.filters
+++ b/src/core/core.vcxproj.filters
@@ -147,9 +147,6 @@
     <ClCompile Include="arm\interpreter\mmu\wb.cpp">
       <Filter>arm\interpreter\mmu</Filter>
     </ClCompile>
-    <ClCompile Include="arm\interpreter\armcopro.cpp">
-      <Filter>arm</Filter>
-    </ClCompile>
     <ClCompile Include="arm\interpreter\mmu\maverick.cpp">
       <Filter>arm\interpreter\mmu</Filter>
     </ClCompile>
@@ -165,6 +162,9 @@
     <ClCompile Include="hle\kernel\mutex.cpp">
       <Filter>hle\kernel</Filter>
     </ClCompile>
+    <ClCompile Include="arm\interpreter\armcopro.cpp">
+      <Filter>arm\interpreter</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="arm\disassembler\arm_disasm.h">

From d26f3d4c1ff27f740fe7185e1bca7dcfc5851919 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 19:06:12 -0400
Subject: [PATCH 65/72] 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(-)

diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 45e36173c..de80de893 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 180339914..7cd79c2c4 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 7cf3439e9..019efbc78 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -30,17 +30,17 @@ public:
 typedef std::multimap<Handle, Handle> 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<Mutex>(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 934ca87c4..5f1d5c400 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 82bf16082..a9e9eb95f 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 444b75feb..ff1c873bb 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;
     }

From 7c0b0060764e75738bc9d4417d0bfd510e54ae4e Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 19:32:45 -0400
Subject: [PATCH 66/72] thread: removed unused SwitchContext/Reschedule reason
 field, added missing arg parameter to SVC CreateThread

---
 src/core/hle/kernel/thread.cpp |  6 +++---
 src/core/hle/kernel/thread.h   |  2 +-
 src/core/hle/svc.cpp           | 13 +++++--------
 3 files changed, 9 insertions(+), 12 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 5f1d5c400..189f7d5f5 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -147,7 +147,7 @@ void CallThread(Thread* t) {
 }
 
 /// Switches CPU context to that of the specified thread
-void SwitchContext(Thread* t, const char* reason) {
+void SwitchContext(Thread* t) {
     Thread* cur = GetCurrentThread();
     
     // Save context for current thread
@@ -299,11 +299,11 @@ Handle SetupMainThread(s32 priority, int stack_size) {
 }
 
 /// Reschedules to the next available thread (call after current thread is suspended)
-void Reschedule(const char* reason) {
+void Reschedule() {
     Thread* prev = GetCurrentThread();
     Thread* next = NextThread();
     if (next > 0) {
-        SwitchContext(next, reason);
+        SwitchContext(next);
 
         // 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
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index a9e9eb95f..d54f47aaf 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -51,7 +51,7 @@ Handle CreateThread(const char* name, u32 entry_point, s32 priority, u32 arg, s3
 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);
+void Reschedule();
 
 /// Puts a thread in the wait state for the given type/reason
 void WaitCurThread(WaitType wait_type, const char* reason);
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 14d512b99..b1854a36e 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -106,10 +106,9 @@ Result CloseHandle(Handle handle) {
 
 /// Wait for a handle to synchronize, timeout after the specified nanoseconds
 Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
-    // ImplementMe
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", 
         handle, nano_seconds);
-    Kernel::Reschedule("WaitSynchronization1");
+    Kernel::WaitCurThread(WAITTYPE_SYNCH, "WaitSynchronization1"); // TODO(bunnei): Is this correct?
     return 0;
 }
 
@@ -117,16 +116,14 @@ Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
 Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wait_all, s64 nano_seconds) {
     s32* out = (s32*)_out;
     Handle* handles = (Handle*)_handles;
-    // ImplementMe
-    
+
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronizationN called handle_count=%d, wait_all=%s, nanoseconds=%d %s", 
         handle_count, (wait_all ? "true" : "false"), nano_seconds);
-    
+
     for (u32 i = 0; i < handle_count; i++) {
         DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]);
     }
-    Kernel::Reschedule("WaitSynchronizationN");
-
+    Kernel::WaitCurThread(WAITTYPE_SYNCH, "WaitSynchronizationN"); // TODO(bunnei): Is this correct?
     return 0;
 }
 
@@ -174,7 +171,7 @@ Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 p
         name = buff;
     }
 
-    Handle thread = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id,
+    Handle thread = Kernel::CreateThread(name.c_str(), entry_point, priority, arg, processor_id,
         stack_top);
 
     Core::g_app_core->SetReg(1, thread);

From b99ac2c3d67e2bcaa2c6eac220f1e93f4576c4fe Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 19:36:56 -0400
Subject: [PATCH 67/72] thread: renamed "WaitCurThread" to "WaitCurrentThread",
 removed unused "reason" argument

---
 src/core/hle/kernel/thread.cpp | 4 ++--
 src/core/hle/kernel/thread.h   | 4 ++--
 src/core/hle/svc.cpp           | 4 ++--
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 189f7d5f5..bf4c8353c 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -186,8 +186,8 @@ Thread* NextThread() {
     return Kernel::g_object_pool.GetFast<Thread>(next);
 }
 
-/// Puts a thread in the wait state for the given type/reason
-void WaitCurThread(WaitType wait_type, const char* reason) {
+/// Puts the current thread in the wait state for the given type
+void WaitCurrentThread(WaitType wait_type) {
     Thread* t = GetCurrentThread();
     t->wait_type = wait_type;
     ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND)));
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index d54f47aaf..9628f165d 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -53,8 +53,8 @@ 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();
 
-/// Puts a thread in the wait state for the given type/reason
-void WaitCurThread(WaitType wait_type, const char* reason);
+/// Puts the current thread in the wait state for the given type
+void WaitCurrentThread(WaitType wait_type);
 
 /// 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 b1854a36e..8018a43a2 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -108,7 +108,7 @@ Result CloseHandle(Handle handle) {
 Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
     DEBUG_LOG(SVC, "(UNIMPLEMENTED) WaitSynchronization1 called handle=0x%08X, nanoseconds=%d", 
         handle, nano_seconds);
-    Kernel::WaitCurThread(WAITTYPE_SYNCH, "WaitSynchronization1"); // TODO(bunnei): Is this correct?
+    Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
     return 0;
 }
 
@@ -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]);
     }
-    Kernel::WaitCurThread(WAITTYPE_SYNCH, "WaitSynchronizationN"); // TODO(bunnei): Is this correct?
+    Kernel::WaitCurrentThread(WAITTYPE_SYNCH); // TODO(bunnei): Is this correct?
     return 0;
 }
 

From 7bb66421a08ee4c061d7336efc20c69f70e97cd9 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 20:01:04 -0400
Subject: [PATCH 68/72] lcd: added thread wait after (faked) vblank interrupt
 (would have) occurred

---
 src/core/hw/lcd.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/src/core/hw/lcd.cpp b/src/core/hw/lcd.cpp
index 6468053f2..b57563a73 100644
--- a/src/core/hw/lcd.cpp
+++ b/src/core/hw/lcd.cpp
@@ -11,6 +11,8 @@
 
 #include "video_core/video_core.h"
 
+#include "core/hle/kernel/thread.h"
+
 namespace LCD {
 
 Registers g_regs;
@@ -130,9 +132,11 @@ template void Write<u8>(u32 addr, const u8 data);
 void Update() {
     u64 current_ticks = Core::g_app_core->GetTicks();
 
+    // Fake a vertical blank
     if ((current_ticks - g_last_ticks) >= kFrameTicks) {
         g_last_ticks = current_ticks;
         VideoCore::g_renderer->SwapBuffers();
+        Kernel::WaitCurrentThread(WAITTYPE_VBLANK);
     }
 }
 

From f8a98ab0228f25431d2df87f88310b41bb381b8e Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 22:49:29 -0400
Subject: [PATCH 69/72] svc: added a check to ensure that a service was
 implemented before attempting to connect to its port

---
 src/core/hle/svc.cpp | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 8018a43a2..90c05cb74 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -84,7 +84,11 @@ Result MapMemoryBlock(Handle memblock, u32 addr, u32 mypermissions, u32 otherper
 /// Connect to an OS service given the port name, returns the handle to the port to out
 Result ConnectToPort(void* out, const char* port_name) {
     Service::Interface* service = Service::g_manager->FetchFromPortName(port_name);
-    Core::g_app_core->SetReg(1, service->GetHandle());
+    if (service) {
+        Core::g_app_core->SetReg(1, service->GetHandle());
+    } else {
+        PanicYesNo("ConnectToPort called port_name=%s, but it is not implemented!", port_name);
+    }
     DEBUG_LOG(SVC, "ConnectToPort called port_name=%s", port_name);
     return 0;
 }

From 51f636b3d44e0c963d73cbc4e1a555633980b3fb Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 22:54:07 -0400
Subject: [PATCH 70/72] core: added Kernel::Reschedule() call to check for
 thread changes, shortened delay time to 100 instructions

---
 src/core/core.cpp | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/core/core.cpp b/src/core/core.cpp
index 61c237b2c..f88bcd704 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -12,6 +12,8 @@
 #include "core/arm/disassembler/arm_disasm.h"
 #include "core/arm/interpreter/arm_interpreter.h"
 
+#include "core/hle/kernel/thread.h"
+
 namespace Core {
 
 ARM_Disasm*     g_disasm    = NULL; ///< ARM disassembler
@@ -21,14 +23,17 @@ ARM_Interface*  g_sys_core  = NULL; ///< ARM11 system (OS) core
 /// Run the core CPU loop
 void RunLoop() {
     for (;;){
-        g_app_core->Run(10000);
+        g_app_core->Run(100);
         HW::Update();
+        Kernel::Reschedule();
     }
 }
 
 /// Step the CPU one instruction
 void SingleStep() {
     g_app_core->Step();
+    HW::Update();
+    Kernel::Reschedule();
 }
 
 /// Halt the core

From 420971a849b5811e4a6ae866292e70f40a716e5c Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 23:39:25 -0400
Subject: [PATCH 71/72] core: fixed headers in CMakeLists

---
 src/core/CMakeLists.txt | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index b63404f13..4086b415b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -78,7 +78,10 @@ set(HEADERS core.h
             hle/config_mem.h
             hle/coprocessor.h
             hle/hle.h
-            hle/syscall.h
+            hle/svc.h
+            hle/kernel/kernel.h
+            hle/kernel/mutex.h
+            hle/kernel/thread.h
             hle/function_wrappers.h
             hle/service/apt.h
             hle/service/gsp.h

From 0aa582bf89c3e3e479540b706511590636870912 Mon Sep 17 00:00:00 2001
From: bunnei <ericbunnie@gmail.com>
Date: Thu, 22 May 2014 23:48:37 -0400
Subject: [PATCH 72/72] service: fixed typo that MSVC did not catch as an error

---
 src/core/hle/service/service.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 716669bed..fab51753f 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -71,7 +71,7 @@ public:
     /// Frees a handle from the service
     template <class T>
     void DeleteHandle(const Handle handle) {
-        g_object_pool.Destroy<T>(handle);
+        Kernel::g_object_pool.Destroy<T>(handle);
         m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end());
     }