diff options
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 @@ #include <array> #include <string> +#include <vector> + #include "common/common.h" #include "core/hle/result.h" @@ -58,17 +60,35 @@ 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; /** - * Wait for kernel object to synchronize. - * @return True if the current thread should wait as a result of the wait + * Check if a thread can wait on the object + * @return True if a thread can wait on the object, otherwise false */ - virtual ResultVal<bool> WaitSynchronization() { - LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); - return UnimplementedFunction(ErrorModule::Kernel); + bool IsWaitable() const { + switch (GetHandleType()) { + case HandleType::Session: + 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; + } + + return false; } private: @@ -92,6 +112,44 @@ inline void intrusive_ptr_release(Object* object) { template <typename T> using SharedPtr = boost::intrusive_ptr<T>; +/// Class that represents a Kernel object that a thread can be waiting on +class WaitObject : public Object { +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 bool ShouldWait() = 0; + + /// Acquire/lock the object if it is available + virtual void Acquire() = 0; + + /** + * Add a thread to wait on this object + * @param thread Pointer to thread to add + */ + void AddWaitingThread(Thread* thread); + + /** + * 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); + + /** + * Wake up the next thread waiting on this object + * @return Pointer to the thread that was resumed, nullptr if no threads are waiting + */ + Thread* WakeupNextThread(); + + /// Wake up all threads waiting on this object + void WakeupAllWaitingThreads(); + +private: + std::vector<Thread*> 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 @@ -146,14 +204,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<Object> 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 <class T> SharedPtr<T> Get(Handle handle) const { @@ -164,6 +222,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<WaitObject> GetWaitObject(Handle handle) const { + SharedPtr<Object> object = GetGeneric(handle); + if (object != nullptr && object->IsWaitable()) { + return boost::static_pointer_cast<WaitObject>(std::move(object)); + } + return nullptr; + } + /// Closes all handles held in this table. void Clear(); |