diff options
| author | 2015-01-21 21:09:47 -0500 | |
|---|---|---|
| committer | 2015-01-21 21:09:47 -0500 | |
| commit | 24a63662ba6c7816001bba399e85d8c131a89489 (patch) | |
| tree | a9959e69723b4f19550834171c962ec06c9e34b7 /src/core/hle/kernel/kernel.h | |
| parent | Merge pull request #491 from archshift/hidspvr (diff) | |
| parent | WaitSynchronization: Added a result code for invalid result, fixed bug. (diff) | |
| download | yuzu-24a63662ba6c7816001bba399e85d8c131a89489.tar.gz yuzu-24a63662ba6c7816001bba399e85d8c131a89489.tar.xz yuzu-24a63662ba6c7816001bba399e85d8c131a89489.zip | |
Merge pull request #495 from bunnei/fix-waitsynch
Fix WaitSynchronization
Diffstat (limited to 'src/core/hle/kernel/kernel.h')
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 87 |
1 files changed, 79 insertions, 8 deletions
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5e5217b78..3828efbea 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | 8 | ||
| 9 | #include <array> | 9 | #include <array> |
| 10 | #include <string> | 10 | #include <string> |
| 11 | #include <vector> | ||
| 12 | |||
| 11 | #include "common/common.h" | 13 | #include "common/common.h" |
| 12 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 13 | 15 | ||
| @@ -58,17 +60,35 @@ class Object : NonCopyable { | |||
| 58 | public: | 60 | public: |
| 59 | virtual ~Object() {} | 61 | virtual ~Object() {} |
| 60 | Handle GetHandle() const { return handle; } | 62 | Handle GetHandle() const { return handle; } |
| 63 | |||
| 61 | virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } | 64 | virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } |
| 62 | virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } | 65 | virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } |
| 63 | virtual Kernel::HandleType GetHandleType() const = 0; | 66 | virtual Kernel::HandleType GetHandleType() const = 0; |
| 64 | 67 | ||
| 65 | /** | 68 | /** |
| 66 | * Wait for kernel object to synchronize. | 69 | * Check if a thread can wait on the object |
| 67 | * @return True if the current thread should wait as a result of the wait | 70 | * @return True if a thread can wait on the object, otherwise false |
| 68 | */ | 71 | */ |
| 69 | virtual ResultVal<bool> WaitSynchronization() { | 72 | bool IsWaitable() const { |
| 70 | LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); | 73 | switch (GetHandleType()) { |
| 71 | return UnimplementedFunction(ErrorModule::Kernel); | 74 | case HandleType::Session: |
| 75 | case HandleType::Event: | ||
| 76 | case HandleType::Mutex: | ||
| 77 | case HandleType::Thread: | ||
| 78 | case HandleType::Semaphore: | ||
| 79 | case HandleType::Timer: | ||
| 80 | return true; | ||
| 81 | |||
| 82 | case HandleType::Unknown: | ||
| 83 | case HandleType::Port: | ||
| 84 | case HandleType::SharedMemory: | ||
| 85 | case HandleType::Redirection: | ||
| 86 | case HandleType::Process: | ||
| 87 | case HandleType::AddressArbiter: | ||
| 88 | return false; | ||
| 89 | } | ||
| 90 | |||
| 91 | return false; | ||
| 72 | } | 92 | } |
| 73 | 93 | ||
| 74 | private: | 94 | private: |
| @@ -92,6 +112,44 @@ inline void intrusive_ptr_release(Object* object) { | |||
| 92 | template <typename T> | 112 | template <typename T> |
| 93 | using SharedPtr = boost::intrusive_ptr<T>; | 113 | using SharedPtr = boost::intrusive_ptr<T>; |
| 94 | 114 | ||
| 115 | /// Class that represents a Kernel object that a thread can be waiting on | ||
| 116 | class WaitObject : public Object { | ||
| 117 | public: | ||
| 118 | |||
| 119 | /** | ||
| 120 | * Check if the current thread should wait until the object is available | ||
| 121 | * @return True if the current thread should wait due to this object being unavailable | ||
| 122 | */ | ||
| 123 | virtual bool ShouldWait() = 0; | ||
| 124 | |||
| 125 | /// Acquire/lock the object if it is available | ||
| 126 | virtual void Acquire() = 0; | ||
| 127 | |||
| 128 | /** | ||
| 129 | * Add a thread to wait on this object | ||
| 130 | * @param thread Pointer to thread to add | ||
| 131 | */ | ||
| 132 | void AddWaitingThread(Thread* thread); | ||
| 133 | |||
| 134 | /** | ||
| 135 | * Removes a thread from waiting on this object (e.g. if it was resumed already) | ||
| 136 | * @param thread Pointer to thread to remove | ||
| 137 | */ | ||
| 138 | void RemoveWaitingThread(Thread* thead); | ||
| 139 | |||
| 140 | /** | ||
| 141 | * Wake up the next thread waiting on this object | ||
| 142 | * @return Pointer to the thread that was resumed, nullptr if no threads are waiting | ||
| 143 | */ | ||
| 144 | Thread* WakeupNextThread(); | ||
| 145 | |||
| 146 | /// Wake up all threads waiting on this object | ||
| 147 | void WakeupAllWaitingThreads(); | ||
| 148 | |||
| 149 | private: | ||
| 150 | std::vector<Thread*> waiting_threads; ///< Threads waiting for this object to become available | ||
| 151 | }; | ||
| 152 | |||
| 95 | /** | 153 | /** |
| 96 | * This class allows the creation of Handles, which are references to objects that can be tested | 154 | * This class allows the creation of Handles, which are references to objects that can be tested |
| 97 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the | 155 | * for validity and looked up. Here they are used to pass references to kernel objects to/from the |
| @@ -146,14 +204,14 @@ public: | |||
| 146 | 204 | ||
| 147 | /** | 205 | /** |
| 148 | * Looks up a handle. | 206 | * Looks up a handle. |
| 149 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. | 207 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. |
| 150 | */ | 208 | */ |
| 151 | SharedPtr<Object> GetGeneric(Handle handle) const; | 209 | SharedPtr<Object> GetGeneric(Handle handle) const; |
| 152 | 210 | ||
| 153 | /** | 211 | /** |
| 154 | * Looks up a handle while verifying its type. | 212 | * Looks up a handle while verifying its type. |
| 155 | * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid or its | 213 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its |
| 156 | * type differs from the handle type `T::HANDLE_TYPE`. | 214 | * type differs from the handle type `T::HANDLE_TYPE`. |
| 157 | */ | 215 | */ |
| 158 | template <class T> | 216 | template <class T> |
| 159 | SharedPtr<T> Get(Handle handle) const { | 217 | SharedPtr<T> Get(Handle handle) const { |
| @@ -164,6 +222,19 @@ public: | |||
| 164 | return nullptr; | 222 | return nullptr; |
| 165 | } | 223 | } |
| 166 | 224 | ||
| 225 | /** | ||
| 226 | * Looks up a handle while verifying that it is an object that a thread can wait on | ||
| 227 | * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or it is | ||
| 228 | * not a waitable object. | ||
| 229 | */ | ||
| 230 | SharedPtr<WaitObject> GetWaitObject(Handle handle) const { | ||
| 231 | SharedPtr<Object> object = GetGeneric(handle); | ||
| 232 | if (object != nullptr && object->IsWaitable()) { | ||
| 233 | return boost::static_pointer_cast<WaitObject>(std::move(object)); | ||
| 234 | } | ||
| 235 | return nullptr; | ||
| 236 | } | ||
| 237 | |||
| 167 | /// Closes all handles held in this table. | 238 | /// Closes all handles held in this table. |
| 168 | void Clear(); | 239 | void Clear(); |
| 169 | 240 | ||