diff options
| m--------- | externals/boost | 0 | ||||
| -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 |
13 files changed, 97 insertions, 91 deletions
diff --git a/externals/boost b/externals/boost | |||
| Subproject 97052c28acb141dbf3c5e14114af99045344b69 | Subproject a1afc91d3aaa3da06bdbc13c78613e146665340 | ||
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: | |||
| 30 | 30 | ||
| 31 | /// Arbitrate an address | 31 | /// Arbitrate an address |
| 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { | 32 | ResultCode ArbitrateAddress(Handle handle, ArbitrationType type, u32 address, s32 value) { |
| 33 | Object* object = Kernel::g_handle_table.GetGeneric(handle); | 33 | Object* object = Kernel::g_handle_table.GetGeneric(handle).get(); |
| 34 | if (object == nullptr) | 34 | if (object == nullptr) |
| 35 | return InvalidHandle(ErrorModule::Kernel); | 35 | return InvalidHandle(ErrorModule::Kernel); |
| 36 | 36 | ||
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: | |||
| 53 | * @return Result of operation, 0 on success, otherwise error code | 53 | * @return Result of operation, 0 on success, otherwise error code |
| 54 | */ | 54 | */ |
| 55 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { | 55 | ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { |
| 56 | Event* evt = g_handle_table.Get<Event>(handle); | 56 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 57 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 57 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 58 | 58 | ||
| 59 | evt->permanent_locked = permanent_locked; | 59 | evt->permanent_locked = permanent_locked; |
| @@ -67,7 +67,7 @@ ResultCode SetPermanentLock(Handle handle, const bool permanent_locked) { | |||
| 67 | * @return Result of operation, 0 on success, otherwise error code | 67 | * @return Result of operation, 0 on success, otherwise error code |
| 68 | */ | 68 | */ |
| 69 | ResultCode SetEventLocked(const Handle handle, const bool locked) { | 69 | ResultCode SetEventLocked(const Handle handle, const bool locked) { |
| 70 | Event* evt = g_handle_table.Get<Event>(handle); | 70 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 71 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 71 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 72 | 72 | ||
| 73 | if (!evt->permanent_locked) { | 73 | if (!evt->permanent_locked) { |
| @@ -82,13 +82,13 @@ ResultCode SetEventLocked(const Handle handle, const bool locked) { | |||
| 82 | * @return Result of operation, 0 on success, otherwise error code | 82 | * @return Result of operation, 0 on success, otherwise error code |
| 83 | */ | 83 | */ |
| 84 | ResultCode SignalEvent(const Handle handle) { | 84 | ResultCode SignalEvent(const Handle handle) { |
| 85 | Event* evt = g_handle_table.Get<Event>(handle); | 85 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 86 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 86 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 87 | 87 | ||
| 88 | // Resume threads waiting for event to signal | 88 | // Resume threads waiting for event to signal |
| 89 | bool event_caught = false; | 89 | bool event_caught = false; |
| 90 | for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { | 90 | for (size_t i = 0; i < evt->waiting_threads.size(); ++i) { |
| 91 | Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]); | 91 | Thread* thread = Kernel::g_handle_table.Get<Thread>(evt->waiting_threads[i]).get(); |
| 92 | if (thread != nullptr) | 92 | if (thread != nullptr) |
| 93 | thread->ResumeFromWait(); | 93 | thread->ResumeFromWait(); |
| 94 | 94 | ||
| @@ -112,7 +112,7 @@ ResultCode SignalEvent(const Handle handle) { | |||
| 112 | * @return Result of operation, 0 on success, otherwise error code | 112 | * @return Result of operation, 0 on success, otherwise error code |
| 113 | */ | 113 | */ |
| 114 | ResultCode ClearEvent(Handle handle) { | 114 | ResultCode ClearEvent(Handle handle) { |
| 115 | Event* evt = g_handle_table.Get<Event>(handle); | 115 | Event* evt = g_handle_table.Get<Event>(handle).get(); |
| 116 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); | 116 | if (evt == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 117 | 117 | ||
| 118 | if (!evt->permanent_locked) { | 118 | 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 @@ | |||
| 14 | 14 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | Thread* g_main_thread = nullptr; | 17 | SharedPtr<Thread> g_main_thread = nullptr; |
| 18 | HandleTable g_handle_table; | 18 | HandleTable g_handle_table; |
| 19 | u64 g_program_id = 0; | 19 | u64 g_program_id = 0; |
| 20 | 20 | ||
| @@ -23,7 +23,7 @@ HandleTable::HandleTable() { | |||
| 23 | Clear(); | 23 | Clear(); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | ResultVal<Handle> HandleTable::Create(Object* obj) { | 26 | ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { |
| 27 | _dbg_assert_(Kernel, obj != nullptr); | 27 | _dbg_assert_(Kernel, obj != nullptr); |
| 28 | 28 | ||
| 29 | u16 slot = next_free_slot; | 29 | u16 slot = next_free_slot; |
| @@ -39,22 +39,23 @@ ResultVal<Handle> HandleTable::Create(Object* obj) { | |||
| 39 | // CTR-OS doesn't use generation 0, so skip straight to 1. | 39 | // CTR-OS doesn't use generation 0, so skip straight to 1. |
| 40 | if (next_generation >= (1 << 15)) next_generation = 1; | 40 | if (next_generation >= (1 << 15)) next_generation = 1; |
| 41 | 41 | ||
| 42 | Handle handle = generation | (slot << 15); | ||
| 43 | if (obj->handle == INVALID_HANDLE) | ||
| 44 | obj->handle = handle; | ||
| 45 | |||
| 42 | generations[slot] = generation; | 46 | generations[slot] = generation; |
| 43 | intrusive_ptr_add_ref(obj); | 47 | objects[slot] = std::move(obj); |
| 44 | objects[slot] = obj; | ||
| 45 | 48 | ||
| 46 | Handle handle = generation | (slot << 15); | ||
| 47 | obj->handle = handle; | ||
| 48 | return MakeResult<Handle>(handle); | 49 | return MakeResult<Handle>(handle); |
| 49 | } | 50 | } |
| 50 | 51 | ||
| 51 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { | 52 | ResultVal<Handle> HandleTable::Duplicate(Handle handle) { |
| 52 | Object* object = GetGeneric(handle); | 53 | SharedPtr<Object> object = GetGeneric(handle); |
| 53 | if (object == nullptr) { | 54 | if (object == nullptr) { |
| 54 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); | 55 | LOG_ERROR(Kernel, "Tried to duplicate invalid handle: %08X", handle); |
| 55 | return ERR_INVALID_HANDLE; | 56 | return ERR_INVALID_HANDLE; |
| 56 | } | 57 | } |
| 57 | return Create(object); | 58 | return Create(std::move(object)); |
| 58 | } | 59 | } |
| 59 | 60 | ||
| 60 | ResultCode HandleTable::Close(Handle handle) { | 61 | ResultCode HandleTable::Close(Handle handle) { |
| @@ -64,7 +65,6 @@ ResultCode HandleTable::Close(Handle handle) { | |||
| 64 | size_t slot = GetSlot(handle); | 65 | size_t slot = GetSlot(handle); |
| 65 | u16 generation = GetGeneration(handle); | 66 | u16 generation = GetGeneration(handle); |
| 66 | 67 | ||
| 67 | intrusive_ptr_release(objects[slot]); | ||
| 68 | objects[slot] = nullptr; | 68 | objects[slot] = nullptr; |
| 69 | 69 | ||
| 70 | generations[generation] = next_free_slot; | 70 | generations[generation] = next_free_slot; |
| @@ -79,7 +79,7 @@ bool HandleTable::IsValid(Handle handle) const { | |||
| 79 | return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; | 79 | return slot < MAX_COUNT && objects[slot] != nullptr && generations[slot] == generation; |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | Object* HandleTable::GetGeneric(Handle handle) const { | 82 | SharedPtr<Object> HandleTable::GetGeneric(Handle handle) const { |
| 83 | if (handle == CurrentThread) { | 83 | if (handle == CurrentThread) { |
| 84 | return GetCurrentThread(); | 84 | return GetCurrentThread(); |
| 85 | } else if (handle == CurrentProcess) { | 85 | } else if (handle == CurrentProcess) { |
| @@ -96,8 +96,6 @@ Object* HandleTable::GetGeneric(Handle handle) const { | |||
| 96 | void HandleTable::Clear() { | 96 | void HandleTable::Clear() { |
| 97 | for (size_t i = 0; i < MAX_COUNT; ++i) { | 97 | for (size_t i = 0; i < MAX_COUNT; ++i) { |
| 98 | generations[i] = i + 1; | 98 | generations[i] = i + 1; |
| 99 | if (objects[i] != nullptr) | ||
| 100 | intrusive_ptr_release(objects[i]); | ||
| 101 | objects[i] = nullptr; | 99 | objects[i] = nullptr; |
| 102 | } | 100 | } |
| 103 | next_free_slot = 0; | 101 | next_free_slot = 0; |
| @@ -125,7 +123,7 @@ bool LoadExec(u32 entry_point) { | |||
| 125 | Core::g_app_core->SetPC(entry_point); | 123 | Core::g_app_core->SetPC(entry_point); |
| 126 | 124 | ||
| 127 | // 0x30 is the typical main thread priority I've seen used so far | 125 | // 0x30 is the typical main thread priority I've seen used so far |
| 128 | g_main_thread = Kernel::SetupMainThread(0x30); | 126 | g_main_thread = Kernel::SetupMainThread(0x30, Kernel::DEFAULT_STACK_SIZE); |
| 129 | // Setup the idle thread | 127 | // Setup the idle thread |
| 130 | Kernel::SetupIdleThread(); | 128 | Kernel::SetupIdleThread(); |
| 131 | 129 | ||
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 @@ | |||
| 4 | 4 | ||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <boost/intrusive_ptr.hpp> | ||
| 8 | |||
| 7 | #include <array> | 9 | #include <array> |
| 8 | #include <string> | 10 | #include <string> |
| 9 | #include "common/common.h" | 11 | #include "common/common.h" |
| @@ -52,7 +54,7 @@ class HandleTable; | |||
| 52 | 54 | ||
| 53 | class Object : NonCopyable { | 55 | class Object : NonCopyable { |
| 54 | friend class HandleTable; | 56 | friend class HandleTable; |
| 55 | u32 handle; | 57 | u32 handle = INVALID_HANDLE; |
| 56 | public: | 58 | public: |
| 57 | virtual ~Object() {} | 59 | virtual ~Object() {} |
| 58 | Handle GetHandle() const { return handle; } | 60 | Handle GetHandle() const { return handle; } |
| @@ -76,7 +78,7 @@ private: | |||
| 76 | unsigned int ref_count = 0; | 78 | unsigned int ref_count = 0; |
| 77 | }; | 79 | }; |
| 78 | 80 | ||
| 79 | // Special functions that will later be used by boost::instrusive_ptr to do automatic ref-counting | 81 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting |
| 80 | inline void intrusive_ptr_add_ref(Object* object) { | 82 | inline void intrusive_ptr_add_ref(Object* object) { |
| 81 | ++object->ref_count; | 83 | ++object->ref_count; |
| 82 | } | 84 | } |
| @@ -87,6 +89,9 @@ inline void intrusive_ptr_release(Object* object) { | |||
| 87 | } | 89 | } |
| 88 | } | 90 | } |
| 89 | 91 | ||
| 92 | template <typename T> | ||
| 93 | using SharedPtr = boost::intrusive_ptr<T>; | ||
| 94 | |||
| 90 | /** | 95 | /** |
| 91 | * This class allows the creation of Handles, which are references to objects that can be tested | 96 | * This class allows the creation of Handles, which are references to objects that can be tested |
| 92 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the | 97 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the |
| @@ -119,7 +124,7 @@ public: | |||
| 119 | * @return The created Handle or one of the following errors: | 124 | * @return The created Handle or one of the following errors: |
| 120 | * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. | 125 | * - `ERR_OUT_OF_HANDLES`: the maximum number of handles has been exceeded. |
| 121 | */ | 126 | */ |
| 122 | ResultVal<Handle> Create(Object* obj); | 127 | ResultVal<Handle> Create(SharedPtr<Object> obj); |
| 123 | 128 | ||
| 124 | /** | 129 | /** |
| 125 | * Returns a new handle that points to the same object as the passed in handle. | 130 | * Returns a new handle that points to the same object as the passed in handle. |
| @@ -143,7 +148,7 @@ public: | |||
| 143 | * Looks up a handle. | 148 | * Looks up a handle. |
| 144 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. | 149 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. |
| 145 | */ | 150 | */ |
| 146 | Object* GetGeneric(Handle handle) const; | 151 | SharedPtr<Object> GetGeneric(Handle handle) const; |
| 147 | 152 | ||
| 148 | /** | 153 | /** |
| 149 | * Looks up a handle while verifying its type. | 154 | * Looks up a handle while verifying its type. |
| @@ -151,10 +156,10 @@ public: | |||
| 151 | * type differs from the handle type `T::HANDLE_TYPE`. | 156 | * type differs from the handle type `T::HANDLE_TYPE`. |
| 152 | */ | 157 | */ |
| 153 | template <class T> | 158 | template <class T> |
| 154 | T* Get(Handle handle) const { | 159 | SharedPtr<T> Get(Handle handle) const { |
| 155 | Object* object = GetGeneric(handle); | 160 | SharedPtr<Object> object = GetGeneric(handle); |
| 156 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { | 161 | if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { |
| 157 | return static_cast<T*>(object); | 162 | return boost::static_pointer_cast<T>(std::move(object)); |
| 158 | } | 163 | } |
| 159 | return nullptr; | 164 | return nullptr; |
| 160 | } | 165 | } |
| @@ -173,7 +178,7 @@ private: | |||
| 173 | static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } | 178 | static u16 GetGeneration(Handle handle) { return handle & 0x7FFF; } |
| 174 | 179 | ||
| 175 | /// Stores the Object referenced by the handle or null if the slot is empty. | 180 | /// Stores the Object referenced by the handle or null if the slot is empty. |
| 176 | std::array<Object*, MAX_COUNT> objects; | 181 | std::array<SharedPtr<Object>, MAX_COUNT> objects; |
| 177 | 182 | ||
| 178 | /** | 183 | /** |
| 179 | * The value of `next_generation` when the handle was created, used to check for validity. For | 184 | * The value of `next_generation` when the handle was created, used to check for validity. For |
| @@ -192,7 +197,7 @@ private: | |||
| 192 | }; | 197 | }; |
| 193 | 198 | ||
| 194 | extern HandleTable g_handle_table; | 199 | extern HandleTable g_handle_table; |
| 195 | extern Thread* g_main_thread; | 200 | extern SharedPtr<Thread> g_main_thread; |
| 196 | 201 | ||
| 197 | /// The ID code of the currently running game | 202 | /// The ID code of the currently running game |
| 198 | /// TODO(Subv): This variable should not be here, | 203 | /// 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 | |||
| 48 | bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) { | 48 | bool ReleaseMutexForThread(Mutex* mutex, Handle thread_handle) { |
| 49 | MutexAcquireLock(mutex, thread_handle); | 49 | MutexAcquireLock(mutex, thread_handle); |
| 50 | 50 | ||
| 51 | Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle); | 51 | Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle).get(); |
| 52 | if (thread == nullptr) { | 52 | if (thread == nullptr) { |
| 53 | LOG_ERROR(Kernel, "Called with invalid handle: %08X", thread_handle); | 53 | LOG_ERROR(Kernel, "Called with invalid handle: %08X", thread_handle); |
| 54 | return false; | 54 | return false; |
| @@ -94,7 +94,7 @@ void ReleaseThreadMutexes(Handle thread) { | |||
| 94 | 94 | ||
| 95 | // Release every mutex that the thread holds, and resume execution on the waiting threads | 95 | // Release every mutex that the thread holds, and resume execution on the waiting threads |
| 96 | for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { | 96 | for (MutexMap::iterator iter = locked.first; iter != locked.second; ++iter) { |
| 97 | Mutex* mutex = g_handle_table.Get<Mutex>(iter->second); | 97 | Mutex* mutex = g_handle_table.Get<Mutex>(iter->second).get(); |
| 98 | ResumeWaitingThread(mutex); | 98 | ResumeWaitingThread(mutex); |
| 99 | } | 99 | } |
| 100 | 100 | ||
| @@ -122,7 +122,7 @@ bool ReleaseMutex(Mutex* mutex) { | |||
| 122 | * @param handle Handle to mutex to release | 122 | * @param handle Handle to mutex to release |
| 123 | */ | 123 | */ |
| 124 | ResultCode ReleaseMutex(Handle handle) { | 124 | ResultCode ReleaseMutex(Handle handle) { |
| 125 | Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle); | 125 | Mutex* mutex = Kernel::g_handle_table.Get<Mutex>(handle).get(); |
| 126 | if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); | 126 | if (mutex == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 127 | 127 | ||
| 128 | if (!ReleaseMutex(mutex)) { | 128 | 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, | |||
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | 72 | ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { |
| 73 | Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle); | 73 | Semaphore* semaphore = g_handle_table.Get<Semaphore>(handle).get(); |
| 74 | if (semaphore == nullptr) | 74 | if (semaphore == nullptr) |
| 75 | return InvalidHandle(ErrorModule::Kernel); | 75 | return InvalidHandle(ErrorModule::Kernel); |
| 76 | 76 | ||
| @@ -84,7 +84,7 @@ ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { | |||
| 84 | // Notify some of the threads that the semaphore has been released | 84 | // Notify some of the threads that the semaphore has been released |
| 85 | // stop once the semaphore is full again or there are no more waiting threads | 85 | // stop once the semaphore is full again or there are no more waiting threads |
| 86 | while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { | 86 | while (!semaphore->waiting_threads.empty() && semaphore->IsAvailable()) { |
| 87 | Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()); | 87 | Thread* thread = Kernel::g_handle_table.Get<Thread>(semaphore->waiting_threads.front()).get(); |
| 88 | if (thread != nullptr) | 88 | if (thread != nullptr) |
| 89 | thread->ResumeFromWait(); | 89 | thread->ResumeFromWait(); |
| 90 | semaphore->waiting_threads.pop(); | 90 | 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 | |||
| 61 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 61 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 62 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 62 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 63 | } | 63 | } |
| 64 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | 64 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get(); |
| 65 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); | 65 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 66 | 66 | ||
| 67 | shared_memory->base_address = address; | 67 | shared_memory->base_address = address; |
| @@ -72,7 +72,7 @@ ResultCode MapSharedMemory(u32 handle, u32 address, MemoryPermission permissions | |||
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { | 74 | ResultVal<u8*> GetSharedMemoryPointer(Handle handle, u32 offset) { |
| 75 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle); | 75 | SharedMemory* shared_memory = Kernel::g_handle_table.Get<SharedMemory>(handle).get(); |
| 76 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); | 76 | if (shared_memory == nullptr) return InvalidHandle(ErrorModule::Kernel); |
| 77 | 77 | ||
| 78 | if (0 != shared_memory->base_address) | 78 | 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() { | |||
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | // Lists all thread ids that aren't deleted/etc. | 38 | // Lists all thread ids that aren't deleted/etc. |
| 39 | static std::vector<Thread*> thread_list; // TODO(yuriks): Owned | 39 | static std::vector<SharedPtr<Thread>> thread_list; |
| 40 | 40 | ||
| 41 | // Lists only ready thread ids. | 41 | // Lists only ready thread ids. |
| 42 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> thread_ready_queue; | 42 | static Common::ThreadQueueList<Thread*, THREADPRIO_LOWEST+1> thread_ready_queue; |
| @@ -110,8 +110,8 @@ void Thread::Stop(const char* reason) { | |||
| 110 | 110 | ||
| 111 | ChangeReadyState(this, false); | 111 | ChangeReadyState(this, false); |
| 112 | status = THREADSTATUS_DORMANT; | 112 | status = THREADSTATUS_DORMANT; |
| 113 | for (Thread* waiting_thread : waiting_threads) { | 113 | for (auto& waiting_thread : waiting_threads) { |
| 114 | if (CheckWaitType(waiting_thread, WAITTYPE_THREADEND, this)) | 114 | if (CheckWaitType(waiting_thread.get(), WAITTYPE_THREADEND, this)) |
| 115 | waiting_thread->ResumeFromWait(); | 115 | waiting_thread->ResumeFromWait(); |
| 116 | } | 116 | } |
| 117 | waiting_threads.clear(); | 117 | waiting_threads.clear(); |
| @@ -143,15 +143,15 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) { | |||
| 143 | s32 priority = THREADPRIO_LOWEST; | 143 | s32 priority = THREADPRIO_LOWEST; |
| 144 | 144 | ||
| 145 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 145 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 146 | for (Thread* thread : thread_list) { | 146 | for (auto& thread : thread_list) { |
| 147 | if (!CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) | 147 | if (!CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address)) |
| 148 | continue; | 148 | continue; |
| 149 | 149 | ||
| 150 | if (thread == nullptr) | 150 | if (thread == nullptr) |
| 151 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. | 151 | continue; // TODO(yuriks): Thread handle will hang around forever. Should clean up. |
| 152 | 152 | ||
| 153 | if(thread->current_priority <= priority) { | 153 | if(thread->current_priority <= priority) { |
| 154 | highest_priority_thread = thread; | 154 | highest_priority_thread = thread.get(); |
| 155 | priority = thread->current_priority; | 155 | priority = thread->current_priority; |
| 156 | } | 156 | } |
| 157 | } | 157 | } |
| @@ -168,8 +168,8 @@ Thread* ArbitrateHighestPriorityThread(Object* arbiter, u32 address) { | |||
| 168 | void ArbitrateAllThreads(Object* arbiter, u32 address) { | 168 | void ArbitrateAllThreads(Object* arbiter, u32 address) { |
| 169 | 169 | ||
| 170 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... | 170 | // Iterate through threads, find highest priority thread that is waiting to be arbitrated... |
| 171 | for (Thread* thread : thread_list) { | 171 | for (auto& thread : thread_list) { |
| 172 | if (CheckWaitType(thread, WAITTYPE_ARB, arbiter, address)) | 172 | if (CheckWaitType(thread.get(), WAITTYPE_ARB, arbiter, address)) |
| 173 | thread->ResumeFromWait(); | 173 | thread->ResumeFromWait(); |
| 174 | } | 174 | } |
| 175 | } | 175 | } |
| @@ -241,7 +241,7 @@ static int ThreadWakeupEventType = -1; | |||
| 241 | /// Callback that will wake up the thread it was scheduled for | 241 | /// Callback that will wake up the thread it was scheduled for |
| 242 | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | 242 | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { |
| 243 | Handle handle = static_cast<Handle>(parameter); | 243 | Handle handle = static_cast<Handle>(parameter); |
| 244 | Thread* thread = Kernel::g_handle_table.Get<Thread>(handle); | 244 | SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(handle); |
| 245 | if (thread == nullptr) { | 245 | if (thread == nullptr) { |
| 246 | LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); | 246 | LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); |
| 247 | return; | 247 | return; |
| @@ -278,20 +278,18 @@ static void DebugThreadQueue() { | |||
| 278 | return; | 278 | return; |
| 279 | } | 279 | } |
| 280 | LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); | 280 | LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); |
| 281 | for (Thread* t : thread_list) { | 281 | for (auto& t : thread_list) { |
| 282 | s32 priority = thread_ready_queue.contains(t); | 282 | s32 priority = thread_ready_queue.contains(t.get()); |
| 283 | if (priority != -1) { | 283 | if (priority != -1) { |
| 284 | LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); | 284 | LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); |
| 285 | } | 285 | } |
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priority, u32 arg, | 289 | ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, s32 priority, |
| 290 | s32 processor_id, u32 stack_top, int stack_size) { | 290 | u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size) { |
| 291 | _dbg_assert_(Kernel, name != nullptr); | 291 | if (stack_size < 0x200) { |
| 292 | 292 | LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name.c_str(), stack_size); | |
| 293 | if ((u32)stack_size < 0x200) { | ||
| 294 | LOG_ERROR(Kernel, "(name=%s): invalid stack_size=0x%08X", name, stack_size); | ||
| 295 | // TODO: Verify error | 293 | // TODO: Verify error |
| 296 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Kernel, | 294 | return ResultCode(ErrorDescription::InvalidSize, ErrorModule::Kernel, |
| 297 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 295 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| @@ -300,27 +298,26 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit | |||
| 300 | if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { | 298 | if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) { |
| 301 | s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); | 299 | s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST); |
| 302 | LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", | 300 | LOG_WARNING(Kernel_SVC, "(name=%s): invalid priority=%d, clamping to %d", |
| 303 | name, priority, new_priority); | 301 | name.c_str(), priority, new_priority); |
| 304 | // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm | 302 | // TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm |
| 305 | // validity of this | 303 | // validity of this |
| 306 | priority = new_priority; | 304 | priority = new_priority; |
| 307 | } | 305 | } |
| 308 | 306 | ||
| 309 | if (!Memory::GetPointer(entry_point)) { | 307 | if (!Memory::GetPointer(entry_point)) { |
| 310 | LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name, entry_point); | 308 | LOG_ERROR(Kernel_SVC, "(name=%s): invalid entry %08x", name.c_str(), entry_point); |
| 311 | // TODO: Verify error | 309 | // TODO: Verify error |
| 312 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 310 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 313 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 311 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| 314 | } | 312 | } |
| 315 | 313 | ||
| 316 | Thread* thread = new Thread; | 314 | SharedPtr<Thread> thread(new Thread); |
| 317 | 315 | ||
| 318 | // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for | 316 | // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for |
| 319 | // the time being. Create a handle here, it will be copied to the handle field in | 317 | // the time being. Create a handle here, it will be copied to the handle field in |
| 320 | // the object and use by the rest of the code. This should be removed when other | 318 | // the object and use by the rest of the code. This should be removed when other |
| 321 | // code doesn't rely on the handle anymore. | 319 | // code doesn't rely on the handle anymore. |
| 322 | ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread); | 320 | ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread); |
| 323 | // TODO(yuriks): Plug memory leak | ||
| 324 | if (handle.Failed()) | 321 | if (handle.Failed()) |
| 325 | return handle.Code(); | 322 | return handle.Code(); |
| 326 | 323 | ||
| @@ -337,12 +334,12 @@ ResultVal<Thread*> Thread::Create(const char* name, u32 entry_point, s32 priorit | |||
| 337 | thread->wait_type = WAITTYPE_NONE; | 334 | thread->wait_type = WAITTYPE_NONE; |
| 338 | thread->wait_object = nullptr; | 335 | thread->wait_object = nullptr; |
| 339 | thread->wait_address = 0; | 336 | thread->wait_address = 0; |
| 340 | thread->name = name; | 337 | thread->name = std::move(name); |
| 341 | 338 | ||
| 342 | ResetThread(thread, arg, 0); | 339 | ResetThread(thread.get(), arg, 0); |
| 343 | CallThread(thread); | 340 | CallThread(thread.get()); |
| 344 | 341 | ||
| 345 | return MakeResult<Thread*>(thread); | 342 | return MakeResult<SharedPtr<Thread>>(std::move(thread)); |
| 346 | } | 343 | } |
| 347 | 344 | ||
| 348 | /// Set the priority of the thread specified by handle | 345 | /// Set the priority of the thread specified by handle |
| @@ -376,20 +373,20 @@ Handle SetupIdleThread() { | |||
| 376 | auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, | 373 | auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, |
| 377 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); | 374 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); |
| 378 | _dbg_assert_(Kernel, thread_res.Succeeded()); | 375 | _dbg_assert_(Kernel, thread_res.Succeeded()); |
| 379 | Thread* thread = *thread_res; | 376 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 380 | 377 | ||
| 381 | thread->idle = true; | 378 | thread->idle = true; |
| 382 | CallThread(thread); | 379 | CallThread(thread.get()); |
| 383 | return thread->GetHandle(); | 380 | return thread->GetHandle(); |
| 384 | } | 381 | } |
| 385 | 382 | ||
| 386 | Thread* SetupMainThread(s32 priority, int stack_size) { | 383 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size) { |
| 387 | // Initialize new "main" thread | 384 | // Initialize new "main" thread |
| 388 | ResultVal<Thread*> thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0, | 385 | auto thread_res = Thread::Create("main", Core::g_app_core->GetPC(), priority, 0, |
| 389 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); | 386 | THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size); |
| 390 | // TODO(yuriks): Propagate error | 387 | // TODO(yuriks): Propagate error |
| 391 | _dbg_assert_(Kernel, thread_res.Succeeded()); | 388 | _dbg_assert_(Kernel, thread_res.Succeeded()); |
| 392 | Thread* thread = *thread_res; | 389 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 393 | 390 | ||
| 394 | // If running another thread already, set it to "ready" state | 391 | // If running another thread already, set it to "ready" state |
| 395 | Thread* cur = GetCurrentThread(); | 392 | Thread* cur = GetCurrentThread(); |
| @@ -398,7 +395,7 @@ Thread* SetupMainThread(s32 priority, int stack_size) { | |||
| 398 | } | 395 | } |
| 399 | 396 | ||
| 400 | // Run new "main" thread | 397 | // Run new "main" thread |
| 401 | current_thread = thread; | 398 | current_thread = thread.get(); |
| 402 | thread->status = THREADSTATUS_RUNNING; | 399 | thread->status = THREADSTATUS_RUNNING; |
| 403 | Core::g_app_core->LoadContext(thread->context); | 400 | Core::g_app_core->LoadContext(thread->context); |
| 404 | 401 | ||
| @@ -418,7 +415,7 @@ void Reschedule() { | |||
| 418 | } else { | 415 | } else { |
| 419 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); | 416 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); |
| 420 | 417 | ||
| 421 | for (Thread* thread : thread_list) { | 418 | for (auto& thread : thread_list) { |
| 422 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", | 419 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X wait_type=0x%08X wait_handle=0x%08X", |
| 423 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, | 420 | thread->GetHandle(), thread->current_priority, thread->status, thread->wait_type, |
| 424 | (thread->wait_object ? thread->wait_object->GetHandle() : INVALID_HANDLE)); | 421 | (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 { | |||
| 54 | 54 | ||
| 55 | class Thread : public Kernel::Object { | 55 | class Thread : public Kernel::Object { |
| 56 | public: | 56 | public: |
| 57 | static ResultVal<Thread*> Create(const char* name, u32 entry_point, s32 priority, u32 arg, | 57 | static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, |
| 58 | s32 processor_id, u32 stack_top, int stack_size = Kernel::DEFAULT_STACK_SIZE); | 58 | u32 arg, s32 processor_id, VAddr stack_top, u32 stack_size); |
| 59 | 59 | ||
| 60 | std::string GetName() const override { return name; } | 60 | std::string GetName() const override { return name; } |
| 61 | std::string GetTypeName() const override { return "Thread"; } | 61 | std::string GetTypeName() const override { return "Thread"; } |
| @@ -99,7 +99,7 @@ public: | |||
| 99 | Object* wait_object; | 99 | Object* wait_object; |
| 100 | VAddr wait_address; | 100 | VAddr wait_address; |
| 101 | 101 | ||
| 102 | std::vector<Thread*> waiting_threads; // TODO(yuriks): Owned | 102 | std::vector<SharedPtr<Thread>> waiting_threads; |
| 103 | 103 | ||
| 104 | std::string name; | 104 | std::string name; |
| 105 | 105 | ||
| @@ -111,7 +111,7 @@ private: | |||
| 111 | }; | 111 | }; |
| 112 | 112 | ||
| 113 | /// Sets up the primary application thread | 113 | /// Sets up the primary application thread |
| 114 | Thread* SetupMainThread(s32 priority, int stack_size = Kernel::DEFAULT_STACK_SIZE); | 114 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size); |
| 115 | 115 | ||
| 116 | /// Reschedules to the next available thread (call after current thread is suspended) | 116 | /// Reschedules to the next available thread (call after current thread is suspended) |
| 117 | void Reschedule(); | 117 | 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 | |||
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | ResultCode ClearTimer(Handle handle) { | 68 | ResultCode ClearTimer(Handle handle) { |
| 69 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 69 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 70 | 70 | ||
| 71 | if (timer == nullptr) | 71 | if (timer == nullptr) |
| 72 | return InvalidHandle(ErrorModule::Kernel); | 72 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -80,7 +80,7 @@ static int TimerCallbackEventType = -1; | |||
| 80 | 80 | ||
| 81 | /// The timer callback event, called when a timer is fired | 81 | /// The timer callback event, called when a timer is fired |
| 82 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 82 | static void TimerCallback(u64 timer_handle, int cycles_late) { |
| 83 | Timer* timer = Kernel::g_handle_table.Get<Timer>(timer_handle); | 83 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle); |
| 84 | 84 | ||
| 85 | if (timer == nullptr) { | 85 | if (timer == nullptr) { |
| 86 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle); | 86 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle); |
| @@ -93,7 +93,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 93 | 93 | ||
| 94 | // Resume all waiting threads | 94 | // Resume all waiting threads |
| 95 | for (Handle thread_handle : timer->waiting_threads) { | 95 | for (Handle thread_handle : timer->waiting_threads) { |
| 96 | if (Thread* thread = Kernel::g_handle_table.Get<Thread>(thread_handle)) | 96 | if (SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(thread_handle)) |
| 97 | thread->ResumeFromWait(); | 97 | thread->ResumeFromWait(); |
| 98 | } | 98 | } |
| 99 | 99 | ||
| @@ -111,7 +111,7 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 111 | } | 111 | } |
| 112 | 112 | ||
| 113 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { | 113 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { |
| 114 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 114 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 115 | 115 | ||
| 116 | if (timer == nullptr) | 116 | if (timer == nullptr) |
| 117 | return InvalidHandle(ErrorModule::Kernel); | 117 | return InvalidHandle(ErrorModule::Kernel); |
| @@ -125,7 +125,7 @@ ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { | |||
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | ResultCode CancelTimer(Handle handle) { | 127 | ResultCode CancelTimer(Handle handle) { |
| 128 | Timer* timer = Kernel::g_handle_table.Get<Timer>(handle); | 128 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); |
| 129 | 129 | ||
| 130 | if (timer == nullptr) | 130 | if (timer == nullptr) |
| 131 | return InvalidHandle(ErrorModule::Kernel); | 131 | 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) { | |||
| 59 | } | 59 | } |
| 60 | 60 | ||
| 61 | Interface* Manager::FetchFromHandle(Handle handle) { | 61 | Interface* Manager::FetchFromHandle(Handle handle) { |
| 62 | return Kernel::g_handle_table.Get<Interface>(handle); | 62 | // TODO(yuriks): This function is very suspicious and should probably be exterminated. |
| 63 | return Kernel::g_handle_table.Get<Interface>(handle).get(); | ||
| 63 | } | 64 | } |
| 64 | 65 | ||
| 65 | Interface* Manager::FetchFromPortName(const std::string& port_name) { | 66 | 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 @@ | |||
| 25 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 25 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 26 | // Namespace SVC | 26 | // Namespace SVC |
| 27 | 27 | ||
| 28 | using Kernel::SharedPtr; | ||
| 29 | |||
| 28 | namespace SVC { | 30 | namespace SVC { |
| 29 | 31 | ||
| 30 | enum ControlMemoryOperation { | 32 | enum ControlMemoryOperation { |
| @@ -94,7 +96,7 @@ static Result ConnectToPort(Handle* out, const char* port_name) { | |||
| 94 | 96 | ||
| 95 | /// Synchronize to an OS service | 97 | /// Synchronize to an OS service |
| 96 | static Result SendSyncRequest(Handle handle) { | 98 | static Result SendSyncRequest(Handle handle) { |
| 97 | Kernel::Session* session = Kernel::g_handle_table.Get<Kernel::Session>(handle); | 99 | SharedPtr<Kernel::Session> session = Kernel::g_handle_table.Get<Kernel::Session>(handle); |
| 98 | if (session == nullptr) { | 100 | if (session == nullptr) { |
| 99 | return InvalidHandle(ErrorModule::Kernel).raw; | 101 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 100 | } | 102 | } |
| @@ -121,12 +123,12 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | |||
| 121 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this | 123 | // TODO(bunnei): Do something with nano_seconds, currently ignoring this |
| 122 | bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated | 124 | bool wait_infinite = (nano_seconds == -1); // Used to wait until a thread has terminated |
| 123 | 125 | ||
| 124 | Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handle); | 126 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handle); |
| 125 | if (object == nullptr) | 127 | if (object == nullptr) |
| 126 | return InvalidHandle(ErrorModule::Kernel).raw; | 128 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 127 | 129 | ||
| 128 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(), | 130 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, |
| 129 | object->GetName().c_str(), nano_seconds); | 131 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); |
| 130 | 132 | ||
| 131 | ResultVal<bool> wait = object->WaitSynchronization(); | 133 | ResultVal<bool> wait = object->WaitSynchronization(); |
| 132 | 134 | ||
| @@ -151,12 +153,12 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 151 | 153 | ||
| 152 | // Iterate through each handle, synchronize kernel object | 154 | // Iterate through each handle, synchronize kernel object |
| 153 | for (s32 i = 0; i < handle_count; i++) { | 155 | for (s32 i = 0; i < handle_count; i++) { |
| 154 | Kernel::Object* object = Kernel::g_handle_table.GetGeneric(handles[i]); | 156 | SharedPtr<Kernel::Object> object = Kernel::g_handle_table.GetGeneric(handles[i]); |
| 155 | if (object == nullptr) | 157 | if (object == nullptr) |
| 156 | return InvalidHandle(ErrorModule::Kernel).raw; | 158 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 157 | 159 | ||
| 158 | LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], object->GetTypeName().c_str(), | 160 | LOG_TRACE(Kernel_SVC, "\thandle[%d] = 0x%08X(%s:%s)", i, handles[i], |
| 159 | object->GetName().c_str()); | 161 | object->GetTypeName().c_str(), object->GetName().c_str()); |
| 160 | 162 | ||
| 161 | // TODO(yuriks): Verify how the real function behaves when an error happens here | 163 | // TODO(yuriks): Verify how the real function behaves when an error happens here |
| 162 | ResultVal<bool> wait_result = object->WaitSynchronization(); | 164 | ResultVal<bool> wait_result = object->WaitSynchronization(); |
| @@ -223,6 +225,8 @@ static Result GetResourceLimitCurrentValues(s64* values, Handle resource_limit, | |||
| 223 | 225 | ||
| 224 | /// Creates a new thread | 226 | /// Creates a new thread |
| 225 | static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) { | 227 | static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top, u32 processor_id) { |
| 228 | using Kernel::Thread; | ||
| 229 | |||
| 226 | std::string name; | 230 | std::string name; |
| 227 | if (Symbols::HasSymbol(entry_point)) { | 231 | if (Symbols::HasSymbol(entry_point)) { |
| 228 | TSymbol symbol = Symbols::GetSymbol(entry_point); | 232 | TSymbol symbol = Symbols::GetSymbol(entry_point); |
| @@ -231,12 +235,13 @@ static Result CreateThread(u32 priority, u32 entry_point, u32 arg, u32 stack_top | |||
| 231 | name = Common::StringFromFormat("unknown-%08x", entry_point); | 235 | name = Common::StringFromFormat("unknown-%08x", entry_point); |
| 232 | } | 236 | } |
| 233 | 237 | ||
| 234 | ResultVal<Kernel::Thread*> thread_res = Kernel::Thread::Create(name.c_str(), entry_point, priority, arg, | 238 | ResultVal<SharedPtr<Thread>> thread_res = Kernel::Thread::Create( |
| 235 | processor_id, stack_top); | 239 | name, entry_point, priority, arg, processor_id, stack_top, Kernel::DEFAULT_STACK_SIZE); |
| 236 | if (thread_res.Failed()) | 240 | if (thread_res.Failed()) |
| 237 | return thread_res.Code().raw; | 241 | return thread_res.Code().raw; |
| 238 | Kernel::Thread* thread = *thread_res; | 242 | SharedPtr<Thread> thread = std::move(*thread_res); |
| 239 | 243 | ||
| 244 | // TODO(yuriks): Create new handle instead of using built-in | ||
| 240 | Core::g_app_core->SetReg(1, thread->GetHandle()); | 245 | Core::g_app_core->SetReg(1, thread->GetHandle()); |
| 241 | 246 | ||
| 242 | LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " | 247 | LOG_TRACE(Kernel_SVC, "called entrypoint=0x%08X (%s), arg=0x%08X, stacktop=0x%08X, " |
| @@ -261,7 +266,7 @@ static void ExitThread() { | |||
| 261 | 266 | ||
| 262 | /// Gets the priority for the specified thread | 267 | /// Gets the priority for the specified thread |
| 263 | static Result GetThreadPriority(s32* priority, Handle handle) { | 268 | static Result GetThreadPriority(s32* priority, Handle handle) { |
| 264 | const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 269 | const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 265 | if (thread == nullptr) | 270 | if (thread == nullptr) |
| 266 | return InvalidHandle(ErrorModule::Kernel).raw; | 271 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 267 | 272 | ||
| @@ -271,7 +276,7 @@ static Result GetThreadPriority(s32* priority, Handle handle) { | |||
| 271 | 276 | ||
| 272 | /// Sets the priority for the specified thread | 277 | /// Sets the priority for the specified thread |
| 273 | static Result SetThreadPriority(Handle handle, s32 priority) { | 278 | static Result SetThreadPriority(Handle handle, s32 priority) { |
| 274 | Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 279 | SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 275 | if (thread == nullptr) | 280 | if (thread == nullptr) |
| 276 | return InvalidHandle(ErrorModule::Kernel).raw; | 281 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 277 | 282 | ||
| @@ -298,7 +303,7 @@ static Result ReleaseMutex(Handle handle) { | |||
| 298 | static Result GetThreadId(u32* thread_id, Handle handle) { | 303 | static Result GetThreadId(u32* thread_id, Handle handle) { |
| 299 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle); | 304 | LOG_TRACE(Kernel_SVC, "called thread=0x%08X", handle); |
| 300 | 305 | ||
| 301 | const Kernel::Thread* thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); | 306 | const SharedPtr<Kernel::Thread> thread = Kernel::g_handle_table.Get<Kernel::Thread>(handle); |
| 302 | if (thread == nullptr) | 307 | if (thread == nullptr) |
| 303 | return InvalidHandle(ErrorModule::Kernel).raw; | 308 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 304 | 309 | ||