diff options
| author | bunnei <bunneidev@gmail.com> | 2015-01-10 15:19:21 -0500 | 
|---|---|---|
| committer | bunnei <bunneidev@gmail.com> | 2015-01-10 15:19:21 -0500 | 
| commit | 5a4b361f6065d33fd9efb73b3654910f74d5e3cd (patch) | |
| tree | cb6506c96f7880ef38f783221d4dd5b34978e3ef /src/core/hle | |
| parent | e213f9137339ff157e480934ec04aae7ae177452 (diff) | |
| parent | 8ad41775ccae67e54e9f03cbe054d7562b1c66ce (diff) | |
Merge pull request #455 from yuriks/handle-reform3
Kernel Lifetime Reform Pt. 3
Diffstat (limited to 'src/core/hle')
| -rw-r--r-- | src/core/hle/kernel/address_arbiter.cpp | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/event.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 23 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/shared_memory.cpp | 4 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 63 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 8 | ||||
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 3 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 31 | 
12 files changed, 97 insertions, 91 deletions
| diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 28adc5500..62e3460e1 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 697e08681..271190dbe 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 a1bc6c5d8..d3684896f 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,22 +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; +    Handle handle = generation | (slot << 15); +    if (obj->handle == INVALID_HANDLE) +        obj->handle = handle; +      generations[slot] = generation; -    intrusive_ptr_add_ref(obj); -    objects[slot] = obj; +    objects[slot] = std::move(obj); -    Handle handle = generation | (slot << 15); -    obj->handle = handle;      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) { @@ -64,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; @@ -79,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) { @@ -96,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; @@ -125,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 31d80c7ac..5e5217b78 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" @@ -52,7 +54,7 @@ class HandleTable;  class Object : NonCopyable {      friend class HandleTable; -    u32 handle; +    u32 handle = INVALID_HANDLE;  public:      virtual ~Object() {}      Handle GetHandle() const { return handle; } @@ -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 7d008f6cc..853a5dd74 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 d7eeaa3da..88ec9a104 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 cea1f6fa1..5368e4728 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 0ae1a21df..dd20ca30e 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 24450379c..284dec400 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 685a202c0..3b0452d4d 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 0c5597283..33c29a4a0 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 8ac1c7350..ba620bd0f 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; | 
