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/event.cpp | 6 +++++- src/core/hle/kernel/kernel.h | 13 +++++++++++-- src/core/hle/kernel/mutex.cpp | 19 ++++++++++++++----- src/core/hle/kernel/semaphore.cpp | 15 ++++++++++++--- src/core/hle/kernel/thread.cpp | 6 +++++- src/core/hle/kernel/thread.h | 3 ++- src/core/hle/kernel/timer.cpp | 6 +++++- src/core/hle/svc.cpp | 9 +++++---- 8 files changed, 59 insertions(+), 18 deletions(-) diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp index 4173a980b..41e1bd6c5 100644 --- a/src/core/hle/kernel/event.cpp +++ b/src/core/hle/kernel/event.cpp @@ -28,7 +28,7 @@ public: bool signaled; ///< Whether the event has already been signaled std::string name; ///< Name of event (optional) - ResultVal WaitSynchronization(unsigned index) override { + ResultVal Wait(unsigned index) override { bool wait = !signaled; if (wait) { AddWaitingThread(GetCurrentThread()); @@ -36,6 +36,10 @@ public: } return MakeResult(wait); } + + ResultVal Acquire() override { + return MakeResult(true); + } }; ResultCode SignalEvent(const Handle handle) { 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); } diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 78063b8f1..37e7be4e7 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -26,7 +26,8 @@ public: Handle lock_thread; ///< Handle to thread that currently has mutex std::string name; ///< Name of mutex (optional) - ResultVal WaitSynchronization(unsigned index) override; + ResultVal Wait(unsigned index) override; + ResultVal Acquire() override; }; //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -155,17 +156,25 @@ Handle CreateMutex(bool initial_locked, const std::string& name) { return handle; } -ResultVal Mutex::WaitSynchronization(unsigned index) { - bool wait = locked; +ResultVal Mutex::Wait(unsigned index) { if (locked) { AddWaitingThread(GetCurrentThread()); Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_MUTEX, this, index); - } else { + } + + return MakeResult(locked); +} + +ResultVal Mutex::Acquire() { + bool res = false; + + if (!locked) { // Lock the mutex when the first thread accesses it locked = true; + res = true; MutexAcquireLock(this); } - return MakeResult(wait); + return MakeResult(res); } } // namespace diff --git a/src/core/hle/kernel/semaphore.cpp b/src/core/hle/kernel/semaphore.cpp index 288928441..6464b2580 100644 --- a/src/core/hle/kernel/semaphore.cpp +++ b/src/core/hle/kernel/semaphore.cpp @@ -32,18 +32,27 @@ public: return available_count > 0; } - ResultVal WaitSynchronization(unsigned index) override { + ResultVal Wait(unsigned index) override { bool wait = !IsAvailable(); if (wait) { Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_SEMA, this, index); AddWaitingThread(GetCurrentThread()); - } else { - --available_count; } return MakeResult(wait); } + + ResultVal Acquire() override { + bool res = false; + + if (IsAvailable()) { + --available_count; + res = true; + } + + return MakeResult(res); + } }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 0c9ecc091..6b0bdebb5 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -22,7 +22,7 @@ namespace Kernel { -ResultVal Thread::WaitSynchronization(unsigned index) { +ResultVal Thread::Wait(unsigned index) { const bool wait = status != THREADSTATUS_DORMANT; if (wait) { AddWaitingThread(GetCurrentThread()); @@ -32,6 +32,10 @@ ResultVal Thread::WaitSynchronization(unsigned index) { return MakeResult(wait); } +ResultVal Thread::Acquire() { + return MakeResult(true); +} + // Lists all thread ids that aren't deleted/etc. static std::vector> thread_list; diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index f3dc4eec0..9faf89c15 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -70,7 +70,8 @@ public: inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } inline bool IsIdle() const { return idle; } - ResultVal WaitSynchronization(unsigned index) override; + ResultVal Wait(unsigned index) override; + ResultVal Acquire() override; s32 GetPriority() const { return current_priority; } void SetPriority(s32 priority); diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index c97ae6c5c..6497bb349 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -29,7 +29,7 @@ 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 WaitSynchronization(unsigned index) override { + ResultVal Wait(unsigned index) override { bool wait = !signaled; if (wait) { AddWaitingThread(GetCurrentThread()); @@ -37,6 +37,10 @@ public: } return MakeResult(wait); } + + ResultVal Acquire() override { + return MakeResult(true); + } }; /** diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 23885f129..a27aa6269 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp @@ -127,7 +127,7 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); - ResultVal wait = object->WaitSynchronization(); + ResultVal wait = object->Wait(); // Check for next thread to schedule if (wait.Succeeded() && *wait) { @@ -137,6 +137,8 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { Kernel::GetCurrentThread()->SetWaitAll(false); HLE::Reschedule(__func__); + } else { + object->Acquire(); } return wait.Code().raw; @@ -163,15 +165,14 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, if (object == nullptr) return InvalidHandle(ErrorModule::Kernel).raw; - ResultVal wait = object->WaitSynchronization(handle_index); + ResultVal wait = object->Wait(handle_index); wait_thread = (wait.Succeeded() && *wait); // If this object waited and we are waiting on all objects to synchronize - if (wait_thread && wait_all) { + if (wait_thread && wait_all) // Enforce later on that this thread does not continue wait_all_succeeded = true; - } // If this object synchronized and we are not waiting on all objects to synchronize if (!wait_thread && !wait_all) -- cgit v1.2.3