diff options
| author | 2015-02-02 13:04:04 -0500 | |
|---|---|---|
| committer | 2015-02-02 13:04:04 -0500 | |
| commit | 7f730ed158bc9bba064100b9644b318134ef0bb3 (patch) | |
| tree | c4181a69ff882e1af1b7d65bf3596a6cb3dd88b9 /src | |
| parent | Merge pull request #517 from bunnei/blend-factors (diff) | |
| parent | Kernel: Stop creating useless Handles during object creation (diff) | |
| download | yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.gz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.tar.xz yuzu-7f730ed158bc9bba064100b9644b318134ef0bb3.zip | |
Merge pull request #523 from yuriks/kernel-lifetime5
Kernel Lifetime Reform Pt. 5: The Reckoning
Diffstat (limited to 'src')
70 files changed, 367 insertions, 372 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ac173c486..0ab0e440c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -26,6 +26,7 @@ set(SRCS | |||
| 26 | hle/kernel/kernel.cpp | 26 | hle/kernel/kernel.cpp |
| 27 | hle/kernel/mutex.cpp | 27 | hle/kernel/mutex.cpp |
| 28 | hle/kernel/semaphore.cpp | 28 | hle/kernel/semaphore.cpp |
| 29 | hle/kernel/session.cpp | ||
| 29 | hle/kernel/shared_memory.cpp | 30 | hle/kernel/shared_memory.cpp |
| 30 | hle/kernel/timer.cpp | 31 | hle/kernel/timer.cpp |
| 31 | hle/kernel/thread.cpp | 32 | hle/kernel/thread.cpp |
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index 2d01e2ef5..42f8ce2d9 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp | |||
| @@ -15,14 +15,15 @@ | |||
| 15 | 15 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
| 18 | ResultVal<SharedPtr<AddressArbiter>> AddressArbiter::Create(std::string name) { | 18 | AddressArbiter::AddressArbiter() {} |
| 19 | AddressArbiter::~AddressArbiter() {} | ||
| 20 | |||
| 21 | SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) { | ||
| 19 | SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter); | 22 | SharedPtr<AddressArbiter> address_arbiter(new AddressArbiter); |
| 20 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 21 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(address_arbiter)); | ||
| 22 | 23 | ||
| 23 | address_arbiter->name = std::move(name); | 24 | address_arbiter->name = std::move(name); |
| 24 | 25 | ||
| 25 | return MakeResult<SharedPtr<AddressArbiter>>(std::move(address_arbiter)); | 26 | return address_arbiter; |
| 26 | } | 27 | } |
| 27 | 28 | ||
| 28 | ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, | 29 | ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, |
| @@ -51,7 +52,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, | |||
| 51 | case ArbitrationType::WaitIfLessThanWithTimeout: | 52 | case ArbitrationType::WaitIfLessThanWithTimeout: |
| 52 | if ((s32)Memory::Read32(address) <= value) { | 53 | if ((s32)Memory::Read32(address) <= value) { |
| 53 | Kernel::WaitCurrentThread_ArbitrateAddress(address); | 54 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 54 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); | 55 | GetCurrentThread()->WakeAfterDelay(nanoseconds); |
| 55 | HLE::Reschedule(__func__); | 56 | HLE::Reschedule(__func__); |
| 56 | } | 57 | } |
| 57 | break; | 58 | break; |
| @@ -71,7 +72,7 @@ ResultCode AddressArbiter::ArbitrateAddress(ArbitrationType type, VAddr address, | |||
| 71 | Memory::Write32(address, memory_value); | 72 | Memory::Write32(address, memory_value); |
| 72 | if (memory_value <= value) { | 73 | if (memory_value <= value) { |
| 73 | Kernel::WaitCurrentThread_ArbitrateAddress(address); | 74 | Kernel::WaitCurrentThread_ArbitrateAddress(address); |
| 74 | Kernel::WakeThreadAfterDelay(GetCurrentThread(), nanoseconds); | 75 | GetCurrentThread()->WakeAfterDelay(nanoseconds); |
| 75 | HLE::Reschedule(__func__); | 76 | HLE::Reschedule(__func__); |
| 76 | } | 77 | } |
| 77 | break; | 78 | break; |
diff --git a/src/core/hle/kernel/address_arbiter.h b/src/core/hle/kernel/address_arbiter.h index 638afff9e..8f6a1a8df 100644 --- a/src/core/hle/kernel/address_arbiter.h +++ b/src/core/hle/kernel/address_arbiter.h | |||
| @@ -34,7 +34,7 @@ public: | |||
| 34 | * @param name Optional name used for debugging. | 34 | * @param name Optional name used for debugging. |
| 35 | * @returns The created AddressArbiter. | 35 | * @returns The created AddressArbiter. |
| 36 | */ | 36 | */ |
| 37 | static ResultVal<SharedPtr<AddressArbiter>> Create(std::string name = "Unknown"); | 37 | static SharedPtr<AddressArbiter> Create(std::string name = "Unknown"); |
| 38 | 38 | ||
| 39 | std::string GetTypeName() const override { return "Arbiter"; } | 39 | std::string GetTypeName() const override { return "Arbiter"; } |
| 40 | std::string GetName() const override { return name; } | 40 | std::string GetName() const override { return name; } |
| @@ -47,7 +47,8 @@ public: | |||
| 47 | ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); | 47 | ResultCode ArbitrateAddress(ArbitrationType type, VAddr address, s32 value, u64 nanoseconds); |
| 48 | 48 | ||
| 49 | private: | 49 | private: |
| 50 | AddressArbiter() = default; | 50 | AddressArbiter(); |
| 51 | ~AddressArbiter() override; | ||
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | } // namespace FileSys | 54 | } // namespace FileSys |
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index d9ad40c6a..898e1c98f 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp | |||
| @@ -14,16 +14,17 @@ | |||
| 14 | 14 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | ResultVal<SharedPtr<Event>> Event::Create(ResetType reset_type, std::string name) { | 17 | Event::Event() {} |
| 18 | Event::~Event() {} | ||
| 19 | |||
| 20 | SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) { | ||
| 18 | SharedPtr<Event> evt(new Event); | 21 | SharedPtr<Event> evt(new Event); |
| 19 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 20 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(evt)); | ||
| 21 | 22 | ||
| 22 | evt->signaled = false; | 23 | evt->signaled = false; |
| 23 | evt->reset_type = evt->intitial_reset_type = reset_type; | 24 | evt->reset_type = evt->intitial_reset_type = reset_type; |
| 24 | evt->name = std::move(name); | 25 | evt->name = std::move(name); |
| 25 | 26 | ||
| 26 | return MakeResult<SharedPtr<Event>>(evt); | 27 | return evt; |
| 27 | } | 28 | } |
| 28 | 29 | ||
| 29 | bool Event::ShouldWait() { | 30 | bool Event::ShouldWait() { |
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h index 2c3e6b14e..fba960d2a 100644 --- a/src/core/hle/kernel/event.h +++ b/src/core/hle/kernel/event.h | |||
| @@ -18,7 +18,7 @@ public: | |||
| 18 | * @param reset_type ResetType describing how to create event | 18 | * @param reset_type ResetType describing how to create event |
| 19 | * @param name Optional name of event | 19 | * @param name Optional name of event |
| 20 | */ | 20 | */ |
| 21 | static ResultVal<SharedPtr<Event>> Create(ResetType reset_type, std::string name = "Unknown"); | 21 | static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown"); |
| 22 | 22 | ||
| 23 | std::string GetTypeName() const override { return "Event"; } | 23 | std::string GetTypeName() const override { return "Event"; } |
| 24 | std::string GetName() const override { return name; } | 24 | std::string GetName() const override { return name; } |
| @@ -39,7 +39,8 @@ public: | |||
| 39 | void Clear(); | 39 | void Clear(); |
| 40 | 40 | ||
| 41 | private: | 41 | private: |
| 42 | Event() = default; | 42 | Event(); |
| 43 | ~Event() override; | ||
| 43 | }; | 44 | }; |
| 44 | 45 | ||
| 45 | } // namespace | 46 | } // namespace |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d7fa4dcea..7e0b9542e 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -14,14 +14,16 @@ | |||
| 14 | 14 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | unsigned int Object::next_object_id = 0; | ||
| 18 | |||
| 17 | SharedPtr<Thread> g_main_thread = nullptr; | 19 | SharedPtr<Thread> g_main_thread = nullptr; |
| 18 | HandleTable g_handle_table; | 20 | HandleTable g_handle_table; |
| 19 | u64 g_program_id = 0; | 21 | u64 g_program_id = 0; |
| 20 | 22 | ||
| 21 | void WaitObject::AddWaitingThread(Thread* thread) { | 23 | void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { |
| 22 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); | 24 | auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); |
| 23 | if (itr == waiting_threads.end()) | 25 | if (itr == waiting_threads.end()) |
| 24 | waiting_threads.push_back(thread); | 26 | waiting_threads.push_back(std::move(thread)); |
| 25 | } | 27 | } |
| 26 | 28 | ||
| 27 | void WaitObject::RemoveWaitingThread(Thread* thread) { | 29 | void WaitObject::RemoveWaitingThread(Thread* thread) { |
| @@ -30,11 +32,11 @@ void WaitObject::RemoveWaitingThread(Thread* thread) { | |||
| 30 | waiting_threads.erase(itr); | 32 | waiting_threads.erase(itr); |
| 31 | } | 33 | } |
| 32 | 34 | ||
| 33 | Thread* WaitObject::WakeupNextThread() { | 35 | SharedPtr<Thread> WaitObject::WakeupNextThread() { |
| 34 | if (waiting_threads.empty()) | 36 | if (waiting_threads.empty()) |
| 35 | return nullptr; | 37 | return nullptr; |
| 36 | 38 | ||
| 37 | auto next_thread = waiting_threads.front(); | 39 | auto next_thread = std::move(waiting_threads.front()); |
| 38 | waiting_threads.erase(waiting_threads.begin()); | 40 | waiting_threads.erase(waiting_threads.begin()); |
| 39 | 41 | ||
| 40 | next_thread->ReleaseWaitObject(this); | 42 | next_thread->ReleaseWaitObject(this); |
| @@ -74,13 +76,10 @@ ResultVal<Handle> HandleTable::Create(SharedPtr<Object> obj) { | |||
| 74 | // CTR-OS doesn't use generation 0, so skip straight to 1. | 76 | // CTR-OS doesn't use generation 0, so skip straight to 1. |
| 75 | if (next_generation >= (1 << 15)) next_generation = 1; | 77 | if (next_generation >= (1 << 15)) next_generation = 1; |
| 76 | 78 | ||
| 77 | Handle handle = generation | (slot << 15); | ||
| 78 | if (obj->handle == INVALID_HANDLE) | ||
| 79 | obj->handle = handle; | ||
| 80 | |||
| 81 | generations[slot] = generation; | 79 | generations[slot] = generation; |
| 82 | objects[slot] = std::move(obj); | 80 | objects[slot] = std::move(obj); |
| 83 | 81 | ||
| 82 | Handle handle = generation | (slot << 15); | ||
| 84 | return MakeResult<Handle>(handle); | 83 | return MakeResult<Handle>(handle); |
| 85 | } | 84 | } |
| 86 | 85 | ||
| @@ -102,7 +101,7 @@ ResultCode HandleTable::Close(Handle handle) { | |||
| 102 | 101 | ||
| 103 | objects[slot] = nullptr; | 102 | objects[slot] = nullptr; |
| 104 | 103 | ||
| 105 | generations[generation] = next_free_slot; | 104 | generations[slot] = next_free_slot; |
| 106 | next_free_slot = slot; | 105 | next_free_slot = slot; |
| 107 | return RESULT_SUCCESS; | 106 | return RESULT_SUCCESS; |
| 108 | } | 107 | } |
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 9860479ac..4d8e388b6 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -58,14 +58,12 @@ enum { | |||
| 58 | DEFAULT_STACK_SIZE = 0x4000, | 58 | DEFAULT_STACK_SIZE = 0x4000, |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | class HandleTable; | ||
| 62 | |||
| 63 | class Object : NonCopyable { | 61 | class Object : NonCopyable { |
| 64 | friend class HandleTable; | ||
| 65 | u32 handle = INVALID_HANDLE; | ||
| 66 | public: | 62 | public: |
| 67 | virtual ~Object() {} | 63 | virtual ~Object() {} |
| 68 | Handle GetHandle() const { return handle; } | 64 | |
| 65 | /// Returns a unique identifier for the object. For debugging purposes only. | ||
| 66 | unsigned int GetObjectId() const { return object_id; } | ||
| 69 | 67 | ||
| 70 | virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } | 68 | virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } |
| 71 | virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } | 69 | virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } |
| @@ -101,7 +99,10 @@ private: | |||
| 101 | friend void intrusive_ptr_add_ref(Object*); | 99 | friend void intrusive_ptr_add_ref(Object*); |
| 102 | friend void intrusive_ptr_release(Object*); | 100 | friend void intrusive_ptr_release(Object*); |
| 103 | 101 | ||
| 102 | static unsigned int next_object_id; | ||
| 103 | |||
| 104 | unsigned int ref_count = 0; | 104 | unsigned int ref_count = 0; |
| 105 | unsigned int object_id = next_object_id++; | ||
| 105 | }; | 106 | }; |
| 106 | 107 | ||
| 107 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting | 108 | // Special functions used by boost::instrusive_ptr to do automatic ref-counting |
| @@ -135,25 +136,26 @@ public: | |||
| 135 | * Add a thread to wait on this object | 136 | * Add a thread to wait on this object |
| 136 | * @param thread Pointer to thread to add | 137 | * @param thread Pointer to thread to add |
| 137 | */ | 138 | */ |
| 138 | void AddWaitingThread(Thread* thread); | 139 | void AddWaitingThread(SharedPtr<Thread> thread); |
| 139 | 140 | ||
| 140 | /** | 141 | /** |
| 141 | * Removes a thread from waiting on this object (e.g. if it was resumed already) | 142 | * Removes a thread from waiting on this object (e.g. if it was resumed already) |
| 142 | * @param thread Pointer to thread to remove | 143 | * @param thread Pointer to thread to remove |
| 143 | */ | 144 | */ |
| 144 | void RemoveWaitingThread(Thread* thead); | 145 | void RemoveWaitingThread(Thread* thread); |
| 145 | 146 | ||
| 146 | /** | 147 | /** |
| 147 | * Wake up the next thread waiting on this object | 148 | * Wake up the next thread waiting on this object |
| 148 | * @return Pointer to the thread that was resumed, nullptr if no threads are waiting | 149 | * @return Pointer to the thread that was resumed, nullptr if no threads are waiting |
| 149 | */ | 150 | */ |
| 150 | Thread* WakeupNextThread(); | 151 | SharedPtr<Thread> WakeupNextThread(); |
| 151 | 152 | ||
| 152 | /// Wake up all threads waiting on this object | 153 | /// Wake up all threads waiting on this object |
| 153 | void WakeupAllWaitingThreads(); | 154 | void WakeupAllWaitingThreads(); |
| 154 | 155 | ||
| 155 | private: | 156 | private: |
| 156 | std::vector<Thread*> waiting_threads; ///< Threads waiting for this object to become available | 157 | /// Threads waiting for this object to become available |
| 158 | std::vector<SharedPtr<Thread>> waiting_threads; | ||
| 157 | }; | 159 | }; |
| 158 | 160 | ||
| 159 | /** | 161 | /** |
| @@ -274,7 +276,6 @@ private: | |||
| 274 | }; | 276 | }; |
| 275 | 277 | ||
| 276 | extern HandleTable g_handle_table; | 278 | extern HandleTable g_handle_table; |
| 277 | extern SharedPtr<Thread> g_main_thread; | ||
| 278 | 279 | ||
| 279 | /// The ID code of the currently running game | 280 | /// The ID code of the currently running game |
| 280 | /// TODO(Subv): This variable should not be here, | 281 | /// 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 acf484659..9f7166ca4 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | #include <map> | 5 | #include <map> |
| 6 | #include <vector> | 6 | #include <vector> |
| 7 | 7 | ||
| 8 | #include <boost/range/algorithm_ext/erase.hpp> | ||
| 9 | |||
| 8 | #include "common/common.h" | 10 | #include "common/common.h" |
| 9 | 11 | ||
| 10 | #include "core/hle/kernel/kernel.h" | 12 | #include "core/hle/kernel/kernel.h" |
| @@ -13,9 +15,6 @@ | |||
| 13 | 15 | ||
| 14 | namespace Kernel { | 16 | namespace Kernel { |
| 15 | 17 | ||
| 16 | typedef std::multimap<SharedPtr<Thread>, SharedPtr<Mutex>> MutexMap; | ||
| 17 | static MutexMap g_mutex_held_locks; | ||
| 18 | |||
| 19 | /** | 18 | /** |
| 20 | * Resumes a thread waiting for the specified mutex | 19 | * Resumes a thread waiting for the specified mutex |
| 21 | * @param mutex The mutex that some thread is waiting on | 20 | * @param mutex The mutex that some thread is waiting on |
| @@ -33,21 +32,17 @@ static void ResumeWaitingThread(Mutex* mutex) { | |||
| 33 | } | 32 | } |
| 34 | 33 | ||
| 35 | void ReleaseThreadMutexes(Thread* thread) { | 34 | void ReleaseThreadMutexes(Thread* thread) { |
| 36 | auto locked_range = g_mutex_held_locks.equal_range(thread); | 35 | for (auto& mtx : thread->held_mutexes) { |
| 37 | 36 | ResumeWaitingThread(mtx.get()); | |
| 38 | // Release every mutex that the thread holds, and resume execution on the waiting threads | ||
| 39 | for (auto iter = locked_range.first; iter != locked_range.second; ++iter) { | ||
| 40 | ResumeWaitingThread(iter->second.get()); | ||
| 41 | } | 37 | } |
| 42 | 38 | thread->held_mutexes.clear(); | |
| 43 | // Erase all the locks that this thread holds | ||
| 44 | g_mutex_held_locks.erase(thread); | ||
| 45 | } | 39 | } |
| 46 | 40 | ||
| 47 | ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) { | 41 | Mutex::Mutex() {} |
| 42 | Mutex::~Mutex() {} | ||
| 43 | |||
| 44 | SharedPtr<Mutex> Mutex::Create(bool initial_locked, std::string name) { | ||
| 48 | SharedPtr<Mutex> mutex(new Mutex); | 45 | SharedPtr<Mutex> mutex(new Mutex); |
| 49 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 50 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(mutex)); | ||
| 51 | 46 | ||
| 52 | mutex->initial_locked = initial_locked; | 47 | mutex->initial_locked = initial_locked; |
| 53 | mutex->locked = false; | 48 | mutex->locked = false; |
| @@ -58,7 +53,7 @@ ResultVal<SharedPtr<Mutex>> Mutex::Create(bool initial_locked, std::string name) | |||
| 58 | if (initial_locked) | 53 | if (initial_locked) |
| 59 | mutex->Acquire(); | 54 | mutex->Acquire(); |
| 60 | 55 | ||
| 61 | return MakeResult<SharedPtr<Mutex>>(mutex); | 56 | return mutex; |
| 62 | } | 57 | } |
| 63 | 58 | ||
| 64 | bool Mutex::ShouldWait() { | 59 | bool Mutex::ShouldWait() { |
| @@ -69,30 +64,22 @@ void Mutex::Acquire() { | |||
| 69 | Acquire(GetCurrentThread()); | 64 | Acquire(GetCurrentThread()); |
| 70 | } | 65 | } |
| 71 | 66 | ||
| 72 | void Mutex::Acquire(Thread* thread) { | 67 | void Mutex::Acquire(SharedPtr<Thread> thread) { |
| 73 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); | 68 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); |
| 74 | if (locked) | 69 | if (locked) |
| 75 | return; | 70 | return; |
| 76 | 71 | ||
| 77 | locked = true; | 72 | locked = true; |
| 78 | 73 | ||
| 79 | g_mutex_held_locks.insert(std::make_pair(thread, this)); | 74 | thread->held_mutexes.insert(this); |
| 80 | holding_thread = thread; | 75 | holding_thread = std::move(thread); |
| 81 | } | 76 | } |
| 82 | 77 | ||
| 83 | void Mutex::Release() { | 78 | void Mutex::Release() { |
| 84 | if (!locked) | 79 | if (!locked) |
| 85 | return; | 80 | return; |
| 86 | 81 | ||
| 87 | auto locked_range = g_mutex_held_locks.equal_range(holding_thread); | 82 | holding_thread->held_mutexes.erase(this); |
| 88 | |||
| 89 | for (MutexMap::iterator iter = locked_range.first; iter != locked_range.second; ++iter) { | ||
| 90 | if (iter->second == this) { | ||
| 91 | g_mutex_held_locks.erase(iter); | ||
| 92 | break; | ||
| 93 | } | ||
| 94 | } | ||
| 95 | |||
| 96 | ResumeWaitingThread(this); | 83 | ResumeWaitingThread(this); |
| 97 | } | 84 | } |
| 98 | 85 | ||
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h index 1e69528f1..548403614 100644 --- a/src/core/hle/kernel/mutex.h +++ b/src/core/hle/kernel/mutex.h | |||
| @@ -22,7 +22,7 @@ public: | |||
| 22 | * @param name Optional name of mutex | 22 | * @param name Optional name of mutex |
| 23 | * @return Pointer to new Mutex object | 23 | * @return Pointer to new Mutex object |
| 24 | */ | 24 | */ |
| 25 | static ResultVal<SharedPtr<Mutex>> Create(bool initial_locked, std::string name = "Unknown"); | 25 | static SharedPtr<Mutex> Create(bool initial_locked, std::string name = "Unknown"); |
| 26 | 26 | ||
| 27 | std::string GetTypeName() const override { return "Mutex"; } | 27 | std::string GetTypeName() const override { return "Mutex"; } |
| 28 | std::string GetName() const override { return name; } | 28 | std::string GetName() const override { return name; } |
| @@ -43,11 +43,12 @@ public: | |||
| 43 | * @param mutex Mutex that is to be acquired | 43 | * @param mutex Mutex that is to be acquired |
| 44 | * @param thread Thread that will acquire the mutex | 44 | * @param thread Thread that will acquire the mutex |
| 45 | */ | 45 | */ |
| 46 | void Acquire(Thread* thread); | 46 | void Acquire(SharedPtr<Thread> thread); |
| 47 | void Release(); | 47 | void Release(); |
| 48 | 48 | ||
| 49 | private: | 49 | private: |
| 50 | Mutex() = default; | 50 | Mutex(); |
| 51 | ~Mutex() override; | ||
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | /** | 54 | /** |
diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index a9e406ef4..c8cf8b9a2 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp | |||
| @@ -10,6 +10,9 @@ | |||
| 10 | 10 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | Semaphore::Semaphore() {} | ||
| 14 | Semaphore::~Semaphore() {} | ||
| 15 | |||
| 13 | ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, | 16 | ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_count, |
| 14 | std::string name) { | 17 | std::string name) { |
| 15 | 18 | ||
| @@ -18,8 +21,6 @@ ResultVal<SharedPtr<Semaphore>> Semaphore::Create(s32 initial_count, s32 max_cou | |||
| 18 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); | 21 | ErrorSummary::WrongArgument, ErrorLevel::Permanent); |
| 19 | 22 | ||
| 20 | SharedPtr<Semaphore> semaphore(new Semaphore); | 23 | SharedPtr<Semaphore> semaphore(new Semaphore); |
| 21 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 22 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(semaphore)); | ||
| 23 | 24 | ||
| 24 | // When the semaphore is created, some slots are reserved for other threads, | 25 | // When the semaphore is created, some slots are reserved for other threads, |
| 25 | // and the rest is reserved for the caller thread | 26 | // and the rest is reserved for the caller thread |
diff --git a/src/core/hle/kernel/semaphore.h b/src/core/hle/kernel/semaphore.h index 9bb404ab6..d8dc1fd78 100644 --- a/src/core/hle/kernel/semaphore.h +++ b/src/core/hle/kernel/semaphore.h | |||
| @@ -47,7 +47,8 @@ public: | |||
| 47 | ResultVal<s32> Release(s32 release_count); | 47 | ResultVal<s32> Release(s32 release_count); |
| 48 | 48 | ||
| 49 | private: | 49 | private: |
| 50 | Semaphore() = default; | 50 | Semaphore(); |
| 51 | ~Semaphore() override; | ||
| 51 | }; | 52 | }; |
| 52 | 53 | ||
| 53 | } // namespace | 54 | } // namespace |
diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp new file mode 100644 index 000000000..0594967f8 --- /dev/null +++ b/src/core/hle/kernel/session.cpp | |||
| @@ -0,0 +1,13 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/session.h" | ||
| 6 | #include "core/hle/kernel/thread.h" | ||
| 7 | |||
| 8 | namespace Kernel { | ||
| 9 | |||
| 10 | Session::Session() {} | ||
| 11 | Session::~Session() {} | ||
| 12 | |||
| 13 | } | ||
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h index 1788e4375..7cc9332c9 100644 --- a/src/core/hle/kernel/session.h +++ b/src/core/hle/kernel/session.h | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include "core/hle/kernel/kernel.h" | 7 | #include "core/hle/kernel/kernel.h" |
| 8 | #include "core/mem_map.h" | ||
| 8 | 9 | ||
| 9 | namespace Kernel { | 10 | namespace Kernel { |
| 10 | 11 | ||
| @@ -43,6 +44,9 @@ inline static u32* GetCommandBuffer(const int offset=0) { | |||
| 43 | */ | 44 | */ |
| 44 | class Session : public WaitObject { | 45 | class Session : public WaitObject { |
| 45 | public: | 46 | public: |
| 47 | Session(); | ||
| 48 | ~Session() override; | ||
| 49 | |||
| 46 | std::string GetTypeName() const override { return "Session"; } | 50 | std::string GetTypeName() const override { return "Session"; } |
| 47 | 51 | ||
| 48 | static const HandleType HANDLE_TYPE = HandleType::Session; | 52 | static const HandleType HANDLE_TYPE = HandleType::Session; |
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index eff68d481..4211fcf04 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp | |||
| @@ -9,22 +9,23 @@ | |||
| 9 | 9 | ||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | 11 | ||
| 12 | ResultVal<SharedPtr<SharedMemory>> SharedMemory::Create(std::string name) { | 12 | SharedMemory::SharedMemory() {} |
| 13 | SharedPtr<SharedMemory> shared_memory(new SharedMemory); | 13 | SharedMemory::~SharedMemory() {} |
| 14 | 14 | ||
| 15 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | 15 | SharedPtr<SharedMemory> SharedMemory::Create(std::string name) { |
| 16 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(shared_memory)); | 16 | SharedPtr<SharedMemory> shared_memory(new SharedMemory); |
| 17 | 17 | ||
| 18 | shared_memory->name = std::move(name); | 18 | shared_memory->name = std::move(name); |
| 19 | return MakeResult<SharedPtr<SharedMemory>>(std::move(shared_memory)); | 19 | |
| 20 | return shared_memory; | ||
| 20 | } | 21 | } |
| 21 | 22 | ||
| 22 | ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, | 23 | ResultCode SharedMemory::Map(VAddr address, MemoryPermission permissions, |
| 23 | MemoryPermission other_permissions) { | 24 | MemoryPermission other_permissions) { |
| 24 | 25 | ||
| 25 | if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { | 26 | if (address < Memory::SHARED_MEMORY_VADDR || address >= Memory::SHARED_MEMORY_VADDR_END) { |
| 26 | LOG_ERROR(Kernel, "cannot map handle=0x%08X, address=0x%08X outside of shared mem bounds!", | 27 | LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X outside of shared mem bounds!", |
| 27 | GetHandle(), address); | 28 | GetObjectId(), address); |
| 28 | // TODO: Verify error code with hardware | 29 | // TODO: Verify error code with hardware |
| 29 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 30 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 30 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); | 31 | ErrorSummary::InvalidArgument, ErrorLevel::Permanent); |
| @@ -41,7 +42,7 @@ ResultVal<u8*> SharedMemory::GetPointer(u32 offset) { | |||
| 41 | if (base_address != 0) | 42 | if (base_address != 0) |
| 42 | return MakeResult<u8*>(Memory::GetPointer(base_address + offset)); | 43 | return MakeResult<u8*>(Memory::GetPointer(base_address + offset)); |
| 43 | 44 | ||
| 44 | LOG_ERROR(Kernel_SVC, "memory block handle=0x%08X not mapped!", GetHandle()); | 45 | LOG_ERROR(Kernel_SVC, "memory block id=%u not mapped!", GetObjectId()); |
| 45 | // TODO(yuriks): Verify error code. | 46 | // TODO(yuriks): Verify error code. |
| 46 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, | 47 | return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, |
| 47 | ErrorSummary::InvalidState, ErrorLevel::Permanent); | 48 | ErrorSummary::InvalidState, ErrorLevel::Permanent); |
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index d393e8175..5833b411c 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h | |||
| @@ -29,7 +29,7 @@ public: | |||
| 29 | * Creates a shared memory object | 29 | * Creates a shared memory object |
| 30 | * @param name Optional object name, used only for debugging purposes. | 30 | * @param name Optional object name, used only for debugging purposes. |
| 31 | */ | 31 | */ |
| 32 | static ResultVal<SharedPtr<SharedMemory>> Create(std::string name = "Unknown"); | 32 | static SharedPtr<SharedMemory> Create(std::string name = "Unknown"); |
| 33 | 33 | ||
| 34 | std::string GetTypeName() const override { return "SharedMemory"; } | 34 | std::string GetTypeName() const override { return "SharedMemory"; } |
| 35 | 35 | ||
| @@ -57,7 +57,8 @@ public: | |||
| 57 | std::string name; ///< Name of shared memory object (optional) | 57 | std::string name; ///< Name of shared memory object (optional) |
| 58 | 58 | ||
| 59 | private: | 59 | private: |
| 60 | SharedMemory() = default; | 60 | SharedMemory(); |
| 61 | ~SharedMemory() override; | ||
| 61 | }; | 62 | }; |
| 62 | 63 | ||
| 63 | } // namespace | 64 | } // namespace |
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 56950ebd4..3987f9608 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include <algorithm> | 5 | #include <algorithm> |
| 6 | #include <list> | 6 | #include <list> |
| 7 | #include <map> | ||
| 8 | #include <vector> | 7 | #include <vector> |
| 9 | 8 | ||
| 10 | #include "common/common.h" | 9 | #include "common/common.h" |
| @@ -41,6 +40,9 @@ static Thread* current_thread; | |||
| 41 | static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup | 40 | static const u32 INITIAL_THREAD_ID = 1; ///< The first available thread id at startup |
| 42 | static u32 next_thread_id; ///< The next available thread id | 41 | static u32 next_thread_id; ///< The next available thread id |
| 43 | 42 | ||
| 43 | Thread::Thread() {} | ||
| 44 | Thread::~Thread() {} | ||
| 45 | |||
| 44 | Thread* GetCurrentThread() { | 46 | Thread* GetCurrentThread() { |
| 45 | return current_thread; | 47 | return current_thread; |
| 46 | } | 48 | } |
| @@ -108,6 +110,9 @@ void Thread::Stop(const char* reason) { | |||
| 108 | WakeupAllWaitingThreads(); | 110 | WakeupAllWaitingThreads(); |
| 109 | 111 | ||
| 110 | // Stopped threads are never waiting. | 112 | // Stopped threads are never waiting. |
| 113 | for (auto& wait_object : wait_objects) { | ||
| 114 | wait_object->RemoveWaitingThread(this); | ||
| 115 | } | ||
| 111 | wait_objects.clear(); | 116 | wait_objects.clear(); |
| 112 | wait_address = 0; | 117 | wait_address = 0; |
| 113 | } | 118 | } |
| @@ -228,13 +233,15 @@ void WaitCurrentThread_ArbitrateAddress(VAddr wait_address) { | |||
| 228 | 233 | ||
| 229 | /// Event type for the thread wake up event | 234 | /// Event type for the thread wake up event |
| 230 | static int ThreadWakeupEventType = -1; | 235 | static int ThreadWakeupEventType = -1; |
| 236 | // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing | ||
| 237 | // us to simply use a pool index or similar. | ||
| 238 | static Kernel::HandleTable wakeup_callback_handle_table; | ||
| 231 | 239 | ||
| 232 | /// Callback that will wake up the thread it was scheduled for | 240 | /// Callback that will wake up the thread it was scheduled for |
| 233 | static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | 241 | static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) { |
| 234 | Handle handle = static_cast<Handle>(parameter); | 242 | SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>((Handle)thread_handle); |
| 235 | SharedPtr<Thread> thread = Kernel::g_handle_table.Get<Thread>(handle); | ||
| 236 | if (thread == nullptr) { | 243 | if (thread == nullptr) { |
| 237 | LOG_ERROR(Kernel, "Thread doesn't exist %u", handle); | 244 | LOG_CRITICAL(Kernel, "Callback fired for invalid thread %08X", thread_handle); |
| 238 | return; | 245 | return; |
| 239 | } | 246 | } |
| 240 | 247 | ||
| @@ -248,14 +255,13 @@ static void ThreadWakeupCallback(u64 parameter, int cycles_late) { | |||
| 248 | } | 255 | } |
| 249 | 256 | ||
| 250 | 257 | ||
| 251 | void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds) { | 258 | void Thread::WakeAfterDelay(s64 nanoseconds) { |
| 252 | // Don't schedule a wakeup if the thread wants to wait forever | 259 | // Don't schedule a wakeup if the thread wants to wait forever |
| 253 | if (nanoseconds == -1) | 260 | if (nanoseconds == -1) |
| 254 | return; | 261 | return; |
| 255 | _dbg_assert_(Kernel, thread != nullptr); | ||
| 256 | 262 | ||
| 257 | u64 microseconds = nanoseconds / 1000; | 263 | u64 microseconds = nanoseconds / 1000; |
| 258 | CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, thread->GetHandle()); | 264 | CoreTiming::ScheduleEvent(usToCycles(microseconds), ThreadWakeupEventType, callback_handle); |
| 259 | } | 265 | } |
| 260 | 266 | ||
| 261 | void Thread::ReleaseWaitObject(WaitObject* wait_object) { | 267 | void Thread::ReleaseWaitObject(WaitObject* wait_object) { |
| @@ -302,7 +308,7 @@ void Thread::ReleaseWaitObject(WaitObject* wait_object) { | |||
| 302 | 308 | ||
| 303 | void Thread::ResumeFromWait() { | 309 | void Thread::ResumeFromWait() { |
| 304 | // Cancel any outstanding wakeup events | 310 | // Cancel any outstanding wakeup events |
| 305 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, GetHandle()); | 311 | CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); |
| 306 | 312 | ||
| 307 | status &= ~THREADSTATUS_WAIT; | 313 | status &= ~THREADSTATUS_WAIT; |
| 308 | 314 | ||
| @@ -326,11 +332,11 @@ static void DebugThreadQueue() { | |||
| 326 | if (!thread) { | 332 | if (!thread) { |
| 327 | return; | 333 | return; |
| 328 | } | 334 | } |
| 329 | LOG_DEBUG(Kernel, "0x%02X 0x%08X (current)", thread->current_priority, GetCurrentThread()->GetHandle()); | 335 | LOG_DEBUG(Kernel, "0x%02X %u (current)", thread->current_priority, GetCurrentThread()->GetObjectId()); |
| 330 | for (auto& t : thread_list) { | 336 | for (auto& t : thread_list) { |
| 331 | s32 priority = thread_ready_queue.contains(t.get()); | 337 | s32 priority = thread_ready_queue.contains(t.get()); |
| 332 | if (priority != -1) { | 338 | if (priority != -1) { |
| 333 | LOG_DEBUG(Kernel, "0x%02X 0x%08X", priority, t->GetHandle()); | 339 | LOG_DEBUG(Kernel, "0x%02X %u", priority, t->GetObjectId()); |
| 334 | } | 340 | } |
| 335 | } | 341 | } |
| 336 | } | 342 | } |
| @@ -362,14 +368,6 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 362 | 368 | ||
| 363 | SharedPtr<Thread> thread(new Thread); | 369 | SharedPtr<Thread> thread(new Thread); |
| 364 | 370 | ||
| 365 | // TODO(yuriks): Thread requires a handle to be inserted into the various scheduling queues for | ||
| 366 | // the time being. Create a handle here, it will be copied to the handle field in | ||
| 367 | // the object and use by the rest of the code. This should be removed when other | ||
| 368 | // code doesn't rely on the handle anymore. | ||
| 369 | ResultVal<Handle> handle = Kernel::g_handle_table.Create(thread); | ||
| 370 | if (handle.Failed()) | ||
| 371 | return handle.Code(); | ||
| 372 | |||
| 373 | thread_list.push_back(thread); | 371 | thread_list.push_back(thread); |
| 374 | thread_ready_queue.prepare(priority); | 372 | thread_ready_queue.prepare(priority); |
| 375 | 373 | ||
| @@ -385,6 +383,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, | |||
| 385 | thread->wait_objects.clear(); | 383 | thread->wait_objects.clear(); |
| 386 | thread->wait_address = 0; | 384 | thread->wait_address = 0; |
| 387 | thread->name = std::move(name); | 385 | thread->name = std::move(name); |
| 386 | thread->callback_handle = wakeup_callback_handle_table.Create(thread).MoveFrom(); | ||
| 388 | 387 | ||
| 389 | ResetThread(thread.get(), arg, 0); | 388 | ResetThread(thread.get(), arg, 0); |
| 390 | CallThread(thread.get()); | 389 | CallThread(thread.get()); |
| @@ -418,16 +417,14 @@ void Thread::SetPriority(s32 priority) { | |||
| 418 | } | 417 | } |
| 419 | } | 418 | } |
| 420 | 419 | ||
| 421 | Handle SetupIdleThread() { | 420 | SharedPtr<Thread> SetupIdleThread() { |
| 422 | // We need to pass a few valid values to get around parameter checking in Thread::Create. | 421 | // We need to pass a few valid values to get around parameter checking in Thread::Create. |
| 423 | auto thread_res = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, | 422 | auto thread = Thread::Create("idle", Memory::KERNEL_MEMORY_VADDR, THREADPRIO_LOWEST, 0, |
| 424 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE); | 423 | THREADPROCESSORID_0, 0, Kernel::DEFAULT_STACK_SIZE).MoveFrom(); |
| 425 | _dbg_assert_(Kernel, thread_res.Succeeded()); | ||
| 426 | SharedPtr<Thread> thread = std::move(*thread_res); | ||
| 427 | 424 | ||
| 428 | thread->idle = true; | 425 | thread->idle = true; |
| 429 | CallThread(thread.get()); | 426 | CallThread(thread.get()); |
| 430 | return thread->GetHandle(); | 427 | return thread; |
| 431 | } | 428 | } |
| 432 | 429 | ||
| 433 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size) { | 430 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size) { |
| @@ -460,13 +457,13 @@ void Reschedule() { | |||
| 460 | HLE::g_reschedule = false; | 457 | HLE::g_reschedule = false; |
| 461 | 458 | ||
| 462 | if (next != nullptr) { | 459 | if (next != nullptr) { |
| 463 | LOG_TRACE(Kernel, "context switch 0x%08X -> 0x%08X", prev->GetHandle(), next->GetHandle()); | 460 | LOG_TRACE(Kernel, "context switch %u -> %u", prev->GetObjectId(), next->GetObjectId()); |
| 464 | SwitchContext(next); | 461 | SwitchContext(next); |
| 465 | } else { | 462 | } else { |
| 466 | LOG_TRACE(Kernel, "cannot context switch from 0x%08X, no higher priority thread!", prev->GetHandle()); | 463 | LOG_TRACE(Kernel, "cannot context switch from %u, no higher priority thread!", prev->GetObjectId()); |
| 467 | 464 | ||
| 468 | for (auto& thread : thread_list) { | 465 | for (auto& thread : thread_list) { |
| 469 | LOG_TRACE(Kernel, "\thandle=0x%08X prio=0x%02X, status=0x%08X", thread->GetHandle(), | 466 | LOG_TRACE(Kernel, "\tid=%u prio=0x%02X, status=0x%08X", thread->GetObjectId(), |
| 470 | thread->current_priority, thread->status); | 467 | thread->current_priority, thread->status); |
| 471 | } | 468 | } |
| 472 | } | 469 | } |
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index d6299364a..633bb7c98 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h | |||
| @@ -7,6 +7,8 @@ | |||
| 7 | #include <string> | 7 | #include <string> |
| 8 | #include <vector> | 8 | #include <vector> |
| 9 | 9 | ||
| 10 | #include <boost/container/flat_set.hpp> | ||
| 11 | |||
| 10 | #include "common/common_types.h" | 12 | #include "common/common_types.h" |
| 11 | 13 | ||
| 12 | #include "core/core.h" | 14 | #include "core/core.h" |
| @@ -40,6 +42,8 @@ enum ThreadStatus { | |||
| 40 | 42 | ||
| 41 | namespace Kernel { | 43 | namespace Kernel { |
| 42 | 44 | ||
| 45 | class Mutex; | ||
| 46 | |||
| 43 | class Thread final : public WaitObject { | 47 | class Thread final : public WaitObject { |
| 44 | public: | 48 | public: |
| 45 | static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, | 49 | static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, s32 priority, |
| @@ -78,6 +82,12 @@ public: | |||
| 78 | void ResumeFromWait(); | 82 | void ResumeFromWait(); |
| 79 | 83 | ||
| 80 | /** | 84 | /** |
| 85 | * Schedules an event to wake up the specified thread after the specified delay. | ||
| 86 | * @param nanoseconds The time this thread will be allowed to sleep for. | ||
| 87 | */ | ||
| 88 | void WakeAfterDelay(s64 nanoseconds); | ||
| 89 | |||
| 90 | /** | ||
| 81 | * Sets the result after the thread awakens (from either WaitSynchronization SVC) | 91 | * Sets the result after the thread awakens (from either WaitSynchronization SVC) |
| 82 | * @param result Value to set to the returned result | 92 | * @param result Value to set to the returned result |
| 83 | */ | 93 | */ |
| @@ -103,8 +113,10 @@ public: | |||
| 103 | 113 | ||
| 104 | s32 processor_id; | 114 | s32 processor_id; |
| 105 | 115 | ||
| 106 | std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on | 116 | /// Mutexes currently held by this thread, which will be released when it exits. |
| 117 | boost::container::flat_set<SharedPtr<Mutex>> held_mutexes; | ||
| 107 | 118 | ||
| 119 | std::vector<SharedPtr<WaitObject>> wait_objects; ///< Objects that the thread is waiting on | ||
| 108 | VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address | 120 | VAddr wait_address; ///< If waiting on an AddressArbiter, this is the arbitration address |
| 109 | bool wait_all; ///< True if the thread is waiting on all objects before resuming | 121 | bool wait_all; ///< True if the thread is waiting on all objects before resuming |
| 110 | bool wait_set_output; ///< True if the output parameter should be set on thread wakeup | 122 | bool wait_set_output; ///< True if the output parameter should be set on thread wakeup |
| @@ -115,9 +127,15 @@ public: | |||
| 115 | bool idle = false; | 127 | bool idle = false; |
| 116 | 128 | ||
| 117 | private: | 129 | private: |
| 118 | Thread() = default; | 130 | Thread(); |
| 131 | ~Thread() override; | ||
| 132 | |||
| 133 | /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. | ||
| 134 | Handle callback_handle; | ||
| 119 | }; | 135 | }; |
| 120 | 136 | ||
| 137 | extern SharedPtr<Thread> g_main_thread; | ||
| 138 | |||
| 121 | /// Sets up the primary application thread | 139 | /// Sets up the primary application thread |
| 122 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size); | 140 | SharedPtr<Thread> SetupMainThread(s32 priority, u32 stack_size); |
| 123 | 141 | ||
| @@ -151,19 +169,12 @@ void WaitCurrentThread_WaitSynchronization(SharedPtr<WaitObject> wait_object, bo | |||
| 151 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); | 169 | void WaitCurrentThread_ArbitrateAddress(VAddr wait_address); |
| 152 | 170 | ||
| 153 | /** | 171 | /** |
| 154 | * Schedules an event to wake up the specified thread after the specified delay. | ||
| 155 | * @param handle The thread handle. | ||
| 156 | * @param nanoseconds The time this thread will be allowed to sleep for. | ||
| 157 | */ | ||
| 158 | void WakeThreadAfterDelay(Thread* thread, s64 nanoseconds); | ||
| 159 | |||
| 160 | /** | ||
| 161 | * Sets up the idle thread, this is a thread that is intended to never execute instructions, | 172 | * Sets up the idle thread, this is a thread that is intended to never execute instructions, |
| 162 | * only to advance the timing. It is scheduled when there are no other ready threads in the thread queue | 173 | * only to advance the timing. It is scheduled when there are no other ready threads in the thread queue |
| 163 | * and will try to yield on every call. | 174 | * and will try to yield on every call. |
| 164 | * @returns The handle of the idle thread | 175 | * @returns The handle of the idle thread |
| 165 | */ | 176 | */ |
| 166 | Handle SetupIdleThread(); | 177 | SharedPtr<Thread> SetupIdleThread(); |
| 167 | 178 | ||
| 168 | /// Initialize threading | 179 | /// Initialize threading |
| 169 | void ThreadingInit(); | 180 | void ThreadingInit(); |
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 503a5d2ce..4352fc99c 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -2,8 +2,6 @@ | |||
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include <set> | ||
| 6 | |||
| 7 | #include "common/common.h" | 5 | #include "common/common.h" |
| 8 | 6 | ||
| 9 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| @@ -15,18 +13,24 @@ namespace Kernel { | |||
| 15 | 13 | ||
| 16 | /// The event type of the generic timer callback event | 14 | /// The event type of the generic timer callback event |
| 17 | static int timer_callback_event_type = -1; | 15 | static int timer_callback_event_type = -1; |
| 16 | // TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing | ||
| 17 | // us to simply use a pool index or similar. | ||
| 18 | static Kernel::HandleTable timer_callback_handle_table; | ||
| 19 | |||
| 20 | Timer::Timer() {} | ||
| 21 | Timer::~Timer() {} | ||
| 18 | 22 | ||
| 19 | ResultVal<SharedPtr<Timer>> Timer::Create(ResetType reset_type, std::string name) { | 23 | SharedPtr<Timer> Timer::Create(ResetType reset_type, std::string name) { |
| 20 | SharedPtr<Timer> timer(new Timer); | 24 | SharedPtr<Timer> timer(new Timer); |
| 21 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 22 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(timer)); | ||
| 23 | 25 | ||
| 24 | timer->reset_type = reset_type; | 26 | timer->reset_type = reset_type; |
| 25 | timer->signaled = false; | 27 | timer->signaled = false; |
| 26 | timer->name = std::move(name); | 28 | timer->name = std::move(name); |
| 27 | timer->initial_delay = 0; | 29 | timer->initial_delay = 0; |
| 28 | timer->interval_delay = 0; | 30 | timer->interval_delay = 0; |
| 29 | return MakeResult<SharedPtr<Timer>>(timer); | 31 | timer->callback_handle = timer_callback_handle_table.Create(timer).MoveFrom(); |
| 32 | |||
| 33 | return timer; | ||
| 30 | } | 34 | } |
| 31 | 35 | ||
| 32 | bool Timer::ShouldWait() { | 36 | bool Timer::ShouldWait() { |
| @@ -38,17 +42,19 @@ void Timer::Acquire() { | |||
| 38 | } | 42 | } |
| 39 | 43 | ||
| 40 | void Timer::Set(s64 initial, s64 interval) { | 44 | void Timer::Set(s64 initial, s64 interval) { |
| 45 | // Ensure we get rid of any previous scheduled event | ||
| 46 | Cancel(); | ||
| 47 | |||
| 41 | initial_delay = initial; | 48 | initial_delay = initial; |
| 42 | interval_delay = interval; | 49 | interval_delay = interval; |
| 43 | 50 | ||
| 44 | u64 initial_microseconds = initial / 1000; | 51 | u64 initial_microseconds = initial / 1000; |
| 45 | // TODO(yuriks): Figure out a replacement for GetHandle here | 52 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), |
| 46 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | 53 | timer_callback_event_type, callback_handle); |
| 47 | GetHandle()); | ||
| 48 | } | 54 | } |
| 49 | 55 | ||
| 50 | void Timer::Cancel() { | 56 | void Timer::Cancel() { |
| 51 | CoreTiming::UnscheduleEvent(timer_callback_event_type, GetHandle()); | 57 | CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_handle); |
| 52 | } | 58 | } |
| 53 | 59 | ||
| 54 | void Timer::Clear() { | 60 | void Timer::Clear() { |
| @@ -57,7 +63,7 @@ void Timer::Clear() { | |||
| 57 | 63 | ||
| 58 | /// The timer callback event, called when a timer is fired | 64 | /// The timer callback event, called when a timer is fired |
| 59 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 65 | static void TimerCallback(u64 timer_handle, int cycles_late) { |
| 60 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle); | 66 | SharedPtr<Timer> timer = timer_callback_handle_table.Get<Timer>(timer_handle); |
| 61 | 67 | ||
| 62 | if (timer == nullptr) { | 68 | if (timer == nullptr) { |
| 63 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08X", timer_handle); | 69 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08X", timer_handle); |
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index c45e79954..540e4e187 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h | |||
| @@ -19,7 +19,7 @@ public: | |||
| 19 | * @param name Optional name of timer | 19 | * @param name Optional name of timer |
| 20 | * @return The created Timer | 20 | * @return The created Timer |
| 21 | */ | 21 | */ |
| 22 | static ResultVal<SharedPtr<Timer>> Create(ResetType reset_type, std::string name = "Unknown"); | 22 | static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown"); |
| 23 | 23 | ||
| 24 | std::string GetTypeName() const override { return "Timer"; } | 24 | std::string GetTypeName() const override { return "Timer"; } |
| 25 | std::string GetName() const override { return name; } | 25 | std::string GetName() const override { return name; } |
| @@ -49,7 +49,11 @@ public: | |||
| 49 | void Clear(); | 49 | void Clear(); |
| 50 | 50 | ||
| 51 | private: | 51 | private: |
| 52 | Timer() = default; | 52 | Timer(); |
| 53 | ~Timer() override; | ||
| 54 | |||
| 55 | /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. | ||
| 56 | Handle callback_handle; | ||
| 53 | }; | 57 | }; |
| 54 | 58 | ||
| 55 | /// Initializes the required variables for timers | 59 | /// Initializes the required variables for timers |
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index 20a3fa2e5..53d920de1 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp | |||
| @@ -53,7 +53,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 53 | // Interface class | 53 | // Interface class |
| 54 | 54 | ||
| 55 | Interface::Interface() { | 55 | Interface::Interface() { |
| 56 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 56 | Register(FunctionTable); |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | } // namespace | 59 | } // namespace |
diff --git a/src/core/hle/service/act_u.cpp b/src/core/hle/service/act_u.cpp index 10870f14b..4ea7a9fb2 100644 --- a/src/core/hle/service/act_u.cpp +++ b/src/core/hle/service/act_u.cpp | |||
| @@ -18,7 +18,7 @@ namespace ACT_U { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/am_app.cpp b/src/core/hle/service/am_app.cpp index 0b396b6d3..df10db87f 100644 --- a/src/core/hle/service/am_app.cpp +++ b/src/core/hle/service/am_app.cpp | |||
| @@ -18,7 +18,7 @@ namespace AM_APP { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am_net.cpp index 112844e5b..c74012d9d 100644 --- a/src/core/hle/service/am_net.cpp +++ b/src/core/hle/service/am_net.cpp | |||
| @@ -38,7 +38,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 38 | // Interface class | 38 | // Interface class |
| 39 | 39 | ||
| 40 | Interface::Interface() { | 40 | Interface::Interface() { |
| 41 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 41 | Register(FunctionTable); |
| 42 | } | 42 | } |
| 43 | 43 | ||
| 44 | } // namespace | 44 | } // namespace |
diff --git a/src/core/hle/service/am_sys.cpp b/src/core/hle/service/am_sys.cpp index b63c8c087..c5df8abda 100644 --- a/src/core/hle/service/am_sys.cpp +++ b/src/core/hle/service/am_sys.cpp | |||
| @@ -18,7 +18,7 @@ namespace AM_SYS { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/apt_a.cpp b/src/core/hle/service/apt_a.cpp index 42f2879c1..e1dd2a5fb 100644 --- a/src/core/hle/service/apt_a.cpp +++ b/src/core/hle/service/apt_a.cpp | |||
| @@ -39,7 +39,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 39 | // Interface class | 39 | // Interface class |
| 40 | 40 | ||
| 41 | Interface::Interface() { | 41 | Interface::Interface() { |
| 42 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 42 | Register(FunctionTable); |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | } // namespace | 45 | } // namespace |
diff --git a/src/core/hle/service/apt_s.cpp b/src/core/hle/service/apt_s.cpp index 7ad428ee7..686335428 100644 --- a/src/core/hle/service/apt_s.cpp +++ b/src/core/hle/service/apt_s.cpp | |||
| @@ -117,7 +117,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 117 | // Interface class | 117 | // Interface class |
| 118 | 118 | ||
| 119 | Interface::Interface() { | 119 | Interface::Interface() { |
| 120 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 120 | Register(FunctionTable); |
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | } // namespace | 123 | } // namespace |
diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index 4c3f621d0..ccfd04591 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp | |||
| @@ -69,8 +69,8 @@ void Initialize(Service::Interface* self) { | |||
| 69 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 69 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 70 | 70 | ||
| 71 | // TODO(bunnei): Check if these are created in Initialize or on APT process startup. | 71 | // TODO(bunnei): Check if these are created in Initialize or on APT process startup. |
| 72 | notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification").MoveFrom(); | 72 | notification_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Notification"); |
| 73 | pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause").MoveFrom(); | 73 | pause_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "APT_U:Pause"); |
| 74 | 74 | ||
| 75 | cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom(); | 75 | cmd_buff[3] = Kernel::g_handle_table.Create(notification_event).MoveFrom(); |
| 76 | cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom(); | 76 | cmd_buff[4] = Kernel::g_handle_table.Create(pause_event).MoveFrom(); |
| @@ -512,15 +512,15 @@ Interface::Interface() { | |||
| 512 | file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); | 512 | file.ReadBytes(shared_font.data(), (size_t)file.GetSize()); |
| 513 | 513 | ||
| 514 | // Create shared font memory object | 514 | // Create shared font memory object |
| 515 | shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem").MoveFrom(); | 515 | shared_font_mem = Kernel::SharedMemory::Create("APT_U:shared_font_mem"); |
| 516 | } else { | 516 | } else { |
| 517 | LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); | 517 | LOG_WARNING(Service_APT, "Unable to load shared font: %s", filepath.c_str()); |
| 518 | shared_font_mem = nullptr; | 518 | shared_font_mem = nullptr; |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | lock = Kernel::Mutex::Create(false, "APT_U:Lock").MoveFrom(); | 521 | lock = Kernel::Mutex::Create(false, "APT_U:Lock"); |
| 522 | 522 | ||
| 523 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 523 | Register(FunctionTable); |
| 524 | } | 524 | } |
| 525 | 525 | ||
| 526 | } // namespace | 526 | } // namespace |
diff --git a/src/core/hle/service/boss_p.cpp b/src/core/hle/service/boss_p.cpp index f245a38e9..b3aa6acee 100644 --- a/src/core/hle/service/boss_p.cpp +++ b/src/core/hle/service/boss_p.cpp | |||
| @@ -18,7 +18,7 @@ namespace BOSS_P { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp index 1820ea7ad..50bb5d426 100644 --- a/src/core/hle/service/boss_u.cpp +++ b/src/core/hle/service/boss_u.cpp | |||
| @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 19 | // Interface class | 19 | // Interface class |
| 20 | 20 | ||
| 21 | Interface::Interface() { | 21 | Interface::Interface() { |
| 22 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 22 | Register(FunctionTable); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | } // namespace | 25 | } // namespace |
diff --git a/src/core/hle/service/cam_u.cpp b/src/core/hle/service/cam_u.cpp index 549095339..cf3b27664 100644 --- a/src/core/hle/service/cam_u.cpp +++ b/src/core/hle/service/cam_u.cpp | |||
| @@ -18,7 +18,7 @@ namespace CAM_U { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/cecd_s.cpp b/src/core/hle/service/cecd_s.cpp index 9c4992f13..2c707baff 100644 --- a/src/core/hle/service/cecd_s.cpp +++ b/src/core/hle/service/cecd_s.cpp | |||
| @@ -18,7 +18,7 @@ namespace CECD_S { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/cecd_u.cpp b/src/core/hle/service/cecd_u.cpp index b7655ef0b..b7ea3a186 100644 --- a/src/core/hle/service/cecd_u.cpp +++ b/src/core/hle/service/cecd_u.cpp | |||
| @@ -18,7 +18,7 @@ namespace CECD_U { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/cfg/cfg_i.cpp b/src/core/hle/service/cfg/cfg_i.cpp index 7c1ee8ac3..555b7884a 100644 --- a/src/core/hle/service/cfg/cfg_i.cpp +++ b/src/core/hle/service/cfg/cfg_i.cpp | |||
| @@ -104,7 +104,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 104 | // Interface class | 104 | // Interface class |
| 105 | 105 | ||
| 106 | Interface::Interface() { | 106 | Interface::Interface() { |
| 107 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 107 | Register(FunctionTable); |
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | } // namespace | 110 | } // namespace |
diff --git a/src/core/hle/service/cfg/cfg_s.cpp b/src/core/hle/service/cfg/cfg_s.cpp index cf4e82152..2170894d6 100644 --- a/src/core/hle/service/cfg/cfg_s.cpp +++ b/src/core/hle/service/cfg/cfg_s.cpp | |||
| @@ -92,7 +92,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 92 | // Interface class | 92 | // Interface class |
| 93 | 93 | ||
| 94 | Interface::Interface() { | 94 | Interface::Interface() { |
| 95 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 95 | Register(FunctionTable); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | } // namespace | 98 | } // namespace |
diff --git a/src/core/hle/service/cfg/cfg_u.cpp b/src/core/hle/service/cfg/cfg_u.cpp index 835620909..1da9f59f6 100644 --- a/src/core/hle/service/cfg/cfg_u.cpp +++ b/src/core/hle/service/cfg/cfg_u.cpp | |||
| @@ -186,7 +186,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 186 | // Interface class | 186 | // Interface class |
| 187 | 187 | ||
| 188 | Interface::Interface() { | 188 | Interface::Interface() { |
| 189 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 189 | Register(FunctionTable); |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | } // namespace | 192 | } // namespace |
diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp index 3a557efe1..39b00982c 100644 --- a/src/core/hle/service/csnd_snd.cpp +++ b/src/core/hle/service/csnd_snd.cpp | |||
| @@ -29,7 +29,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 29 | // Interface class | 29 | // Interface class |
| 30 | 30 | ||
| 31 | Interface::Interface() { | 31 | Interface::Interface() { |
| 32 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 32 | Register(FunctionTable); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | } // namespace | 35 | } // namespace |
diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 9a38be393..0f86894a6 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp | |||
| @@ -201,12 +201,11 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 201 | // Interface class | 201 | // Interface class |
| 202 | 202 | ||
| 203 | Interface::Interface() { | 203 | Interface::Interface() { |
| 204 | semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, | 204 | semaphore_event = Kernel::Event::Create(RESETTYPE_ONESHOT, "DSP_DSP::semaphore_event"); |
| 205 | "DSP_DSP::semaphore_event").MoveFrom(); | ||
| 206 | interrupt_event = nullptr; | 205 | interrupt_event = nullptr; |
| 207 | read_pipe_count = 0; | 206 | read_pipe_count = 0; |
| 208 | 207 | ||
| 209 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 208 | Register(FunctionTable); |
| 210 | } | 209 | } |
| 211 | 210 | ||
| 212 | } // namespace | 211 | } // namespace |
diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 8c900eabc..962de2170 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp | |||
| @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 19 | // Interface class | 19 | // Interface class |
| 20 | 20 | ||
| 21 | Interface::Interface() { | 21 | Interface::Interface() { |
| 22 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 22 | Register(FunctionTable); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | } // namespace | 25 | } // namespace |
diff --git a/src/core/hle/service/frd_a.cpp b/src/core/hle/service/frd_a.cpp index 53edc2cd8..79140a756 100644 --- a/src/core/hle/service/frd_a.cpp +++ b/src/core/hle/service/frd_a.cpp | |||
| @@ -18,7 +18,7 @@ namespace FRD_A { | |||
| 18 | // Interface class | 18 | // Interface class |
| 19 | 19 | ||
| 20 | Interface::Interface() { | 20 | Interface::Interface() { |
| 21 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 21 | //Register(FunctionTable); |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | } // namespace | 24 | } // namespace |
diff --git a/src/core/hle/service/frd_u.cpp b/src/core/hle/service/frd_u.cpp index 021186e57..59faca77a 100644 --- a/src/core/hle/service/frd_u.cpp +++ b/src/core/hle/service/frd_u.cpp | |||
| @@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 27 | // Interface class | 27 | // Interface class |
| 28 | 28 | ||
| 29 | Interface::Interface() { | 29 | Interface::Interface() { |
| 30 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 30 | Register(FunctionTable); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | } // namespace | 33 | } // namespace |
diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index 43eef034e..ccf132f31 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp | |||
| @@ -163,7 +163,7 @@ public: | |||
| 163 | case FileCommand::OpenLinkFile: | 163 | case FileCommand::OpenLinkFile: |
| 164 | { | 164 | { |
| 165 | LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); | 165 | LOG_WARNING(Service_FS, "(STUBBED) File command OpenLinkFile %s", GetName().c_str()); |
| 166 | cmd_buff[3] = GetHandle(); | 166 | cmd_buff[3] = Kernel::g_handle_table.Create(this).ValueOr(INVALID_HANDLE); |
| 167 | break; | 167 | break; |
| 168 | } | 168 | } |
| 169 | 169 | ||
| @@ -303,7 +303,8 @@ ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, Arc | |||
| 303 | return RESULT_SUCCESS; | 303 | return RESULT_SUCCESS; |
| 304 | } | 304 | } |
| 305 | 305 | ||
| 306 | ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode) { | 306 | ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenFileFromArchive(ArchiveHandle archive_handle, |
| 307 | const FileSys::Path& path, const FileSys::Mode mode) { | ||
| 307 | Archive* archive = GetArchive(archive_handle); | 308 | Archive* archive = GetArchive(archive_handle); |
| 308 | if (archive == nullptr) | 309 | if (archive == nullptr) |
| 309 | return ERR_INVALID_HANDLE; | 310 | return ERR_INVALID_HANDLE; |
| @@ -314,10 +315,8 @@ ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSy | |||
| 314 | ErrorSummary::NotFound, ErrorLevel::Status); | 315 | ErrorSummary::NotFound, ErrorLevel::Status); |
| 315 | } | 316 | } |
| 316 | 317 | ||
| 317 | auto file = Common::make_unique<File>(std::move(backend), path); | 318 | auto file = Kernel::SharedPtr<File>(new File(std::move(backend), path)); |
| 318 | // TOOD(yuriks): Fix error reporting | 319 | return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(file)); |
| 319 | Handle handle = Kernel::g_handle_table.Create(file.release()).ValueOr(INVALID_HANDLE); | ||
| 320 | return MakeResult<Handle>(handle); | ||
| 321 | } | 320 | } |
| 322 | 321 | ||
| 323 | ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | 322 | ResultCode DeleteFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { |
| @@ -403,13 +402,8 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons | |||
| 403 | ErrorSummary::NothingHappened, ErrorLevel::Status); | 402 | ErrorSummary::NothingHappened, ErrorLevel::Status); |
| 404 | } | 403 | } |
| 405 | 404 | ||
| 406 | /** | 405 | ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, |
| 407 | * Open a Directory from an Archive | 406 | const FileSys::Path& path) { |
| 408 | * @param archive_handle Handle to an open Archive object | ||
| 409 | * @param path Path to the Directory inside of the Archive | ||
| 410 | * @return Opened Directory object | ||
| 411 | */ | ||
| 412 | ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path) { | ||
| 413 | Archive* archive = GetArchive(archive_handle); | 407 | Archive* archive = GetArchive(archive_handle); |
| 414 | if (archive == nullptr) | 408 | if (archive == nullptr) |
| 415 | return ERR_INVALID_HANDLE; | 409 | return ERR_INVALID_HANDLE; |
| @@ -420,10 +414,8 @@ ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const F | |||
| 420 | ErrorSummary::NotFound, ErrorLevel::Permanent); | 414 | ErrorSummary::NotFound, ErrorLevel::Permanent); |
| 421 | } | 415 | } |
| 422 | 416 | ||
| 423 | auto directory = Common::make_unique<Directory>(std::move(backend), path); | 417 | auto directory = Kernel::SharedPtr<Directory>(new Directory(std::move(backend), path)); |
| 424 | // TOOD(yuriks): Fix error reporting | 418 | return MakeResult<Kernel::SharedPtr<Kernel::Session>>(std::move(directory)); |
| 425 | Handle handle = Kernel::g_handle_table.Create(directory.release()).ValueOr(INVALID_HANDLE); | ||
| 426 | return MakeResult<Handle>(handle); | ||
| 427 | } | 419 | } |
| 428 | 420 | ||
| 429 | ResultCode FormatSaveData() { | 421 | ResultCode FormatSaveData() { |
diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index ba674d7f6..ab5ea4da8 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h | |||
| @@ -15,6 +15,10 @@ extern const std::string SYSTEM_ID; | |||
| 15 | /// The scrambled SD card CID, also known as ID1 | 15 | /// The scrambled SD card CID, also known as ID1 |
| 16 | extern const std::string SDCARD_ID; | 16 | extern const std::string SDCARD_ID; |
| 17 | 17 | ||
| 18 | namespace Kernel { | ||
| 19 | class Session; | ||
| 20 | } | ||
| 21 | |||
| 18 | namespace Service { | 22 | namespace Service { |
| 19 | namespace FS { | 23 | namespace FS { |
| 20 | 24 | ||
| @@ -58,9 +62,10 @@ ResultCode CreateArchive(std::unique_ptr<FileSys::ArchiveBackend>&& backend, Arc | |||
| 58 | * @param archive_handle Handle to an open Archive object | 62 | * @param archive_handle Handle to an open Archive object |
| 59 | * @param path Path to the File inside of the Archive | 63 | * @param path Path to the File inside of the Archive |
| 60 | * @param mode Mode under which to open the File | 64 | * @param mode Mode under which to open the File |
| 61 | * @return Handle to the opened File object | 65 | * @return The opened File object as a Session |
| 62 | */ | 66 | */ |
| 63 | ResultVal<Handle> OpenFileFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path, const FileSys::Mode mode); | 67 | ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenFileFromArchive(ArchiveHandle archive_handle, |
| 68 | const FileSys::Path& path, const FileSys::Mode mode); | ||
| 64 | 69 | ||
| 65 | /** | 70 | /** |
| 66 | * Delete a File from an Archive | 71 | * Delete a File from an Archive |
| @@ -121,9 +126,10 @@ ResultCode RenameDirectoryBetweenArchives(ArchiveHandle src_archive_handle, cons | |||
| 121 | * Open a Directory from an Archive | 126 | * Open a Directory from an Archive |
| 122 | * @param archive_handle Handle to an open Archive object | 127 | * @param archive_handle Handle to an open Archive object |
| 123 | * @param path Path to the Directory inside of the Archive | 128 | * @param path Path to the Directory inside of the Archive |
| 124 | * @return Handle to the opened File object | 129 | * @return The opened Directory object as a Session |
| 125 | */ | 130 | */ |
| 126 | ResultVal<Handle> OpenDirectoryFromArchive(ArchiveHandle archive_handle, const FileSys::Path& path); | 131 | ResultVal<Kernel::SharedPtr<Kernel::Session>> OpenDirectoryFromArchive(ArchiveHandle archive_handle, |
| 132 | const FileSys::Path& path); | ||
| 127 | 133 | ||
| 128 | /** | 134 | /** |
| 129 | * Creates a blank SaveData archive. | 135 | * Creates a blank SaveData archive. |
diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index c495b6f3c..94a3a31c8 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp | |||
| @@ -14,6 +14,9 @@ | |||
| 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 14 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 15 | // Namespace FS_User | 15 | // Namespace FS_User |
| 16 | 16 | ||
| 17 | using Kernel::SharedPtr; | ||
| 18 | using Kernel::Session; | ||
| 19 | |||
| 17 | namespace Service { | 20 | namespace Service { |
| 18 | namespace FS { | 21 | namespace FS { |
| 19 | 22 | ||
| @@ -58,10 +61,10 @@ static void OpenFile(Service::Interface* self) { | |||
| 58 | 61 | ||
| 59 | LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); | 62 | LOG_DEBUG(Service_FS, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); |
| 60 | 63 | ||
| 61 | ResultVal<Handle> handle = OpenFileFromArchive(archive_handle, file_path, mode); | 64 | ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(archive_handle, file_path, mode); |
| 62 | cmd_buff[1] = handle.Code().raw; | 65 | cmd_buff[1] = file_res.Code().raw; |
| 63 | if (handle.Succeeded()) { | 66 | if (file_res.Succeeded()) { |
| 64 | cmd_buff[3] = *handle; | 67 | cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); |
| 65 | } else { | 68 | } else { |
| 66 | cmd_buff[3] = 0; | 69 | cmd_buff[3] = 0; |
| 67 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); | 70 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); |
| @@ -114,10 +117,10 @@ static void OpenFileDirectly(Service::Interface* self) { | |||
| 114 | } | 117 | } |
| 115 | SCOPE_EXIT({ CloseArchive(*archive_handle); }); | 118 | SCOPE_EXIT({ CloseArchive(*archive_handle); }); |
| 116 | 119 | ||
| 117 | ResultVal<Handle> handle = OpenFileFromArchive(*archive_handle, file_path, mode); | 120 | ResultVal<SharedPtr<Session>> file_res = OpenFileFromArchive(*archive_handle, file_path, mode); |
| 118 | cmd_buff[1] = handle.Code().raw; | 121 | cmd_buff[1] = file_res.Code().raw; |
| 119 | if (handle.Succeeded()) { | 122 | if (file_res.Succeeded()) { |
| 120 | cmd_buff[3] = *handle; | 123 | cmd_buff[3] = Kernel::g_handle_table.Create(*file_res).MoveFrom(); |
| 121 | } else { | 124 | } else { |
| 122 | cmd_buff[3] = 0; | 125 | cmd_buff[3] = 0; |
| 123 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); | 126 | LOG_ERROR(Service_FS, "failed to get a handle for file %s", file_path.DebugStr().c_str()); |
| @@ -334,10 +337,10 @@ static void OpenDirectory(Service::Interface* self) { | |||
| 334 | 337 | ||
| 335 | LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); | 338 | LOG_DEBUG(Service_FS, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); |
| 336 | 339 | ||
| 337 | ResultVal<Handle> handle = OpenDirectoryFromArchive(archive_handle, dir_path); | 340 | ResultVal<SharedPtr<Session>> dir_res = OpenDirectoryFromArchive(archive_handle, dir_path); |
| 338 | cmd_buff[1] = handle.Code().raw; | 341 | cmd_buff[1] = dir_res.Code().raw; |
| 339 | if (handle.Succeeded()) { | 342 | if (dir_res.Succeeded()) { |
| 340 | cmd_buff[3] = *handle; | 343 | cmd_buff[3] = Kernel::g_handle_table.Create(*dir_res).MoveFrom(); |
| 341 | } else { | 344 | } else { |
| 342 | LOG_ERROR(Service_FS, "failed to get a handle for directory"); | 345 | LOG_ERROR(Service_FS, "failed to get a handle for directory"); |
| 343 | } | 346 | } |
| @@ -588,7 +591,7 @@ const FSUserInterface::FunctionInfo FunctionTable[] = { | |||
| 588 | // Interface class | 591 | // Interface class |
| 589 | 592 | ||
| 590 | FSUserInterface::FSUserInterface() { | 593 | FSUserInterface::FSUserInterface() { |
| 591 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 594 | Register(FunctionTable); |
| 592 | } | 595 | } |
| 593 | 596 | ||
| 594 | } // namespace FS | 597 | } // namespace FS |
diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 5b91f17d2..495c117ee 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp | |||
| @@ -187,7 +187,7 @@ static void RegisterInterruptRelayQueue(Service::Interface* self) { | |||
| 187 | 187 | ||
| 188 | g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); | 188 | g_interrupt_event = Kernel::g_handle_table.Get<Kernel::Event>(cmd_buff[3]); |
| 189 | _assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!"); | 189 | _assert_msg_(GSP, (g_interrupt_event != nullptr), "handle is not valid!"); |
| 190 | g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem").MoveFrom(); | 190 | g_shared_memory = Kernel::SharedMemory::Create("GSPSharedMem"); |
| 191 | 191 | ||
| 192 | Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); | 192 | Handle shmem_handle = Kernel::g_handle_table.Create(g_shared_memory).MoveFrom(); |
| 193 | 193 | ||
| @@ -389,7 +389,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 389 | // Interface class | 389 | // Interface class |
| 390 | 390 | ||
| 391 | Interface::Interface() { | 391 | Interface::Interface() { |
| 392 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 392 | Register(FunctionTable); |
| 393 | 393 | ||
| 394 | g_interrupt_event = 0; | 394 | g_interrupt_event = 0; |
| 395 | g_shared_memory = 0; | 395 | g_shared_memory = 0; |
diff --git a/src/core/hle/service/gsp_lcd.cpp b/src/core/hle/service/gsp_lcd.cpp index 6213472ff..d63fa1ee2 100644 --- a/src/core/hle/service/gsp_lcd.cpp +++ b/src/core/hle/service/gsp_lcd.cpp | |||
| @@ -20,7 +20,7 @@ namespace GSP_LCD { | |||
| 20 | // Interface class | 20 | // Interface class |
| 21 | 21 | ||
| 22 | Interface::Interface() { | 22 | Interface::Interface() { |
| 23 | //Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 23 | //Register(FunctionTable); |
| 24 | } | 24 | } |
| 25 | 25 | ||
| 26 | } // namespace | 26 | } // namespace |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 835055af4..7cb01729e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -30,6 +30,8 @@ static s16 next_circle_y = 0; | |||
| 30 | * Gets a pointer to the PadData structure inside HID shared memory | 30 | * Gets a pointer to the PadData structure inside HID shared memory |
| 31 | */ | 31 | */ |
| 32 | static inline PadData* GetPadData() { | 32 | static inline PadData* GetPadData() { |
| 33 | if (g_shared_mem == nullptr) | ||
| 34 | return nullptr; | ||
| 33 | return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr)); | 35 | return reinterpret_cast<PadData*>(g_shared_mem->GetPointer().ValueOr(nullptr)); |
| 34 | } | 36 | } |
| 35 | 37 | ||
| @@ -122,14 +124,14 @@ void PadUpdateComplete() { | |||
| 122 | void HIDInit() { | 124 | void HIDInit() { |
| 123 | using namespace Kernel; | 125 | using namespace Kernel; |
| 124 | 126 | ||
| 125 | g_shared_mem = SharedMemory::Create("HID:SharedMem").MoveFrom(); | 127 | g_shared_mem = SharedMemory::Create("HID:SharedMem"); |
| 126 | 128 | ||
| 127 | // Create event handles | 129 | // Create event handles |
| 128 | g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1").MoveFrom(); | 130 | g_event_pad_or_touch_1 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch1"); |
| 129 | g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2").MoveFrom(); | 131 | g_event_pad_or_touch_2 = Event::Create(RESETTYPE_ONESHOT, "HID:EventPadOrTouch2"); |
| 130 | g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer").MoveFrom(); | 132 | g_event_accelerometer = Event::Create(RESETTYPE_ONESHOT, "HID:EventAccelerometer"); |
| 131 | g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope").MoveFrom(); | 133 | g_event_gyroscope = Event::Create(RESETTYPE_ONESHOT, "HID:EventGyroscope"); |
| 132 | g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad").MoveFrom(); | 134 | g_event_debug_pad = Event::Create(RESETTYPE_ONESHOT, "HID:EventDebugPad"); |
| 133 | } | 135 | } |
| 134 | 136 | ||
| 135 | void HIDShutdown() { | 137 | void HIDShutdown() { |
diff --git a/src/core/hle/service/hid/hid_spvr.cpp b/src/core/hle/service/hid/hid_spvr.cpp index 76c40b659..054aa8b59 100644 --- a/src/core/hle/service/hid/hid_spvr.cpp +++ b/src/core/hle/service/hid/hid_spvr.cpp | |||
| @@ -32,7 +32,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 32 | // Interface class | 32 | // Interface class |
| 33 | 33 | ||
| 34 | Interface::Interface() { | 34 | Interface::Interface() { |
| 35 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 35 | Register(FunctionTable); |
| 36 | } | 36 | } |
| 37 | 37 | ||
| 38 | } // namespace | 38 | } // namespace |
diff --git a/src/core/hle/service/hid/hid_user.cpp b/src/core/hle/service/hid/hid_user.cpp index 5444aa5ee..68edafebb 100644 --- a/src/core/hle/service/hid/hid_user.cpp +++ b/src/core/hle/service/hid/hid_user.cpp | |||
| @@ -72,7 +72,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 72 | // Interface class | 72 | // Interface class |
| 73 | 73 | ||
| 74 | Interface::Interface() { | 74 | Interface::Interface() { |
| 75 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 75 | Register(FunctionTable); |
| 76 | } | 76 | } |
| 77 | 77 | ||
| 78 | } // namespace | 78 | } // namespace |
diff --git a/src/core/hle/service/http_c.cpp b/src/core/hle/service/http_c.cpp index d0bff552f..6595ca572 100644 --- a/src/core/hle/service/http_c.cpp +++ b/src/core/hle/service/http_c.cpp | |||
| @@ -58,7 +58,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 58 | // Interface class | 58 | // Interface class |
| 59 | 59 | ||
| 60 | Interface::Interface() { | 60 | Interface::Interface() { |
| 61 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 61 | Register(FunctionTable); |
| 62 | } | 62 | } |
| 63 | 63 | ||
| 64 | } // namespace | 64 | } // namespace |
diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp index d49bd5335..31da8e160 100644 --- a/src/core/hle/service/ir_rst.cpp +++ b/src/core/hle/service/ir_rst.cpp | |||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 22 | // Interface class | 22 | // Interface class |
| 23 | 23 | ||
| 24 | Interface::Interface() { | 24 | Interface::Interface() { |
| 25 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 25 | Register(FunctionTable); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | } // namespace | 28 | } // namespace |
diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir_u.cpp index da6f38e41..7fa233048 100644 --- a/src/core/hle/service/ir_u.cpp +++ b/src/core/hle/service/ir_u.cpp | |||
| @@ -36,7 +36,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 36 | // Interface class | 36 | // Interface class |
| 37 | 37 | ||
| 38 | Interface::Interface() { | 38 | Interface::Interface() { |
| 39 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 39 | Register(FunctionTable); |
| 40 | } | 40 | } |
| 41 | 41 | ||
| 42 | } // namespace | 42 | } // namespace |
diff --git a/src/core/hle/service/ldr_ro.cpp b/src/core/hle/service/ldr_ro.cpp index 7d6e2e8e8..459717fff 100644 --- a/src/core/hle/service/ldr_ro.cpp +++ b/src/core/hle/service/ldr_ro.cpp | |||
| @@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 27 | // Interface class | 27 | // Interface class |
| 28 | 28 | ||
| 29 | Interface::Interface() { | 29 | Interface::Interface() { |
| 30 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 30 | Register(FunctionTable); |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | } // namespace | 33 | } // namespace |
diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 82bce9180..af967b5b6 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp | |||
| @@ -34,7 +34,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 34 | // Interface class | 34 | // Interface class |
| 35 | 35 | ||
| 36 | Interface::Interface() { | 36 | Interface::Interface() { |
| 37 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 37 | Register(FunctionTable); |
| 38 | } | 38 | } |
| 39 | 39 | ||
| 40 | } // namespace | 40 | } // namespace |
diff --git a/src/core/hle/service/ndm_u.cpp b/src/core/hle/service/ndm_u.cpp index 0f03de6ae..df3c97193 100644 --- a/src/core/hle/service/ndm_u.cpp +++ b/src/core/hle/service/ndm_u.cpp | |||
| @@ -24,7 +24,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 24 | // Interface class | 24 | // Interface class |
| 25 | 25 | ||
| 26 | Interface::Interface() { | 26 | Interface::Interface() { |
| 27 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 27 | Register(FunctionTable); |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | } // namespace | 30 | } // namespace |
diff --git a/src/core/hle/service/news_s.cpp b/src/core/hle/service/news_s.cpp index 1850f59bd..d7537875b 100644 --- a/src/core/hle/service/news_s.cpp +++ b/src/core/hle/service/news_s.cpp | |||
| @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 19 | // Interface class | 19 | // Interface class |
| 20 | 20 | ||
| 21 | Interface::Interface() { | 21 | Interface::Interface() { |
| 22 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 22 | Register(FunctionTable); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | } // namespace | 25 | } // namespace |
diff --git a/src/core/hle/service/news_u.cpp b/src/core/hle/service/news_u.cpp index b5adad4c6..a9e161c23 100644 --- a/src/core/hle/service/news_u.cpp +++ b/src/core/hle/service/news_u.cpp | |||
| @@ -19,7 +19,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 19 | // Interface class | 19 | // Interface class |
| 20 | 20 | ||
| 21 | Interface::Interface() { | 21 | Interface::Interface() { |
| 22 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 22 | Register(FunctionTable); |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | } // namespace | 25 | } // namespace |
diff --git a/src/core/hle/service/nim_aoc.cpp b/src/core/hle/service/nim_aoc.cpp index 17d1c4ff5..ab2ef4429 100644 --- a/src/core/hle/service/nim_aoc.cpp +++ b/src/core/hle/service/nim_aoc.cpp | |||
| @@ -25,7 +25,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 25 | // Interface class | 25 | // Interface class |
| 26 | 26 | ||
| 27 | Interface::Interface() { | 27 | Interface::Interface() { |
| 28 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 28 | Register(FunctionTable); |
| 29 | } | 29 | } |
| 30 | 30 | ||
| 31 | } // namespace | 31 | } // namespace |
diff --git a/src/core/hle/service/ns_s.cpp b/src/core/hle/service/ns_s.cpp index b9aca4257..5cf3e2039 100644 --- a/src/core/hle/service/ns_s.cpp +++ b/src/core/hle/service/ns_s.cpp | |||
| @@ -21,7 +21,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 21 | // Interface class | 21 | // Interface class |
| 22 | 22 | ||
| 23 | Interface::Interface() { | 23 | Interface::Interface() { |
| 24 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 24 | Register(FunctionTable); |
| 25 | } | 25 | } |
| 26 | 26 | ||
| 27 | } // namespace | 27 | } // namespace |
diff --git a/src/core/hle/service/nwm_uds.cpp b/src/core/hle/service/nwm_uds.cpp index ce456a966..61fcb54ce 100644 --- a/src/core/hle/service/nwm_uds.cpp +++ b/src/core/hle/service/nwm_uds.cpp | |||
| @@ -26,7 +26,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 26 | // Interface class | 26 | // Interface class |
| 27 | 27 | ||
| 28 | Interface::Interface() { | 28 | Interface::Interface() { |
| 29 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 29 | Register(FunctionTable); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | } // namespace | 32 | } // namespace |
diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp index 529dccafb..d61eaf80f 100644 --- a/src/core/hle/service/pm_app.cpp +++ b/src/core/hle/service/pm_app.cpp | |||
| @@ -26,7 +26,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 26 | // Interface class | 26 | // Interface class |
| 27 | 27 | ||
| 28 | Interface::Interface() { | 28 | Interface::Interface() { |
| 29 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 29 | Register(FunctionTable); |
| 30 | } | 30 | } |
| 31 | 31 | ||
| 32 | } // namespace | 32 | } // namespace |
diff --git a/src/core/hle/service/ptm_play.cpp b/src/core/hle/service/ptm_play.cpp index ae9e2925c..b357057fd 100644 --- a/src/core/hle/service/ptm_play.cpp +++ b/src/core/hle/service/ptm_play.cpp | |||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 22 | // Interface class | 22 | // Interface class |
| 23 | 23 | ||
| 24 | Interface::Interface() { | 24 | Interface::Interface() { |
| 25 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 25 | Register(FunctionTable); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | } // namespace | 28 | } // namespace |
diff --git a/src/core/hle/service/ptm_sysm.cpp b/src/core/hle/service/ptm_sysm.cpp index 4b5f86a47..b6f688de3 100644 --- a/src/core/hle/service/ptm_sysm.cpp +++ b/src/core/hle/service/ptm_sysm.cpp | |||
| @@ -50,7 +50,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 50 | // Interface class | 50 | // Interface class |
| 51 | 51 | ||
| 52 | Interface::Interface() { | 52 | Interface::Interface() { |
| 53 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 53 | Register(FunctionTable); |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | } // namespace | 56 | } // namespace |
diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index 753180add..7b465a348 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp | |||
| @@ -137,7 +137,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 137 | // Interface class | 137 | // Interface class |
| 138 | 138 | ||
| 139 | Interface::Interface() { | 139 | Interface::Interface() { |
| 140 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 140 | Register(FunctionTable); |
| 141 | // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file | 141 | // Create the SharedExtSaveData archive 0xF000000B and the gamecoin.dat file |
| 142 | // TODO(Subv): In the future we should use the FS service to query this archive | 142 | // TODO(Subv): In the future we should use the FS service to query this archive |
| 143 | std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); | 143 | std::string nand_directory = FileUtil::GetUserPath(D_NAND_IDX); |
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 355196fd3..e0979ea5d 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -54,96 +54,76 @@ | |||
| 54 | 54 | ||
| 55 | namespace Service { | 55 | namespace Service { |
| 56 | 56 | ||
| 57 | Manager* g_manager = nullptr; ///< Service manager | 57 | std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; |
| 58 | std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; | ||
| 58 | 59 | ||
| 59 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 60 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| 60 | // Service Manager class | 61 | // Module interface |
| 61 | |||
| 62 | void Manager::AddService(Interface* service) { | ||
| 63 | // TOOD(yuriks): Fix error reporting | ||
| 64 | m_port_map[service->GetPortName()] = Kernel::g_handle_table.Create(service).ValueOr(INVALID_HANDLE); | ||
| 65 | m_services.push_back(service); | ||
| 66 | } | ||
| 67 | |||
| 68 | void Manager::DeleteService(const std::string& port_name) { | ||
| 69 | Interface* service = FetchFromPortName(port_name); | ||
| 70 | m_services.erase(std::remove(m_services.begin(), m_services.end(), service), m_services.end()); | ||
| 71 | m_port_map.erase(port_name); | ||
| 72 | } | ||
| 73 | 62 | ||
| 74 | Interface* Manager::FetchFromHandle(Handle handle) { | 63 | static void AddNamedPort(Interface* interface) { |
| 75 | // TODO(yuriks): This function is very suspicious and should probably be exterminated. | 64 | g_kernel_named_ports.emplace(interface->GetPortName(), interface); |
| 76 | return Kernel::g_handle_table.Get<Interface>(handle).get(); | ||
| 77 | } | 65 | } |
| 78 | 66 | ||
| 79 | Interface* Manager::FetchFromPortName(const std::string& port_name) { | 67 | static void AddService(Interface* interface) { |
| 80 | auto itr = m_port_map.find(port_name); | 68 | g_srv_services.emplace(interface->GetPortName(), interface); |
| 81 | if (itr == m_port_map.end()) { | ||
| 82 | return nullptr; | ||
| 83 | } | ||
| 84 | return FetchFromHandle(itr->second); | ||
| 85 | } | 69 | } |
| 86 | 70 | ||
| 87 | |||
| 88 | //////////////////////////////////////////////////////////////////////////////////////////////////// | ||
| 89 | // Module interface | ||
| 90 | |||
| 91 | /// Initialize ServiceManager | 71 | /// Initialize ServiceManager |
| 92 | void Init() { | 72 | void Init() { |
| 93 | g_manager = new Manager; | 73 | AddNamedPort(new SRV::Interface); |
| 94 | 74 | ||
| 95 | g_manager->AddService(new SRV::Interface); | 75 | AddService(new AC_U::Interface); |
| 96 | g_manager->AddService(new AC_U::Interface); | 76 | AddService(new ACT_U::Interface); |
| 97 | g_manager->AddService(new ACT_U::Interface); | 77 | AddService(new AM_APP::Interface); |
| 98 | g_manager->AddService(new AM_APP::Interface); | 78 | AddService(new AM_NET::Interface); |
| 99 | g_manager->AddService(new AM_NET::Interface); | 79 | AddService(new AM_SYS::Interface); |
| 100 | g_manager->AddService(new AM_SYS::Interface); | 80 | AddService(new APT_A::Interface); |
| 101 | g_manager->AddService(new APT_A::Interface); | 81 | AddService(new APT_S::Interface); |
| 102 | g_manager->AddService(new APT_S::Interface); | 82 | AddService(new APT_U::Interface); |
| 103 | g_manager->AddService(new APT_U::Interface); | 83 | AddService(new BOSS_P::Interface); |
| 104 | g_manager->AddService(new BOSS_P::Interface); | 84 | AddService(new BOSS_U::Interface); |
| 105 | g_manager->AddService(new BOSS_U::Interface); | 85 | AddService(new CAM_U::Interface); |
| 106 | g_manager->AddService(new CAM_U::Interface); | 86 | AddService(new CECD_S::Interface); |
| 107 | g_manager->AddService(new CECD_S::Interface); | 87 | AddService(new CECD_U::Interface); |
| 108 | g_manager->AddService(new CECD_U::Interface); | 88 | AddService(new CFG_I::Interface); |
| 109 | g_manager->AddService(new CFG_I::Interface); | 89 | AddService(new CFG_S::Interface); |
| 110 | g_manager->AddService(new CFG_S::Interface); | 90 | AddService(new CFG_U::Interface); |
| 111 | g_manager->AddService(new CFG_U::Interface); | 91 | AddService(new CSND_SND::Interface); |
| 112 | g_manager->AddService(new CSND_SND::Interface); | 92 | AddService(new DSP_DSP::Interface); |
| 113 | g_manager->AddService(new DSP_DSP::Interface); | 93 | AddService(new ERR_F::Interface); |
| 114 | g_manager->AddService(new ERR_F::Interface); | 94 | AddService(new FRD_A::Interface); |
| 115 | g_manager->AddService(new FRD_A::Interface); | 95 | AddService(new FRD_U::Interface); |
| 116 | g_manager->AddService(new FRD_U::Interface); | 96 | AddService(new FS::FSUserInterface); |
| 117 | g_manager->AddService(new FS::FSUserInterface); | 97 | AddService(new GSP_GPU::Interface); |
| 118 | g_manager->AddService(new GSP_GPU::Interface); | 98 | AddService(new GSP_LCD::Interface); |
| 119 | g_manager->AddService(new GSP_LCD::Interface); | 99 | AddService(new HID_User::Interface); |
| 120 | g_manager->AddService(new HID_User::Interface); | 100 | AddService(new HID_SPVR::Interface); |
| 121 | g_manager->AddService(new HID_SPVR::Interface); | 101 | AddService(new HTTP_C::Interface); |
| 122 | g_manager->AddService(new HTTP_C::Interface); | 102 | AddService(new IR_RST::Interface); |
| 123 | g_manager->AddService(new IR_RST::Interface); | 103 | AddService(new IR_U::Interface); |
| 124 | g_manager->AddService(new IR_U::Interface); | 104 | AddService(new LDR_RO::Interface); |
| 125 | g_manager->AddService(new LDR_RO::Interface); | 105 | AddService(new MIC_U::Interface); |
| 126 | g_manager->AddService(new MIC_U::Interface); | 106 | AddService(new NDM_U::Interface); |
| 127 | g_manager->AddService(new NDM_U::Interface); | 107 | AddService(new NEWS_S::Interface); |
| 128 | g_manager->AddService(new NEWS_S::Interface); | 108 | AddService(new NEWS_U::Interface); |
| 129 | g_manager->AddService(new NEWS_U::Interface); | 109 | AddService(new NIM_AOC::Interface); |
| 130 | g_manager->AddService(new NIM_AOC::Interface); | 110 | AddService(new NS_S::Interface); |
| 131 | g_manager->AddService(new NS_S::Interface); | 111 | AddService(new NWM_UDS::Interface); |
| 132 | g_manager->AddService(new NWM_UDS::Interface); | 112 | AddService(new PM_APP::Interface); |
| 133 | g_manager->AddService(new PM_APP::Interface); | 113 | AddService(new PTM_PLAY::Interface); |
| 134 | g_manager->AddService(new PTM_PLAY::Interface); | 114 | AddService(new PTM_U::Interface); |
| 135 | g_manager->AddService(new PTM_U::Interface); | 115 | AddService(new PTM_SYSM::Interface); |
| 136 | g_manager->AddService(new PTM_SYSM::Interface); | 116 | AddService(new SOC_U::Interface); |
| 137 | g_manager->AddService(new SOC_U::Interface); | 117 | AddService(new SSL_C::Interface); |
| 138 | g_manager->AddService(new SSL_C::Interface); | 118 | AddService(new Y2R_U::Interface); |
| 139 | g_manager->AddService(new Y2R_U::Interface); | ||
| 140 | 119 | ||
| 141 | LOG_DEBUG(Service, "initialized OK"); | 120 | LOG_DEBUG(Service, "initialized OK"); |
| 142 | } | 121 | } |
| 143 | 122 | ||
| 144 | /// Shutdown ServiceManager | 123 | /// Shutdown ServiceManager |
| 145 | void Shutdown() { | 124 | void Shutdown() { |
| 146 | delete g_manager; | 125 | g_srv_services.clear(); |
| 126 | g_kernel_named_ports.clear(); | ||
| 147 | LOG_DEBUG(Service, "shutdown OK"); | 127 | LOG_DEBUG(Service, "shutdown OK"); |
| 148 | } | 128 | } |
| 149 | 129 | ||
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index e75d5008b..3370f9f9b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -5,9 +5,11 @@ | |||
| 5 | #pragma once | 5 | #pragma once |
| 6 | 6 | ||
| 7 | #include <algorithm> | 7 | #include <algorithm> |
| 8 | #include <vector> | ||
| 9 | #include <map> | ||
| 10 | #include <string> | 8 | #include <string> |
| 9 | #include <unordered_map> | ||
| 10 | #include <vector> | ||
| 11 | |||
| 12 | #include <boost/container/flat_map.hpp> | ||
| 11 | 13 | ||
| 12 | #include "common/common.h" | 14 | #include "common/common.h" |
| 13 | #include "common/string_util.h" | 15 | #include "common/string_util.h" |
| @@ -27,7 +29,7 @@ static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 character | |||
| 27 | class Manager; | 29 | class Manager; |
| 28 | 30 | ||
| 29 | /// Interface to a CTROS service | 31 | /// Interface to a CTROS service |
| 30 | class Interface : public Kernel::Session { | 32 | class Interface : public Kernel::Session { |
| 31 | // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be | 33 | // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be |
| 32 | // just something that encapsulates a session and acts as a helper to implement service | 34 | // just something that encapsulates a session and acts as a helper to implement service |
| 33 | // processes. | 35 | // processes. |
| @@ -38,11 +40,11 @@ class Interface : public Kernel::Session { | |||
| 38 | * Creates a function string for logging, complete with the name (or header code, depending | 40 | * Creates a function string for logging, complete with the name (or header code, depending |
| 39 | * on what's passed in) the port name, and all the cmd_buff arguments. | 41 | * on what's passed in) the port name, and all the cmd_buff arguments. |
| 40 | */ | 42 | */ |
| 41 | std::string MakeFunctionString(const std::string& name, const std::string& port_name, const u32* cmd_buff) { | 43 | std::string MakeFunctionString(const char* name, const char* port_name, const u32* cmd_buff) { |
| 42 | // Number of params == bits 0-5 + bits 6-11 | 44 | // Number of params == bits 0-5 + bits 6-11 |
| 43 | int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); | 45 | int num_params = (cmd_buff[0] & 0x3F) + ((cmd_buff[0] >> 6) & 0x3F); |
| 44 | 46 | ||
| 45 | std::string function_string = Common::StringFromFormat("function '%s': port=%s", name.c_str(), port_name.c_str()); | 47 | std::string function_string = Common::StringFromFormat("function '%s': port=%s", name, port_name); |
| 46 | for (int i = 1; i <= num_params; ++i) { | 48 | for (int i = 1; i <= num_params; ++i) { |
| 47 | function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); | 49 | function_string += Common::StringFromFormat(", cmd_buff[%i]=%u", i, cmd_buff[i]); |
| 48 | } | 50 | } |
| @@ -57,7 +59,7 @@ public: | |||
| 57 | struct FunctionInfo { | 59 | struct FunctionInfo { |
| 58 | u32 id; | 60 | u32 id; |
| 59 | Function func; | 61 | Function func; |
| 60 | std::string name; | 62 | const char* name; |
| 61 | }; | 63 | }; |
| 62 | 64 | ||
| 63 | /** | 65 | /** |
| @@ -68,34 +70,19 @@ public: | |||
| 68 | return "[UNKNOWN SERVICE PORT]"; | 70 | return "[UNKNOWN SERVICE PORT]"; |
| 69 | } | 71 | } |
| 70 | 72 | ||
| 71 | /// Allocates a new handle for the service | ||
| 72 | Handle CreateHandle(Kernel::Object *obj) { | ||
| 73 | // TODO(yuriks): Fix error reporting | ||
| 74 | Handle handle = Kernel::g_handle_table.Create(obj).ValueOr(INVALID_HANDLE); | ||
| 75 | m_handles.push_back(handle); | ||
| 76 | return handle; | ||
| 77 | } | ||
| 78 | |||
| 79 | /// Frees a handle from the service | ||
| 80 | template <class T> | ||
| 81 | void DeleteHandle(const Handle handle) { | ||
| 82 | Kernel::g_handle_table.Close(handle); | ||
| 83 | m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); | ||
| 84 | } | ||
| 85 | |||
| 86 | ResultVal<bool> SyncRequest() override { | 73 | ResultVal<bool> SyncRequest() override { |
| 87 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 74 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 88 | auto itr = m_functions.find(cmd_buff[0]); | 75 | auto itr = m_functions.find(cmd_buff[0]); |
| 89 | 76 | ||
| 90 | if (itr == m_functions.end() || itr->second.func == nullptr) { | 77 | if (itr == m_functions.end() || itr->second.func == nullptr) { |
| 91 | std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; | 78 | std::string function_name = (itr == m_functions.end()) ? Common::StringFromFormat("0x%08X", cmd_buff[0]) : itr->second.name; |
| 92 | LOG_ERROR(Service, "%s %s", "unknown/unimplemented", MakeFunctionString(function_name, GetPortName(), cmd_buff).c_str()); | 79 | LOG_ERROR(Service, "unknown / unimplemented %s", MakeFunctionString(function_name.c_str(), GetPortName().c_str(), cmd_buff).c_str()); |
| 93 | 80 | ||
| 94 | // TODO(bunnei): Hack - ignore error | 81 | // TODO(bunnei): Hack - ignore error |
| 95 | cmd_buff[1] = 0; | 82 | cmd_buff[1] = 0; |
| 96 | return MakeResult<bool>(false); | 83 | return MakeResult<bool>(false); |
| 97 | } else { | 84 | } else { |
| 98 | LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName(), cmd_buff).c_str()); | 85 | LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); |
| 99 | } | 86 | } |
| 100 | 87 | ||
| 101 | itr->second.func(this); | 88 | itr->second.func(this); |
| @@ -108,37 +95,18 @@ protected: | |||
| 108 | /** | 95 | /** |
| 109 | * Registers the functions in the service | 96 | * Registers the functions in the service |
| 110 | */ | 97 | */ |
| 111 | void Register(const FunctionInfo* functions, int len) { | 98 | template <size_t N> |
| 112 | for (int i = 0; i < len; i++) { | 99 | void Register(const FunctionInfo (&functions)[N]) { |
| 113 | m_functions[functions[i].id] = functions[i]; | 100 | m_functions.reserve(N); |
| 101 | for (auto& fn : functions) { | ||
| 102 | // Usually this array is sorted by id already, so hint to instead at the end | ||
| 103 | m_functions.emplace_hint(m_functions.cend(), fn.id, fn); | ||
| 114 | } | 104 | } |
| 115 | } | 105 | } |
| 116 | 106 | ||
| 117 | private: | 107 | private: |
| 108 | boost::container::flat_map<u32, FunctionInfo> m_functions; | ||
| 118 | 109 | ||
| 119 | std::vector<Handle> m_handles; | ||
| 120 | std::map<u32, FunctionInfo> m_functions; | ||
| 121 | |||
| 122 | }; | ||
| 123 | |||
| 124 | /// Simple class to manage accessing services from ports and UID handles | ||
| 125 | class Manager { | ||
| 126 | public: | ||
| 127 | /// Add a service to the manager | ||
| 128 | void AddService(Interface* service); | ||
| 129 | |||
| 130 | /// Removes a service from the manager | ||
| 131 | void DeleteService(const std::string& port_name); | ||
| 132 | |||
| 133 | /// Get a Service Interface from its Handle | ||
| 134 | Interface* FetchFromHandle(Handle handle); | ||
| 135 | |||
| 136 | /// Get a Service Interface from its port | ||
| 137 | Interface* FetchFromPortName(const std::string& port_name); | ||
| 138 | |||
| 139 | private: | ||
| 140 | std::vector<Interface*> m_services; | ||
| 141 | std::map<std::string, u32> m_port_map; | ||
| 142 | }; | 110 | }; |
| 143 | 111 | ||
| 144 | /// Initialize ServiceManager | 112 | /// Initialize ServiceManager |
| @@ -147,8 +115,9 @@ void Init(); | |||
| 147 | /// Shutdown ServiceManager | 115 | /// Shutdown ServiceManager |
| 148 | void Shutdown(); | 116 | void Shutdown(); |
| 149 | 117 | ||
| 150 | 118 | /// Map of named ports managed by the kernel, which can be retrieved using the ConnectToPort SVC. | |
| 151 | extern Manager* g_manager; ///< Service manager | 119 | extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_kernel_named_ports; |
| 152 | 120 | /// Map of services registered with the "srv:" service, retrieved using GetServiceHandle. | |
| 121 | extern std::unordered_map<std::string, Kernel::SharedPtr<Interface>> g_srv_services; | ||
| 153 | 122 | ||
| 154 | } // namespace | 123 | } // namespace |
diff --git a/src/core/hle/service/soc_u.cpp b/src/core/hle/service/soc_u.cpp index bb8ee86be..414c53c54 100644 --- a/src/core/hle/service/soc_u.cpp +++ b/src/core/hle/service/soc_u.cpp | |||
| @@ -734,7 +734,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 734 | // Interface class | 734 | // Interface class |
| 735 | 735 | ||
| 736 | Interface::Interface() { | 736 | Interface::Interface() { |
| 737 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 737 | Register(FunctionTable); |
| 738 | } | 738 | } |
| 739 | 739 | ||
| 740 | Interface::~Interface() { | 740 | Interface::~Interface() { |
diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index aa0aac3bb..cc59a03ce 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp | |||
| @@ -23,7 +23,7 @@ static void GetProcSemaphore(Service::Interface* self) { | |||
| 23 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 23 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 24 | 24 | ||
| 25 | // TODO(bunnei): Change to a semaphore once these have been implemented | 25 | // TODO(bunnei): Change to a semaphore once these have been implemented |
| 26 | event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event").MoveFrom(); | 26 | event_handle = Kernel::Event::Create(RESETTYPE_ONESHOT, "SRV:Event"); |
| 27 | event_handle->Clear(); | 27 | event_handle->Clear(); |
| 28 | 28 | ||
| 29 | cmd_buff[1] = 0; // No error | 29 | cmd_buff[1] = 0; // No error |
| @@ -35,10 +35,10 @@ static void GetServiceHandle(Service::Interface* self) { | |||
| 35 | u32* cmd_buff = Kernel::GetCommandBuffer(); | 35 | u32* cmd_buff = Kernel::GetCommandBuffer(); |
| 36 | 36 | ||
| 37 | std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); | 37 | std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); |
| 38 | Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); | 38 | auto it = Service::g_srv_services.find(port_name); |
| 39 | 39 | ||
| 40 | if (nullptr != service) { | 40 | if (it != Service::g_srv_services.end()) { |
| 41 | cmd_buff[3] = service->GetHandle(); | 41 | cmd_buff[3] = Kernel::g_handle_table.Create(it->second).MoveFrom(); |
| 42 | LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); | 42 | LOG_TRACE(Service_SRV, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); |
| 43 | } else { | 43 | } else { |
| 44 | LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); | 44 | LOG_ERROR(Service_SRV, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); |
| @@ -63,7 +63,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 63 | // Interface class | 63 | // Interface class |
| 64 | 64 | ||
| 65 | Interface::Interface() { | 65 | Interface::Interface() { |
| 66 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 66 | Register(FunctionTable); |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | } // namespace | 69 | } // namespace |
diff --git a/src/core/hle/service/ssl_c.cpp b/src/core/hle/service/ssl_c.cpp index 360516cdf..3f49c1c97 100644 --- a/src/core/hle/service/ssl_c.cpp +++ b/src/core/hle/service/ssl_c.cpp | |||
| @@ -22,7 +22,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 22 | // Interface class | 22 | // Interface class |
| 23 | 23 | ||
| 24 | Interface::Interface() { | 24 | Interface::Interface() { |
| 25 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 25 | Register(FunctionTable); |
| 26 | } | 26 | } |
| 27 | 27 | ||
| 28 | } // namespace | 28 | } // namespace |
diff --git a/src/core/hle/service/y2r_u.cpp b/src/core/hle/service/y2r_u.cpp index b3d873ef0..fc76d2721 100644 --- a/src/core/hle/service/y2r_u.cpp +++ b/src/core/hle/service/y2r_u.cpp | |||
| @@ -54,7 +54,7 @@ const Interface::FunctionInfo FunctionTable[] = { | |||
| 54 | // Interface class | 54 | // Interface class |
| 55 | 55 | ||
| 56 | Interface::Interface() { | 56 | Interface::Interface() { |
| 57 | Register(FunctionTable, ARRAY_SIZE(FunctionTable)); | 57 | Register(FunctionTable); |
| 58 | } | 58 | } |
| 59 | 59 | ||
| 60 | } // namespace | 60 | } // namespace |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 88813c2ce..34a27917f 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -30,6 +30,11 @@ using Kernel::ERR_INVALID_HANDLE; | |||
| 30 | 30 | ||
| 31 | namespace SVC { | 31 | namespace SVC { |
| 32 | 32 | ||
| 33 | const ResultCode ERR_NOT_FOUND(ErrorDescription::NotFound, ErrorModule::Kernel, | ||
| 34 | ErrorSummary::NotFound, ErrorLevel::Permanent); // 0xD88007FA | ||
| 35 | const ResultCode ERR_PORT_NAME_TOO_LONG(ErrorDescription(30), ErrorModule::OS, | ||
| 36 | ErrorSummary::InvalidArgument, ErrorLevel::Usage); // 0xE0E0181E | ||
| 37 | |||
| 33 | /// An invalid result code that is meant to be overwritten when a thread resumes from waiting | 38 | /// An invalid result code that is meant to be overwritten when a thread resumes from waiting |
| 34 | const ResultCode RESULT_INVALID(0xDEADC0DE); | 39 | const ResultCode RESULT_INVALID(0xDEADC0DE); |
| 35 | 40 | ||
| @@ -94,14 +99,21 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o | |||
| 94 | } | 99 | } |
| 95 | 100 | ||
| 96 | /// Connect to an OS service given the port name, returns the handle to the port to out | 101 | /// Connect to an OS service given the port name, returns the handle to the port to out |
| 97 | static ResultCode ConnectToPort(Handle* out, const char* port_name) { | 102 | static ResultCode ConnectToPort(Handle* out_handle, const char* port_name) { |
| 98 | Service::Interface* service = Service::g_manager->FetchFromPortName(port_name); | 103 | if (port_name == nullptr) |
| 104 | return ERR_NOT_FOUND; | ||
| 105 | if (std::strlen(port_name) > 11) | ||
| 106 | return ERR_PORT_NAME_TOO_LONG; | ||
| 99 | 107 | ||
| 100 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); | 108 | LOG_TRACE(Kernel_SVC, "called port_name=%s", port_name); |
| 101 | _assert_msg_(KERNEL, (service != nullptr), "called, but service is not implemented!"); | ||
| 102 | 109 | ||
| 103 | *out = service->GetHandle(); | 110 | auto it = Service::g_kernel_named_ports.find(port_name); |
| 111 | if (it == Service::g_kernel_named_ports.end()) { | ||
| 112 | LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: %s", port_name); | ||
| 113 | return ERR_NOT_FOUND; | ||
| 114 | } | ||
| 104 | 115 | ||
| 116 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(it->second)); | ||
| 105 | return RESULT_SUCCESS; | 117 | return RESULT_SUCCESS; |
| 106 | } | 118 | } |
| 107 | 119 | ||
| @@ -119,9 +131,8 @@ static ResultCode SendSyncRequest(Handle handle) { | |||
| 119 | 131 | ||
| 120 | /// Close a handle | 132 | /// Close a handle |
| 121 | static ResultCode CloseHandle(Handle handle) { | 133 | static ResultCode CloseHandle(Handle handle) { |
| 122 | // ImplementMe | 134 | LOG_TRACE(Kernel_SVC, "Closing handle 0x%08X", handle); |
| 123 | LOG_ERROR(Kernel_SVC, "(UNIMPLEMENTED) called handle=0x%08X", handle); | 135 | return Kernel::g_handle_table.Close(handle); |
| 124 | return RESULT_SUCCESS; | ||
| 125 | } | 136 | } |
| 126 | 137 | ||
| 127 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds | 138 | /// Wait for a handle to synchronize, timeout after the specified nanoseconds |
| @@ -140,7 +151,7 @@ static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { | |||
| 140 | Kernel::WaitCurrentThread_WaitSynchronization(object, false, false); | 151 | Kernel::WaitCurrentThread_WaitSynchronization(object, false, false); |
| 141 | 152 | ||
| 142 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 153 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 143 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 154 | Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); |
| 144 | 155 | ||
| 145 | HLE::Reschedule(__func__); | 156 | HLE::Reschedule(__func__); |
| 146 | 157 | ||
| @@ -216,7 +227,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou | |||
| 216 | } | 227 | } |
| 217 | 228 | ||
| 218 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 229 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 219 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nano_seconds); | 230 | Kernel::GetCurrentThread()->WakeAfterDelay(nano_seconds); |
| 220 | 231 | ||
| 221 | HLE::Reschedule(__func__); | 232 | HLE::Reschedule(__func__); |
| 222 | 233 | ||
| @@ -250,7 +261,7 @@ static ResultCode WaitSynchronizationN(s32* out, Handle* handles, s32 handle_cou | |||
| 250 | static ResultCode CreateAddressArbiter(Handle* out_handle) { | 261 | static ResultCode CreateAddressArbiter(Handle* out_handle) { |
| 251 | using Kernel::AddressArbiter; | 262 | using Kernel::AddressArbiter; |
| 252 | 263 | ||
| 253 | CASCADE_RESULT(SharedPtr<AddressArbiter> arbiter, AddressArbiter::Create()); | 264 | SharedPtr<AddressArbiter> arbiter = AddressArbiter::Create(); |
| 254 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(arbiter))); | 265 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(arbiter))); |
| 255 | LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *out_handle); | 266 | LOG_TRACE(Kernel_SVC, "returned handle=0x%08X", *out_handle); |
| 256 | return RESULT_SUCCESS; | 267 | return RESULT_SUCCESS; |
| @@ -355,7 +366,7 @@ static ResultCode SetThreadPriority(Handle handle, s32 priority) { | |||
| 355 | static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { | 366 | static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { |
| 356 | using Kernel::Mutex; | 367 | using Kernel::Mutex; |
| 357 | 368 | ||
| 358 | CASCADE_RESULT(SharedPtr<Mutex> mutex, Mutex::Create(initial_locked != 0)); | 369 | SharedPtr<Mutex> mutex = Mutex::Create(initial_locked != 0); |
| 359 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); | 370 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(mutex))); |
| 360 | 371 | ||
| 361 | LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", | 372 | LOG_TRACE(Kernel_SVC, "called initial_locked=%s : created handle=0x%08X", |
| @@ -423,7 +434,9 @@ static ResultCode QueryMemory(void* info, void* out, u32 addr) { | |||
| 423 | 434 | ||
| 424 | /// Create an event | 435 | /// Create an event |
| 425 | static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { | 436 | static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { |
| 426 | CASCADE_RESULT(auto evt, Kernel::Event::Create(static_cast<ResetType>(reset_type))); | 437 | using Kernel::Event; |
| 438 | |||
| 439 | SharedPtr<Event> evt = Kernel::Event::Create(static_cast<ResetType>(reset_type)); | ||
| 427 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); | 440 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(evt))); |
| 428 | 441 | ||
| 429 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", | 442 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", |
| @@ -433,19 +446,17 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { | |||
| 433 | 446 | ||
| 434 | /// Duplicates a kernel handle | 447 | /// Duplicates a kernel handle |
| 435 | static ResultCode DuplicateHandle(Handle* out, Handle handle) { | 448 | static ResultCode DuplicateHandle(Handle* out, Handle handle) { |
| 436 | ResultVal<Handle> out_h = Kernel::g_handle_table.Duplicate(handle); | 449 | CASCADE_RESULT(*out, Kernel::g_handle_table.Duplicate(handle)); |
| 437 | if (out_h.Succeeded()) { | 450 | LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); |
| 438 | *out = *out_h; | 451 | return RESULT_SUCCESS; |
| 439 | LOG_TRACE(Kernel_SVC, "duplicated 0x%08X to 0x%08X", handle, *out); | ||
| 440 | } | ||
| 441 | return out_h.Code(); | ||
| 442 | } | 452 | } |
| 443 | 453 | ||
| 444 | /// Signals an event | 454 | /// Signals an event |
| 445 | static ResultCode SignalEvent(Handle handle) { | 455 | static ResultCode SignalEvent(Handle handle) { |
| 456 | using Kernel::Event; | ||
| 446 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); | 457 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); |
| 447 | 458 | ||
| 448 | auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); | 459 | SharedPtr<Event> evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); |
| 449 | if (evt == nullptr) | 460 | if (evt == nullptr) |
| 450 | return ERR_INVALID_HANDLE; | 461 | return ERR_INVALID_HANDLE; |
| 451 | 462 | ||
| @@ -456,9 +467,10 @@ static ResultCode SignalEvent(Handle handle) { | |||
| 456 | 467 | ||
| 457 | /// Clears an event | 468 | /// Clears an event |
| 458 | static ResultCode ClearEvent(Handle handle) { | 469 | static ResultCode ClearEvent(Handle handle) { |
| 470 | using Kernel::Event; | ||
| 459 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); | 471 | LOG_TRACE(Kernel_SVC, "called event=0x%08X", handle); |
| 460 | 472 | ||
| 461 | auto evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); | 473 | SharedPtr<Event> evt = Kernel::g_handle_table.Get<Kernel::Event>(handle); |
| 462 | if (evt == nullptr) | 474 | if (evt == nullptr) |
| 463 | return ERR_INVALID_HANDLE; | 475 | return ERR_INVALID_HANDLE; |
| 464 | 476 | ||
| @@ -470,7 +482,7 @@ static ResultCode ClearEvent(Handle handle) { | |||
| 470 | static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { | 482 | static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { |
| 471 | using Kernel::Timer; | 483 | using Kernel::Timer; |
| 472 | 484 | ||
| 473 | CASCADE_RESULT(auto timer, Timer::Create(static_cast<ResetType>(reset_type))); | 485 | SharedPtr<Timer> timer = Timer::Create(static_cast<ResetType>(reset_type)); |
| 474 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); | 486 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(timer))); |
| 475 | 487 | ||
| 476 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", | 488 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", |
| @@ -528,7 +540,7 @@ static void SleepThread(s64 nanoseconds) { | |||
| 528 | Kernel::WaitCurrentThread_Sleep(); | 540 | Kernel::WaitCurrentThread_Sleep(); |
| 529 | 541 | ||
| 530 | // Create an event to wake the thread up after the specified nanosecond delay has passed | 542 | // Create an event to wake the thread up after the specified nanosecond delay has passed |
| 531 | Kernel::WakeThreadAfterDelay(Kernel::GetCurrentThread(), nanoseconds); | 543 | Kernel::GetCurrentThread()->WakeAfterDelay(nanoseconds); |
| 532 | 544 | ||
| 533 | HLE::Reschedule(__func__); | 545 | HLE::Reschedule(__func__); |
| 534 | } | 546 | } |
| @@ -544,7 +556,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 | |||
| 544 | using Kernel::SharedMemory; | 556 | using Kernel::SharedMemory; |
| 545 | // TODO(Subv): Implement this function | 557 | // TODO(Subv): Implement this function |
| 546 | 558 | ||
| 547 | CASCADE_RESULT(auto shared_memory, SharedMemory::Create()); | 559 | SharedPtr<SharedMemory> shared_memory = SharedMemory::Create(); |
| 548 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); | 560 | CASCADE_RESULT(*out_handle, Kernel::g_handle_table.Create(std::move(shared_memory))); |
| 549 | 561 | ||
| 550 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); | 562 | LOG_WARNING(Kernel_SVC, "(STUBBED) called addr=0x%08X", addr); |