diff options
author | bunnei <bunneidev@gmail.com> | 2015-01-18 07:27:46 +0100 |
---|---|---|
committer | bunnei <bunneidev@gmail.com> | 2015-01-22 01:11:47 +0100 |
commit | 6643673f28b9273149fc945849a13ed832e9ef33 (patch) | |
tree | 026410cf5b0b57d350ac979380307991646e546c /src/core/hle/kernel | |
parent | Kernel: Separate WaitSynchronization into Wait and Acquire methods. (diff) | |
download | yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar.gz yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar.bz2 yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar.lz yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar.xz yuzu-6643673f28b9273149fc945849a13ed832e9ef33.tar.zst yuzu-6643673f28b9273149fc945849a13ed832e9ef33.zip |
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/kernel/event.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/kernel.h | 12 | ||||
-rw-r--r-- | src/core/hle/kernel/mutex.cpp | 8 | ||||
-rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 6 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.cpp | 61 | ||||
-rw-r--r-- | src/core/hle/kernel/thread.h | 4 | ||||
-rw-r--r-- | src/core/hle/kernel/timer.cpp | 6 |
7 files changed, 49 insertions, 54 deletions
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 41e1bd6c5..ae9b06b84 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,11 +28,11 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal<bool> Wait(unsigned index) override { + ResultVal<bool> Wait(bool wait_thread) override { bool wait = !signaled; - if (wait) { + if (wait && wait_thread) { AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this, index); + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_EVENT, this); } return MakeResult<bool>(wait); } 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<bool> Wait(unsigned index = 0) { + virtual ResultVal<bool> 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<bool> Acquire() { LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 37e7be4e7..f97c69a78 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -26,7 +26,7 @@ public: Handle lock_thread; ///< Handle to thread that currently has mutex std::string name; ///< Name of mutex (optional) - ResultVal<bool> Wait(unsigned index) override; + ResultVal<bool> Wait(bool wait_thread) override; ResultVal<bool> Acquire() override; }; @@ -156,10 +156,10 @@ Handle CreateMutex(bool initial_locked, const std::string& name) { return handle; } -ResultVal<bool> Mutex::Wait(unsigned index) { - if (locked) { +ResultVal<bool> Mutex::Wait(bool wait_thread) { + if (locked && wait_thread) { AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_MUTEX, this, index); + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_MUTEX, this); } return MakeResult<bool>(locked); diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 6464b2580..42b5cf704 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -32,11 +32,11 @@ public: return available_count > 0; } - ResultVal<bool> Wait(unsigned index) override { + ResultVal<bool> Wait(bool wait_thread) override { bool wait = !IsAvailable(); - if (wait) { - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_SEMA, this, index); + if (wait && wait_thread) { + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_SEMA, this); AddWaitingThread(GetCurrentThread()); } diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 6b0bdebb5..62b85f56a 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -22,11 +22,11 @@ namespace Kernel { -ResultVal<bool> Thread::Wait(unsigned index) { +ResultVal<bool> Thread::Wait(bool wait_thread) { const bool wait = status != THREADSTATUS_DORMANT; - if (wait) { + if (wait && wait_thread) { AddWaitingThread(GetCurrentThread()); - WaitCurrentThread_WaitSynchronization(WAITTYPE_THREADEND, this, index); + WaitCurrentThread_WaitSynchronization(WAITTYPE_THREADEND, this); } return MakeResult<bool>(wait); @@ -97,7 +97,7 @@ static bool CheckWaitType(const Thread* thread, WaitType type) { /// Check if a thread is blocking on a specified wait type with a specified handle static bool CheckWaitType(const Thread* thread, WaitType type, Object* wait_object) { for (auto itr = thread->wait_objects.begin(); itr != thread->wait_objects.end(); ++itr) { - if (itr->first == wait_object) + if (*itr == wait_object) return CheckWaitType(thread, type); } return false; @@ -234,16 +234,7 @@ void WaitCurrentThread_WaitSynchronization(WaitType wait_type, WaitObject* wait_ Thread* thread = GetCurrentThread(); thread->wait_type = wait_type; - bool insert_wait_object = true; - for (auto itr = thread->wait_objects.begin(); itr < thread->wait_objects.end(); ++itr) { - if (itr->first == wait_object) { - insert_wait_object = false; - break; - } - } - - if (insert_wait_object) - thread->wait_objects.push_back(std::pair<SharedPtr<WaitObject>, unsigned>(wait_object, index)); + thread->wait_objects.push_back(wait_object); ChangeThreadState(thread, ThreadStatus(THREADSTATUS_WAIT | (thread->status & THREADSTATUS_SUSPEND))); } @@ -288,31 +279,35 @@ void Thread::ReleaseFromWait(WaitObject* wait_object) { return; } - // Remove this thread from the wait_object + // Remove this thread from the waiting object's thread list wait_object->RemoveWaitingThread(this); - // Find the waiting object - auto itr = wait_objects.begin(); - for (; itr != wait_objects.end(); ++itr) { - if (wait_object == itr->first) - break; - } - unsigned index = itr->second; + unsigned index = 0; + bool wait_all_failed = false; // Will be set to true if any object is unavailable - // Remove the wait_object from this thread - if (itr != wait_objects.end()) - wait_objects.erase(itr); + // Iterate through all waiting objects to check availability... + for (auto itr = wait_objects.begin(); itr != wait_objects.end(); ++itr) { + auto res = (*itr)->Wait(false); - // If wait_all=false, resume the thread on a release wait_object from wait - if (!wait_all) { - SetReturnValue(RESULT_SUCCESS, index); - ResumeFromWait(); - } else { - // Otherwise, wait_all=true, only resume the thread if all wait_object's have been released - if (wait_objects.empty()) { + if (*res && res.Succeeded()) + wait_all_failed = true; + + // The output should be the last index of wait_object + if (*itr == wait_object) + index = itr - wait_objects.begin(); + } + + // If we are waiting on all objects... + if (wait_all) { + // Resume the thread only if all are available... + if (!wait_all_failed) { SetReturnValue(RESULT_SUCCESS, -1); ResumeFromWait(); } + } else { + // Otherwise, resume + SetReturnValue(RESULT_SUCCESS, index); + ResumeFromWait(); } } @@ -324,7 +319,7 @@ void Thread::ResumeFromWait() { // Remove this thread from all other WaitObjects for (auto wait_object : wait_objects) - wait_object.first->RemoveWaitingThread(this); + wait_object->RemoveWaitingThread(this); wait_objects.clear(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9faf89c15..dff6bbaec 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -70,7 +70,7 @@ public: inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } inline bool IsIdle() const { return idle; } - ResultVal<bool> Wait(unsigned index) override; + ResultVal<bool> Wait(bool wait_thread) override; ResultVal<bool> Acquire() override; s32 GetPriority() const { return current_priority; } @@ -117,7 +117,7 @@ public: s32 processor_id; WaitType wait_type; - std::vector<std::pair<SharedPtr<WaitObject>, unsigned>> wait_objects; + std::vector<SharedPtr<WaitObject>> wait_objects; VAddr wait_address; std::string name; diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 6497bb349..9f0fbafe2 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -29,11 +29,11 @@ public: u64 initial_delay; ///< The delay until the timer fires for the first time u64 interval_delay; ///< The delay until the timer fires after the first time - ResultVal<bool> Wait(unsigned index) override { + ResultVal<bool> Wait(bool wait_thread) override { bool wait = !signaled; - if (wait) { + if (wait && wait_thread) { AddWaitingThread(GetCurrentThread()); - Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_TIMER, this, index); + Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_TIMER, this); } return MakeResult<bool>(wait); } |