From c22bac6398ff1705992fc44b2c29775c84cff662 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 14 Jan 2015 19:22:50 -0500 Subject: Kernel: Added WaitObject and changed "waitable" objects inherit from it. --- src/core/hle/kernel/kernel.h | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5e5217b78..a9af9de88 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -8,6 +8,8 @@ #include #include +#include + #include "common/common.h" #include "core/hle/result.h" @@ -92,6 +94,29 @@ inline void intrusive_ptr_release(Object* object) { template using SharedPtr = boost::intrusive_ptr; +/// Class that represents a Kernel object that a thread can be waiting on +class WaitObject : public Object { +public: + + /** + * Add a thread to wait on this object + * @param thread Pointer to thread to add + */ + void AddWaitingThread(Thread* thread); + + /** + * Resumes the next thread waiting on this object + * @return Pointer to the thread that was resumed, nullptr if no threads are waiting + */ + Thread* ResumeNextThread(); + + /// Releases all threads waiting on this object + void ReleaseAllWaitingThreads(); + +private: + std::vector waiting_threads; ///< Threads waiting for this object to become available +}; + /** * This class allows the creation of Handles, which are references to objects that can be tested * for validity and looked up. Here they are used to pass references to kernel objects to/from the -- cgit v1.2.3 From 5e77e2e1de73ce7786f52f2a74c28182fa4aa845 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 14 Jan 2015 23:19:22 -0500 Subject: WaitObject: Added RemoveWaitingThread, fixed a bug, and cleanup. --- src/core/hle/kernel/kernel.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a9af9de88..53b3f9143 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -105,7 +105,13 @@ public: void AddWaitingThread(Thread* thread); /** - * Resumes the next thread waiting on this object + * Removes a thread from waiting on this object (e.g. if it was resumed already) + * @param thread Pointer to thread to remove + */ + void RemoveWaitingThread(Thread* thead); + + /** + * Resumes (and removes) the next thread waiting on this object * @return Pointer to the thread that was resumed, nullptr if no threads are waiting */ Thread* ResumeNextThread(); -- cgit v1.2.3 From 7faf2d8e06e705d1866fa0d7848ff43541a4b172 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Jan 2015 02:03:44 -0500 Subject: WaitSynchronizationN: Implement return values --- src/core/hle/kernel/kernel.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 53b3f9143..af4e2f443 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -66,9 +66,10 @@ public: /** * Wait for kernel object to synchronize. + * @param index Index of wait object (only applies to WaitSynchronizationN) * @return True if the current thread should wait as a result of the wait */ - virtual ResultVal WaitSynchronization() { + virtual ResultVal WaitSynchronization(unsigned index=0) { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); return UnimplementedFunction(ErrorModule::Kernel); } @@ -111,10 +112,10 @@ public: void RemoveWaitingThread(Thread* thead); /** - * Resumes (and removes) the next thread waiting on this object + * Releases (and removes) the next thread waiting on this object * @return Pointer to the thread that was resumed, nullptr if no threads are waiting */ - Thread* ResumeNextThread(); + Thread* ReleaseNextThread(); /// Releases all threads waiting on this object void ReleaseAllWaitingThreads(); -- cgit v1.2.3 From aa01c57ae9d73e41b65d37860ca6fbb91caba33a Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 17 Jan 2015 22:23:49 -0500 Subject: Kernel: Separate WaitSynchronization into Wait and Acquire methods. --- src/core/hle/kernel/kernel.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index af4e2f443..d98fd0389 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -65,11 +65,20 @@ public: virtual Kernel::HandleType GetHandleType() const = 0; /** - * Wait for kernel object to synchronize. + * Wait the current thread for kernel object to synchronize. * @param index Index of wait object (only applies to WaitSynchronizationN) * @return True if the current thread should wait as a result of the wait */ - virtual ResultVal WaitSynchronization(unsigned index=0) { + virtual ResultVal Wait(unsigned index = 0) { + LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); + return UnimplementedFunction(ErrorModule::Kernel); + } + + /** + * Acquire/lock the kernel object if it is available + * @return True if we were able to acquire the kernel object, otherwise false + */ + virtual ResultVal Acquire() { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); return UnimplementedFunction(ErrorModule::Kernel); } -- cgit v1.2.3 From 6643673f28b9273149fc945849a13ed832e9ef33 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 01:27:46 -0500 Subject: WaitSynchronizationN: Refactor to fix several bugs - Separate wait checking from waiting the current thread - Resume thread when wait_all=true only if all objects are available at once - Set output to correct wait object index when there are duplicate handles --- src/core/hle/kernel/kernel.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index d98fd0389..cfaf0c901 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -65,18 +65,18 @@ public: virtual Kernel::HandleType GetHandleType() const = 0; /** - * Wait the current thread for kernel object to synchronize. - * @param index Index of wait object (only applies to WaitSynchronizationN) - * @return True if the current thread should wait as a result of the wait + * Check if this object is available, (optionally) wait the current thread if not + * @param wait_thread If true, wait the current thread if this object is unavailable + * @return True if the current thread should wait due to this object being unavailable */ - virtual ResultVal Wait(unsigned index = 0) { + virtual ResultVal Wait(bool wait_thread) { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); return UnimplementedFunction(ErrorModule::Kernel); } /** - * Acquire/lock the kernel object if it is available - * @return True if we were able to acquire the kernel object, otherwise false + * Acquire/lock the this object if it is available + * @return True if we were able to acquire this object, otherwise false */ virtual ResultVal Acquire() { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); -- cgit v1.2.3 From e5a9f1c64483e01b7856c581ae5685d0c5ad88dc Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 13:25:51 -0500 Subject: Kernel: Get rid of WaitTypes and simplify lots of code, removing hacks. --- src/core/hle/kernel/kernel.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index cfaf0c901..5bf9a2bfc 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -65,11 +65,10 @@ public: virtual Kernel::HandleType GetHandleType() const = 0; /** - * Check if this object is available, (optionally) wait the current thread if not - * @param wait_thread If true, wait the current thread if this object is unavailable + * Check if this object is available * @return True if the current thread should wait due to this object being unavailable */ - virtual ResultVal Wait(bool wait_thread) { + virtual ResultVal Wait() { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); return UnimplementedFunction(ErrorModule::Kernel); } -- cgit v1.2.3 From 9412996c8f86f5da5a9052f7533b05e9780c4eb0 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 14:33:11 -0500 Subject: Kernel: Moved Wait and Acquire to WaitObject, added way to retrieve a WaitObject safely. --- src/core/hle/kernel/kernel.h | 71 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5bf9a2bfc..a9a893f41 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -60,26 +60,34 @@ class Object : NonCopyable { public: virtual ~Object() {} Handle GetHandle() const { return handle; } + virtual std::string GetTypeName() const { return "[BAD KERNEL OBJECT TYPE]"; } virtual std::string GetName() const { return "[UNKNOWN KERNEL OBJECT]"; } virtual Kernel::HandleType GetHandleType() const = 0; /** - * Check if this object is available - * @return True if the current thread should wait due to this object being unavailable + * Check if a thread can wait on the object + * @return True if a thread can wait on the object, otherwise false */ - virtual ResultVal Wait() { - LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); - return UnimplementedFunction(ErrorModule::Kernel); - } + bool IsWaitable() const { + switch (GetHandleType()) { + case HandleType::Event: + case HandleType::Mutex: + case HandleType::Thread: + case HandleType::Semaphore: + case HandleType::Timer: + return true; + + case HandleType::Unknown: + case HandleType::Port: + case HandleType::SharedMemory: + case HandleType::Redirection: + case HandleType::Process: + case HandleType::AddressArbiter: + return false; + } - /** - * Acquire/lock the this object if it is available - * @return True if we were able to acquire this object, otherwise false - */ - virtual ResultVal Acquire() { - LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); - return UnimplementedFunction(ErrorModule::Kernel); + return false; } private: @@ -107,6 +115,24 @@ using SharedPtr = boost::intrusive_ptr; class WaitObject : public Object { public: + /** + * Check if this object is available + * @return True if the current thread should wait due to this object being unavailable + */ + virtual ResultVal Wait() { + LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); + return UnimplementedFunction(ErrorModule::Kernel); + } + + /** + * Acquire/lock the this object if it is available + * @return True if we were able to acquire this object, otherwise false + */ + virtual ResultVal Acquire() { + LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); + return UnimplementedFunction(ErrorModule::Kernel); + } + /** * Add a thread to wait on this object * @param thread Pointer to thread to add @@ -186,14 +212,14 @@ public: /** * Looks up a handle. - * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid. + * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. */ SharedPtr GetGeneric(Handle handle) const; /** * Looks up a handle while verifying its type. - * @returns Pointer to the looked-up object, or `nullptr` if the handle is not valid or its - * type differs from the handle type `T::HANDLE_TYPE`. + * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its + * type differs from the handle type `T::HANDLE_TYPE`. */ template SharedPtr Get(Handle handle) const { @@ -204,6 +230,19 @@ public: return nullptr; } + /** + * Looks up a handle while verifying that it is an object that a thread can wait on + * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or it is + * not a waitable object. + */ + SharedPtr GetWaitObject(Handle handle) const { + SharedPtr object = GetGeneric(handle); + if (object != nullptr && object->IsWaitable()) { + return boost::static_pointer_cast(std::move(object)); + } + return nullptr; + } + /// Closes all handles held in this table. void Clear(); -- cgit v1.2.3 From 9e6ec3b6cd23a7cef80a1d62fda515018f080083 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 18 Jan 2015 20:40:53 -0500 Subject: Session: Change to a WaitObject. --- src/core/hle/kernel/kernel.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index a9a893f41..ca9ccf4bf 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -71,6 +71,7 @@ public: */ bool IsWaitable() const { switch (GetHandleType()) { + case HandleType::Session: case HandleType::Event: case HandleType::Mutex: case HandleType::Thread: -- cgit v1.2.3 From c68eb1569549ae49ae25c6c29cec2e10d8329f2d Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 17:41:12 -0500 Subject: WaitObject: Renamed "Wait" to "ShouldWait", made "ShouldWait" and "Acquire" pure virtual. --- src/core/hle/kernel/kernel.h | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index ca9ccf4bf..1bb0b55bd 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -117,22 +117,16 @@ class WaitObject : public Object { public: /** - * Check if this object is available + * Check if the current thread should wait until the object is available * @return True if the current thread should wait due to this object being unavailable */ - virtual ResultVal Wait() { - LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); - return UnimplementedFunction(ErrorModule::Kernel); - } + virtual ResultVal ShouldWait() = 0; /** - * Acquire/lock the this object if it is available + * Acquire/lock the object if it is available * @return True if we were able to acquire this object, otherwise false */ - virtual ResultVal Acquire() { - LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); - return UnimplementedFunction(ErrorModule::Kernel); - } + virtual ResultVal Acquire() = 0; /** * Add a thread to wait on this object -- cgit v1.2.3 From 15b6a4d9add6b260a2a1a84ab6228addced4f851 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 18:16:45 -0500 Subject: Kernel: Changed "ShouldWait" to return bool and "Acquire" to return void. --- src/core/hle/kernel/kernel.h | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 1bb0b55bd..c26726223 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -120,13 +120,10 @@ public: * Check if the current thread should wait until the object is available * @return True if the current thread should wait due to this object being unavailable */ - virtual ResultVal ShouldWait() = 0; + virtual bool ShouldWait() = 0; - /** - * Acquire/lock the object if it is available - * @return True if we were able to acquire this object, otherwise false - */ - virtual ResultVal Acquire() = 0; + /// Acquire/lock the object if it is available + virtual void Acquire() = 0; /** * Add a thread to wait on this object -- cgit v1.2.3 From f09806aed24b2f7de7d969cbfdb3b9d18ab90c61 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Jan 2015 18:20:47 -0500 Subject: Kernel: Renamed some functions for clarity. - ReleaseNextThread->WakeupNextThread - ReleaseAllWaitingThreads->WakeupAllWaitingThreads. --- src/core/hle/kernel/kernel.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core/hle/kernel/kernel.h') diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index c26726223..3828efbea 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -138,13 +138,13 @@ public: void RemoveWaitingThread(Thread* thead); /** - * Releases (and removes) the next thread waiting on this object + * Wake up the next thread waiting on this object * @return Pointer to the thread that was resumed, nullptr if no threads are waiting */ - Thread* ReleaseNextThread(); + Thread* WakeupNextThread(); - /// Releases all threads waiting on this object - void ReleaseAllWaitingThreads(); + /// Wake up all threads waiting on this object + void WakeupAllWaitingThreads(); private: std::vector waiting_threads; ///< Threads waiting for this object to become available -- cgit v1.2.3