From 8ad41775ccae67e54e9f03cbe054d7562b1c66ce Mon Sep 17 00:00:00 2001
From: Yuri Kunde Schlesner <yuriks@yuriks.net>
Date: Mon, 29 Dec 2014 10:55:30 -0200
Subject: [PATCH] Kernel: Start using boost::intrusive_ptr for lifetime
 management

---
 externals/boost                         |  2 +-
 src/core/hle/kernel/address_arbiter.cpp |  2 +-
 src/core/hle/kernel/event.cpp           | 10 ++--
 src/core/hle/kernel/kernel.cpp          | 23 ++++-----
 src/core/hle/kernel/kernel.h            | 21 +++++----
 src/core/hle/kernel/mutex.cpp           |  6 +--
 src/core/hle/kernel/semaphore.cpp       |  4 +-
 src/core/hle/kernel/shared_memory.cpp   |  4 +-
 src/core/hle/kernel/thread.cpp          | 63 ++++++++++++-------------
 src/core/hle/kernel/thread.h            |  8 ++--
 src/core/hle/kernel/timer.cpp           | 10 ++--
 src/core/hle/service/service.cpp        |  3 +-
 src/core/hle/svc.cpp                    | 31 +++++++-----
 13 files changed, 96 insertions(+), 91 deletions(-)

diff --git a/externals/boost b/externals/boost
index 97052c28ac..a1afc91d3a 160000
--- a/externals/boost
+++ b/externals/boost
@@ -1 +1 @@
-Subproject commit 97052c28acb141dbf3c5e14114af99045344b695
+Subproject commit a1afc91d3aaa3da06bdbc13c78613e1466653405
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index 28adc55006..62e3460e11 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -30,7 +30,7 @@ public:
 
 /// Arbitrate an address
 ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) {
-    Object* object = Kernel::g_handle_table.GetGeneric(handle);
+    Object* object = Kernel::g_handle_table.GetGeneric(handle).get();
     if (object == nullptr)
         return InvalidHandle(ErrorModule::Kernel);
 
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 697e08681e..271190dbe9 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -53,7 +53,7 @@ public:
  * @return Result of operation, 0 on success, otherwise error code
  */
 ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
-    Event* evt = g_handle_table.Get<Event>(handle);
+    Event* evt = g_handle_table.Get<Event>(handle).get();
     if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     evt->permanent_locked = permanent_locked;
@@ -67,7 +67,7 @@ ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) {
  * @return Result of operation, 0 on success, otherwise error code
  */
 ResultCode SetEventLocked(const Handle handle, const bool locked) {
-    Event* evt = g_handle_table.Get<Event>(handle);
+    Event* evt = g_handle_table.Get<Event>(handle).get();
     if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     if (!evt->permanent_locked) {
@@ -82,13 +82,13 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) {
  * @return Result of operation, 0 on success, otherwise error code
  */
 ResultCode SignalEvent(const Handle handle) {
-    Event* evt = g_handle_table.Get<Event>(handle);
+    Event* evt = g_handle_table.Get<Event>(handle).get();
     if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     // Resume threads waiting for event to signal
     bool event_caught = false;
     for (size_t i = 0; i < evt->waiting_threads.size(); ++i) {
-        Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]);
+        Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]).get();
         if (thread != nullptr)
             thread->ResumeFromWait();
 
@@ -112,7 +112,7 @@ ResultCode SignalEvent(const Handle handle) {
  * @return Result of operation, 0 on success, otherwise error code
  */
 ResultCode ClearEvent(Handle handle) {
-    Event* evt = g_handle_table.Get<Event>(handle);
+    Event* evt = g_handle_table.Get<Event>(handle).get();
     if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     if (!evt->permanent_locked) {
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 7d40dcbee7..d3684896f6 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -14,7 +14,7 @@
 
 namespace Kernel {
 
-Thread* g_main_thread = nullptr;
+SharedPtr<Thread> g_main_thread = nullptr;
 HandleTable g_handle_table;
 u64 g_program_id = 0;
 
@@ -23,7 +23,7 @@ HandleTable::HandleTable() {
     Clear();
 }
 
-ResultVal<Handle> HandleTable::Create(Object* obj) {
+ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) {
     _dbg_assert_(Kernel, obj != nullptr);
 
     u16 slot = next_free_slot;
@@ -39,23 +39,23 @@ ResultVal<Handle> HandleTable::Create(Object* obj) {
     // CTR-OS doesn't use generation 0, so skip straight to 1.
     if (next_generation >= (1 << 15)) next_generation = 1;
 
-    generations[slot] = generation;
-    intrusive_ptr_add_ref(obj);
-    objects[slot] = obj;
-
     Handle handle = generation | (slot << 15);
     if (obj->handle == INVALID_HANDLE)
         obj->handle = handle;
+
+    generations[slot] = generation;
+    objects[slot] = std::move(obj);
+
     return MakeResult<Handle>(handle);
 }
 
 ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
-    Object* object = GetGeneric(handle);
+    SharedPtr<Object> object = GetGeneric(handle);
     if (object == nullptr) {
         LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle);
         return ERR_INVALID_HANDLE;
     }
-    return Create(object);
+    return Create(std::move(object));
 }
 
 ResultCode HandleTable::Close(Handle handle) {
@@ -65,7 +65,6 @@ ResultCode HandleTable::Close(Handle handle) {
     size_t slot = GetSlot(handle);
     u16 generation = GetGeneration(handle);
 
-    intrusive_ptr_release(objects[slot]);
     objects[slot] = nullptr;
 
     generations[generation] = next_free_slot;
@@ -80,7 +79,7 @@ bool HandleTable::IsValid(Handle handle) const {
     return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation;
 }
 
-Object* HandleTable::GetGeneric(Handle handle) const {
+SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const {
     if (handle == CurrentThread) {
         return GetCurrentThread();
     } else if (handle == CurrentProcess) {
@@ -97,8 +96,6 @@ Object* HandleTable::GetGeneric(Handle handle) const {
 void HandleTable::Clear() {
     for (size_t i = 0; i < MAX_COUNT; ++i) {
         generations[i] = i + 1;
-        if (objects[i] != nullptr)
-            intrusive_ptr_release(objects[i]);
         objects[i] = nullptr;
     }
     next_free_slot = 0;
@@ -126,7 +123,7 @@ bool LoadExec(u32 entry_point) {
     Core::g_app_core->SetPC(entry_point);
 
     // 0x30 is the typical main thread priority I've seen used so far
-    g_main_thread = Kernel::SetupMainThread(0x30);
+    g_main_thread = Kernel::SetupMainThread(0x30, Kernel::DEFAULT_STACK_SIZE);
     // Setup the idle thread
     Kernel::SetupIdleThread();
 
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index a350557241..5e5217b78b 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,6 +4,8 @@
 
 #pragma once
 
+#include <boost/intrusive_ptr.hpp>
+
 #include <array>
 #include <string>
 #include "common/common.h"
@@ -76,7 +78,7 @@ private:
     unsigned int ref_count = 0;
 };
 
-// Special functions that will later be used by boost::instrusive_ptr to do automatic ref-counting
+// Special functions used by boost::instrusive_ptr to do automatic ref-counting
 inline void intrusive_ptr_add_ref(Object* object) {
     ++object->ref_count;
 }
@@ -87,6 +89,9 @@ inline void intrusive_ptr_release(Object* object) {
     }
 }
 
+template <typename T>
+using SharedPtr = boost::intrusive_ptr<T>;
+
 /**
  * This class allows the creation of Handles, which are references to objects that can be tested
  * for validity and looked up. Here they are used to pass references to kernel objects to/from the
@@ -119,7 +124,7 @@ public:
      * @return The created Handle or one of the following errors:
      *           - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded.
      */
-    ResultVal<Handle> Create(Object* obj);
+    ResultVal<Handle> Create(SharedPtr<Object> obj);
 
     /**
      * Returns a new handle that points to the same object as the passed in handle.
@@ -143,7 +148,7 @@ public:
      * Looks up a handle.
      * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid.
      */
-    Object* GetGeneric(Handle handle) const;
+    SharedPtr<Object> GetGeneric(Handle handle) const;
 
     /**
      * Looks up a handle while verifying its type.
@@ -151,10 +156,10 @@ public:
      *          type differs from the handle type `T::HANDLE_TYPE`.
      */
     template <class T>
-    T* Get(Handle handle) const {
-        Object* object = GetGeneric(handle);
+    SharedPtr<T> Get(Handle handle) const {
+        SharedPtr<Object> object = GetGeneric(handle);
         if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
-            return static_cast<T*>(object);
+            return boost::static_pointer_cast<T>(std::move(object));
         }
         return nullptr;
     }
@@ -173,7 +178,7 @@ private:
     static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; }
 
     /// Stores the Object referenced by the handle or null if the slot is empty.
-    std::array<Object*, MAX_COUNT> objects;
+    std::array<SharedPtr<Object>, MAX_COUNT> objects;
 
     /**
      * The value of `next_generation` when the handle was created, used to check for validity. For
@@ -192,7 +197,7 @@ private:
 };
 
 extern HandleTable g_handle_table;
-extern Thread* g_main_thread;
+extern SharedPtr<Thread> g_main_thread;
 
 /// The ID code of the currently running game
 /// TODO(Subv): This variable should not be here, 
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index 7d008f6cc5..853a5dd741 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -48,7 +48,7 @@ void MutexAcquireLock(Mutex* mutex, Handle thread = GetCurrentThread()->GetHandl
 bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) {
     MutexAcquireLock(mutex, thread_handle);
 
-    Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle);
+    Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle).get();
     if (thread == nullptr) {
         LOG_ERROR(Kernel, "Called with invalid handle: %08X", thread_handle);
         return false;
@@ -94,7 +94,7 @@ void ReleaseThreadMutexes(Handle thread) {
     
     // Release every mutex that the thread holds, and resume execution on the waiting threads
     for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) {
-        Mutex* mutex = g_handle_table.Get<Mutex>(iter->second);
+        Mutex* mutex = g_handle_table.Get<Mutex>(iter->second).get();
         ResumeWaitingThread(mutex);
     }
 
@@ -122,7 +122,7 @@ bool ReleaseMutex(Mutex* mutex) {
  * @param handle Handle to mutex to release
  */
 ResultCode ReleaseMutex(Handle handle) {
-    Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle);
+    Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle).get();
     if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     if (!ReleaseMutex(mutex)) {
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp
index d7eeaa3da1..88ec9a104c 100644
--- a/src/core/hle/kernel/semaphore.cpp
+++ b/src/core/hle/kernel/semaphore.cpp
@@ -70,7 +70,7 @@ ResultCode CreateSemaphore(Handle* handle, s32 initial_count,
 }
 
 ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
-    Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle);
+    Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle).get();
     if (semaphore == nullptr)
         return InvalidHandle(ErrorModule::Kernel);
 
@@ -84,7 +84,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) {
     // Notify some of the threads that the semaphore has been released
     // stop once the semaphore is full again or there are no more waiting threads
     while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) {
-        Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front());
+        Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()).get();
         if (thread != nullptr)
             thread->ResumeFromWait();
         semaphore->waiting_threads.pop();
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index cea1f6fa14..5368e47280 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -61,7 +61,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
         return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
                 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
     }
-    SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
+    SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get();
     if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     shared_memory->base_address = address;
@@ -72,7 +72,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions
 }
 
 ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) {
-    SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle);
+    SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get();
     if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel);
 
     if (0 != shared_memory->base_address)
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 0ae1a21df2..dd20ca30e5 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -36,7 +36,7 @@ ResultVal<bool> Thread::WaitSynchronization() {
 }
 
 // Lists all thread ids that aren't deleted/etc.
-static std::vector<Thread*> thread_list; // TODO(yuriks): Owned
+static std::vector<SharedPtr<Thread>> thread_list;
 
 // Lists only ready thread ids.
 static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> thread_ready_queue;
@@ -110,8 +110,8 @@ void Thread::Stop(const char* reason) {
 
     ChangeReadyState(this, false);
     status = THREADSTATUS_DORMANT;
-    for (Thread* waiting_thread : waiting_threads) {
-        if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, this))
+    for (auto& waiting_thread : waiting_threads) {
+        if (CheckWaitType(waiting_thread.get(), WAITTYPE_THREADEND, this))
             waiting_thread->ResumeFromWait();
     }
     waiting_threads.clear();
@@ -143,15 +143,15 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) {
     s32 priority = THREADPRIO_LOWEST;
 
     // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
-    for (Thread* thread : thread_list) {
-        if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
+    for (auto& thread : thread_list) {
+        if (!CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address))
             continue;
 
         if (thread == nullptr)
             continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up.
 
         if(thread->current_priority <= priority) {
-            highest_priority_thread = thread;
+            highest_priority_thread = thread.get();
             priority = thread->current_priority;
         }
     }
@@ -168,8 +168,8 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) {
 void ArbitrateAllThreads(Object* arbiter, u32 address) {
 
     // Iterate through threads, find highest priority thread that is waiting to be arbitrated...
-    for (Thread* thread : thread_list) {
-        if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address))
+    for (auto& thread : thread_list) {
+        if (CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address))
             thread->ResumeFromWait();
     }
 }
@@ -241,7 +241,7 @@ static int ThreadWakeupEventType = -1;
 /// Callback that will wake up the thread it was scheduled for
 static void ThreadWakeupCallback(u64 parameter, int cycles_late) {
     Handle handle = static_cast<Handle>(parameter);
-    Thread* thread = Kernel::g_handle_table.Get<Thread>(handle);
+    SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(handle);
     if (thread == nullptr) {
         LOG_ERROR(Kernel, "Thread doesn't exist %u", handle);
         return;
@@ -278,20 +278,18 @@ static void DebugThreadQueue() {
         return;
     }
     LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle());
-    for (Thread* t : thread_list) {
-        s32 priority = thread_ready_queue.contains(t);
+    for (auto& t : thread_list) {
+        s32 priority = thread_ready_queue.contains(t.get());
         if (priority != -1) {
             LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle());
         }
     }
 }
 
-ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priority, u32 arg,
-        s32 processor_id, u32 stack_top, int stack_size) {
-    _dbg_assert_(Kernel, name != nullptr);
-
-    if ((u32)stack_size < 0x200) {
-        LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name, stack_size);
+ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority,
+        u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size) {
+    if (stack_size < 0x200) {
+        LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name.c_str(), stack_size);
         // TODO: Verify error
         return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Kernel,
                 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
@@ -300,27 +298,26 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit
     if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) {
         s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST);
         LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d",
-            name, priority, new_priority);
+            name.c_str(), 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)) {
-        LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name, entry_point);
+        LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point);
         // TODO: Verify error
         return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel,
                 ErrorSummary::InvalidArgument, ErrorLevel::Permanent);
     }
 
-    Thread* thread = new Thread;
+    SharedPtr<Thread> thread(new Thread);
 
     // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for
     //               the time being. Create a handle here, it will be copied to the handle field in
     //               the object and use by the rest of the code. This should be removed when other
     //               code doesn't rely on the handle anymore.
     ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread);
-    // TODO(yuriks): Plug memory leak
     if (handle.Failed())
         return handle.Code();
 
@@ -337,12 +334,12 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit
     thread->wait_type = WAITTYPE_NONE;
     thread->wait_object = nullptr;
     thread->wait_address = 0;
-    thread->name = name;
+    thread->name = std::move(name);
 
-    ResetThread(thread, arg, 0);
-    CallThread(thread);
+    ResetThread(thread.get(), arg, 0);
+    CallThread(thread.get());
 
-    return MakeResult<Thread*>(thread);
+    return MakeResult<SharedPtr<Thread>>(std::move(thread));
 }
 
 /// Set the priority of the thread specified by handle
@@ -376,20 +373,20 @@ Handle SetupIdleThread() {
     auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0,
             THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE);
     _dbg_assert_(Kernel, thread_res.Succeeded());
-    Thread* thread = *thread_res;
+    SharedPtr<Thread> thread = std::move(*thread_res);
 
     thread->idle = true;
-    CallThread(thread);
+    CallThread(thread.get());
     return thread->GetHandle();
 }
 
-Thread* SetupMainThread(s32 priority, int stack_size) {
+SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size) {
     // Initialize new "main" thread
-    ResultVal<Thread*> thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0,
-        THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
+    auto thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0,
+            THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
     // TODO(yuriks): Propagate error
     _dbg_assert_(Kernel, thread_res.Succeeded());
-    Thread* thread = *thread_res;
+    SharedPtr<Thread> thread = std::move(*thread_res);
 
     // If running another thread already, set it to "ready" state
     Thread* cur = GetCurrentThread();
@@ -398,7 +395,7 @@ Thread* SetupMainThread(s32 priority, int stack_size) {
     }
 
     // Run new "main" thread
-    current_thread = thread;
+    current_thread = thread.get();
     thread->status = THREADSTATUS_RUNNING;
     Core::g_app_core->LoadContext(thread->context);
 
@@ -418,7 +415,7 @@ void Reschedule() {
     } else {
         LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle());
 
-        for (Thread* thread : thread_list) {
+        for (auto& thread : thread_list) {
             LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X",
                 thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type,
                 (thread->wait_object ? thread->wait_object->GetHandle() : INVALID_HANDLE));
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 24450379cf..284dec4004 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -54,8 +54,8 @@ namespace Kernel {
 
 class Thread : public Kernel::Object {
 public:
-    static ResultVal<Thread*> Create(const char* name, u32 entry_point, s32 priority, u32 arg,
-        s32 processor_id, u32 stack_top, int stack_size = Kernel::DEFAULT_STACK_SIZE);
+    static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority,
+        u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size);
 
     std::string GetName() const override { return name; }
     std::string GetTypeName() const override { return "Thread"; }
@@ -99,7 +99,7 @@ public:
     Object* wait_object;
     VAddr wait_address;
 
-    std::vector<Thread*> waiting_threads; // TODO(yuriks): Owned
+    std::vector<SharedPtr<Thread>> waiting_threads;
 
     std::string name;
 
@@ -111,7 +111,7 @@ private:
 };
 
 /// Sets up the primary application thread
-Thread* SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZE);
+SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size);
 
 /// Reschedules to the next available thread (call after current thread is suspended)
 void Reschedule();
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 685a202c06..3b0452d4d9 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -66,7 +66,7 @@ ResultCode CreateTimer(Handle* handle, const ResetType reset_type, const std::st
 }
 
 ResultCode ClearTimer(Handle handle) {
-    Timer* timer = Kernel::g_handle_table.Get<Timer>(handle);
+    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
     
     if (timer == nullptr)
         return InvalidHandle(ErrorModule::Kernel);
@@ -80,7 +80,7 @@ static int TimerCallbackEventType = -1;
 
 /// The timer callback event, called when a timer is fired
 static void TimerCallback(u64 timer_handle, int cycles_late) {
-    Timer* timer = Kernel::g_handle_table.Get<Timer>(timer_handle);
+    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle);
 
     if (timer == nullptr) {
         LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle);
@@ -93,7 +93,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
 
     // Resume all waiting threads
     for (Handle thread_handle : timer->waiting_threads) {
-        if (Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle))
+        if (SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(thread_handle))
             thread->ResumeFromWait();
     }
 
@@ -111,7 +111,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) {
 }
 
 ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
-    Timer* timer = Kernel::g_handle_table.Get<Timer>(handle);
+    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
 
     if (timer == nullptr)
         return InvalidHandle(ErrorModule::Kernel);
@@ -125,7 +125,7 @@ ResultCode SetTimer(Handle handle, s64 initial, s64 interval) {
 }
 
 ResultCode CancelTimer(Handle handle) {
-    Timer* timer = Kernel::g_handle_table.Get<Timer>(handle);
+    SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle);
 
     if (timer == nullptr)
         return InvalidHandle(ErrorModule::Kernel);
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 0c55972834..33c29a4a02 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -59,7 +59,8 @@ void Manager::DeleteService(const std::string& port_name) {
 }
 
 Interface* Manager::FetchFromHandle(Handle handle) {
-    return Kernel::g_handle_table.Get<Interface>(handle);
+    // TODO(yuriks): This function is very suspicious and should probably be exterminated.
+    return Kernel::g_handle_table.Get<Interface>(handle).get();
 }
 
 Interface* Manager::FetchFromPortName(const std::string& port_name) {
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index 8ac1c7350d..ba620bd0f0 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -25,6 +25,8 @@
 ////////////////////////////////////////////////////////////////////////////////////////////////////
 // Namespace SVC
 
+using Kernel::SharedPtr;
+
 namespace SVC {
 
 enum ControlMemoryOperation {
@@ -94,7 +96,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) {
 
 /// Synchronize to an OS service
 static Result SendSyncRequest(Handle handle) {
-    Kernel::Session* session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
+    SharedPtr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle);
     if (session == nullptr) {
         return InvalidHandle(ErrorModule::Kernel).raw;
     }
@@ -121,12 +123,12 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) {
     // TODO(bunnei): Do something with nano_seconds, currently ignoring this
     bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated
 
-    Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handle);
+    SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle);
     if (object == nullptr)
         return InvalidHandle(ErrorModule::Kernel).raw;
 
-    LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(),
-            object->GetName().c_str(), nano_seconds);
+    LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle,
+            object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds);
 
     ResultVal<bool> wait = object->WaitSynchronization();
 
@@ -151,12 +153,12 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count,
 
     // Iterate through each handle, synchronize kernel object
     for (s32 i = 0; i < handle_count; i++) {
-        Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handles[i]);
+        SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]);
         if (object == nullptr)
             return InvalidHandle(ErrorModule::Kernel).raw;
 
-        LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(),
-            object->GetName().c_str());
+        LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i],
+                object->GetTypeName().c_str(), object->GetName().c_str());
 
         // TODO(yuriks): Verify how the real function behaves when an error happens here
         ResultVal<bool> wait_result = object->WaitSynchronization();
@@ -223,6 +225,8 @@ static Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit,
 
 /// Creates a new thread
 static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) {
+    using Kernel::Thread;
+
     std::string name;
     if (Symbols::HasSymbol(entry_point)) {
         TSymbol symbol = Symbols::GetSymbol(entry_point);
@@ -231,12 +235,13 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top
         name = Common::StringFromFormat("unknown-%08x", entry_point);
     }
 
-    ResultVal<Kernel::Thread*> thread_res = Kernel::Thread::Create(name.c_str(), entry_point, priority, arg,
-            processor_id, stack_top);
+    ResultVal<SharedPtr<Thread>> thread_res = Kernel::Thread::Create(
+            name, entry_point, priority, arg, processor_id, stack_top, Kernel::DEFAULT_STACK_SIZE);
     if (thread_res.Failed())
         return thread_res.Code().raw;
-    Kernel::Thread* thread = *thread_res;
+    SharedPtr<Thread> thread = std::move(*thread_res);
 
+    // TODO(yuriks): Create new handle instead of using built-in
     Core::g_app_core->SetReg(1, thread->GetHandle());
 
     LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, "
@@ -261,7 +266,7 @@ static void ExitThread() {
 
 /// Gets the priority for the specified thread
 static Result GetThreadPriority(s32* priority, Handle handle) {
-    const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
+    const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
     if (thread == nullptr)
         return InvalidHandle(ErrorModule::Kernel).raw;
 
@@ -271,7 +276,7 @@ static Result GetThreadPriority(s32* priority, Handle handle) {
 
 /// Sets the priority for the specified thread
 static Result SetThreadPriority(Handle handle, s32 priority) {
-    Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
+    SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
     if (thread == nullptr)
         return InvalidHandle(ErrorModule::Kernel).raw;
 
@@ -298,7 +303,7 @@ static Result ReleaseMutex(Handle handle) {
 static Result GetThreadId(u32* thread_id, Handle handle) {
     LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle);
 
-    const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
+    const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle);
     if (thread == nullptr)
         return InvalidHandle(ErrorModule::Kernel).raw;