diff options
| author | 2015-01-17 22:23:49 -0500 | |
|---|---|---|
| committer | 2015-01-21 19:10:24 -0500 | |
| commit | aa01c57ae9d73e41b65d37860ca6fbb91caba33a (patch) | |
| tree | 904936860b1e8319ec5edc3a1e0e6c2c12f01d9f /src | |
| parent | WaitSynchronizationN: Handle case where handles=nullptr. (diff) | |
| download | yuzu-aa01c57ae9d73e41b65d37860ca6fbb91caba33a.tar.gz yuzu-aa01c57ae9d73e41b65d37860ca6fbb91caba33a.tar.xz yuzu-aa01c57ae9d73e41b65d37860ca6fbb91caba33a.zip | |
Kernel: Separate WaitSynchronization into Wait and Acquire methods.
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/event.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.h | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/mutex.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/semaphore.cpp | 15 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 6 | ||||
| -rw-r--r-- | 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: | |||
| 28 | bool signaled; ///< Whether the event has already been signaled | 28 | bool signaled; ///< Whether the event has already been signaled |
| 29 | std::string name; ///< Name of event (optional) | 29 | std::string name; ///< Name of event (optional) |
| 30 | 30 | ||
| 31 | ResultVal<bool> WaitSynchronization(unsigned index) override { | 31 | ResultVal<bool> Wait(unsigned index) override { |
| 32 | bool wait = !signaled; | 32 | bool wait = !signaled; |
| 33 | if (wait) { | 33 | if (wait) { |
| 34 | AddWaitingThread(GetCurrentThread()); | 34 | AddWaitingThread(GetCurrentThread()); |
| @@ -36,6 +36,10 @@ public: | |||
| 36 | } | 36 | } |
| 37 | return MakeResult<bool>(wait); | 37 | return MakeResult<bool>(wait); |
| 38 | } | 38 | } |
| 39 | |||
| 40 | ResultVal<bool> Acquire() override { | ||
| 41 | return MakeResult<bool>(true); | ||
| 42 | } | ||
| 39 | }; | 43 | }; |
| 40 | 44 | ||
| 41 | ResultCode SignalEvent(const Handle handle) { | 45 | 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: | |||
| 65 | virtual Kernel::HandleType GetHandleType() const = 0; | 65 | virtual Kernel::HandleType GetHandleType() const = 0; |
| 66 | 66 | ||
| 67 | /** | 67 | /** |
| 68 | * Wait for kernel object to synchronize. | 68 | * Wait the current thread for kernel object to synchronize. |
| 69 | * @param index Index of wait object (only applies to WaitSynchronizationN) | 69 | * @param index Index of wait object (only applies to WaitSynchronizationN) |
| 70 | * @return True if the current thread should wait as a result of the wait | 70 | * @return True if the current thread should wait as a result of the wait |
| 71 | */ | 71 | */ |
| 72 | virtual ResultVal<bool> WaitSynchronization(unsigned index=0) { | 72 | virtual ResultVal<bool> Wait(unsigned index = 0) { |
| 73 | LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); | ||
| 74 | return UnimplementedFunction(ErrorModule::Kernel); | ||
| 75 | } | ||
| 76 | |||
| 77 | /** | ||
| 78 | * Acquire/lock the kernel object if it is available | ||
| 79 | * @return True if we were able to acquire the kernel object, otherwise false | ||
| 80 | */ | ||
| 81 | virtual ResultVal<bool> Acquire() { | ||
| 73 | LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); | 82 | LOG_ERROR(Kernel, "(UNIMPLEMENTED)"); |
| 74 | return UnimplementedFunction(ErrorModule::Kernel); | 83 | return UnimplementedFunction(ErrorModule::Kernel); |
| 75 | } | 84 | } |
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: | |||
| 26 | Handle lock_thread; ///< Handle to thread that currently has mutex | 26 | Handle lock_thread; ///< Handle to thread that currently has mutex |
| 27 | std::string name; ///< Name of mutex (optional) | 27 | std::string name; ///< Name of mutex (optional) |
| 28 | 28 | ||
| 29 | ResultVal<bool> WaitSynchronization(unsigned index) override; | 29 | ResultVal<bool> Wait(unsigned index) override; |
| 30 | ResultVal<bool> Acquire() override; | ||
| 30 | }; | 31 | }; |
| 31 | 32 | ||
| 32 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 33 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
| @@ -155,17 +156,25 @@ Handle CreateMutex(bool initial_locked, const std::string& name) { | |||
| 155 | return handle; | 156 | return handle; |
| 156 | } | 157 | } |
| 157 | 158 | ||
| 158 | ResultVal<bool> Mutex::WaitSynchronization(unsigned index) { | 159 | ResultVal<bool> Mutex::Wait(unsigned index) { |
| 159 | bool wait = locked; | ||
| 160 | if (locked) { | 160 | if (locked) { |
| 161 | AddWaitingThread(GetCurrentThread()); | 161 | AddWaitingThread(GetCurrentThread()); |
| 162 | Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_MUTEX, this, index); | 162 | Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_MUTEX, this, index); |
| 163 | } else { | 163 | } |
| 164 | |||
| 165 | return MakeResult<bool>(locked); | ||
| 166 | } | ||
| 167 | |||
| 168 | ResultVal<bool> Mutex::Acquire() { | ||
| 169 | bool res = false; | ||
| 170 | |||
| 171 | if (!locked) { | ||
| 164 | // Lock the mutex when the first thread accesses it | 172 | // Lock the mutex when the first thread accesses it |
| 165 | locked = true; | 173 | locked = true; |
| 174 | res = true; | ||
| 166 | MutexAcquireLock(this); | 175 | MutexAcquireLock(this); |
| 167 | } | 176 | } |
| 168 | 177 | ||
| 169 | return MakeResult<bool>(wait); | 178 | return MakeResult<bool>(res); |
| 170 | } | 179 | } |
| 171 | } // namespace | 180 | } // 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: | |||
| 32 | return available_count > 0; | 32 | return available_count > 0; |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | ResultVal<bool> WaitSynchronization(unsigned index) override { | 35 | ResultVal<bool> Wait(unsigned index) override { |
| 36 | bool wait = !IsAvailable(); | 36 | bool wait = !IsAvailable(); |
| 37 | 37 | ||
| 38 | if (wait) { | 38 | if (wait) { |
| 39 | Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_SEMA, this, index); | 39 | Kernel::WaitCurrentThread_WaitSynchronization(WAITTYPE_SEMA, this, index); |
| 40 | AddWaitingThread(GetCurrentThread()); | 40 | AddWaitingThread(GetCurrentThread()); |
| 41 | } else { | ||
| 42 | --available_count; | ||
| 43 | } | 41 | } |
| 44 | 42 | ||
| 45 | return MakeResult<bool>(wait); | 43 | return MakeResult<bool>(wait); |
| 46 | } | 44 | } |
| 45 | |||
| 46 | ResultVal<bool> Acquire() override { | ||
| 47 | bool res = false; | ||
| 48 | |||
| 49 | if (IsAvailable()) { | ||
| 50 | --available_count; | ||
| 51 | res = true; | ||
| 52 | } | ||
| 53 | |||
| 54 | return MakeResult<bool>(res); | ||
| 55 | } | ||
| 47 | }; | 56 | }; |
| 48 | 57 | ||
| 49 | //////////////////////////////////////////////////////////////////////////////////////////////////// | 58 | //////////////////////////////////////////////////////////////////////////////////////////////////// |
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 @@ | |||
| 22 | 22 | ||
| 23 | namespace Kernel { | 23 | namespace Kernel { |
| 24 | 24 | ||
| 25 | ResultVal<bool> Thread::WaitSynchronization(unsigned index) { | 25 | ResultVal<bool> Thread::Wait(unsigned index) { |
| 26 | const bool wait = status != THREADSTATUS_DORMANT; | 26 | const bool wait = status != THREADSTATUS_DORMANT; |
| 27 | if (wait) { | 27 | if (wait) { |
| 28 | AddWaitingThread(GetCurrentThread()); | 28 | AddWaitingThread(GetCurrentThread()); |
| @@ -32,6 +32,10 @@ ResultVal<bool> Thread::WaitSynchronization(unsigned index) { | |||
| 32 | return MakeResult<bool>(wait); | 32 | return MakeResult<bool>(wait); |
| 33 | } | 33 | } |
| 34 | 34 | ||
| 35 | ResultVal<bool> Thread::Acquire() { | ||
| 36 | return MakeResult<bool>(true); | ||
| 37 | } | ||
| 38 | |||
| 35 | // Lists all thread ids that aren't deleted/etc. | 39 | // Lists all thread ids that aren't deleted/etc. |
| 36 | static std::vector<SharedPtr<Thread>> thread_list; | 40 | static std::vector<SharedPtr<Thread>> thread_list; |
| 37 | 41 | ||
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: | |||
| 70 | inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } | 70 | inline bool IsSuspended() const { return (status & THREADSTATUS_SUSPEND) != 0; } |
| 71 | inline bool IsIdle() const { return idle; } | 71 | inline bool IsIdle() const { return idle; } |
| 72 | 72 | ||
| 73 | ResultVal<bool> WaitSynchronization(unsigned index) override; | 73 | ResultVal<bool> Wait(unsigned index) override; |
| 74 | ResultVal<bool> Acquire() override; | ||
| 74 | 75 | ||
| 75 | s32 GetPriority() const { return current_priority; } | 76 | s32 GetPriority() const { return current_priority; } |
| 76 | void SetPriority(s32 priority); | 77 | 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: | |||
| 29 | u64 initial_delay; ///< The delay until the timer fires for the first time | 29 | u64 initial_delay; ///< The delay until the timer fires for the first time |
| 30 | u64 interval_delay; ///< The delay until the timer fires after the first time | 30 | u64 interval_delay; ///< The delay until the timer fires after the first time |
| 31 | 31 | ||
| 32 | ResultVal<bool> WaitSynchronization(unsigned index) override { | 32 | ResultVal<bool> Wait(unsigned index) override { |
| 33 | bool wait = !signaled; | 33 | bool wait = !signaled; |
| 34 | if (wait) { | 34 | if (wait) { |
| 35 | AddWaitingThread(GetCurrentThread()); | 35 | AddWaitingThread(GetCurrentThread()); |
| @@ -37,6 +37,10 @@ public: | |||
| 37 | } | 37 | } |
| 38 | return MakeResult<bool>(wait); | 38 | return MakeResult<bool>(wait); |
| 39 | } | 39 | } |
| 40 | |||
| 41 | ResultVal<bool> Acquire() override { | ||
| 42 | return MakeResult<bool>(true); | ||
| 43 | } | ||
| 40 | }; | 44 | }; |
| 41 | 45 | ||
| 42 | /** | 46 | /** |
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) { | |||
| 127 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, | 127 | LOG_TRACE(Kernel_SVC, "called handle=0x%08X(%s:%s), nanoseconds=%lld", handle, |
| 128 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); | 128 | object->GetTypeName().c_str(), object->GetName().c_str(), nano_seconds); |
| 129 | 129 | ||
| 130 | ResultVal<bool> wait = object->WaitSynchronization(); | 130 | ResultVal<bool> wait = object->Wait(); |
| 131 | 131 | ||
| 132 | // Check for next thread to schedule | 132 | // Check for next thread to schedule |
| 133 | if (wait.Succeeded() && *wait) { | 133 | if (wait.Succeeded() && *wait) { |
| @@ -137,6 +137,8 @@ static Result WaitSynchronization1(Handle handle, s64 nano_seconds) { | |||
| 137 | Kernel::GetCurrentThread()->SetWaitAll(false); | 137 | Kernel::GetCurrentThread()->SetWaitAll(false); |
| 138 | 138 | ||
| 139 | HLE::Reschedule(__func__); | 139 | HLE::Reschedule(__func__); |
| 140 | } else { | ||
| 141 | object->Acquire(); | ||
| 140 | } | 142 | } |
| 141 | 143 | ||
| 142 | return wait.Code().raw; | 144 | return wait.Code().raw; |
| @@ -163,15 +165,14 @@ static Result WaitSynchronizationN(s32* out, Handle* handles, s32 handle_count, | |||
| 163 | if (object == nullptr) | 165 | if (object == nullptr) |
| 164 | return InvalidHandle(ErrorModule::Kernel).raw; | 166 | return InvalidHandle(ErrorModule::Kernel).raw; |
| 165 | 167 | ||
| 166 | ResultVal<bool> wait = object->WaitSynchronization(handle_index); | 168 | ResultVal<bool> wait = object->Wait(handle_index); |
| 167 | 169 | ||
| 168 | wait_thread = (wait.Succeeded() && *wait); | 170 | wait_thread = (wait.Succeeded() && *wait); |
| 169 | 171 | ||
| 170 | // If this object waited and we are waiting on all objects to synchronize | 172 | // If this object waited and we are waiting on all objects to synchronize |
| 171 | if (wait_thread && wait_all) { | 173 | if (wait_thread && wait_all) |
| 172 | // Enforce later on that this thread does not continue | 174 | // Enforce later on that this thread does not continue |
| 173 | wait_all_succeeded = true; | 175 | wait_all_succeeded = true; |
| 174 | } | ||
| 175 | 176 | ||
| 176 | // If this object synchronized and we are not waiting on all objects to synchronize | 177 | // If this object synchronized and we are not waiting on all objects to synchronize |
| 177 | if (!wait_thread && !wait_all) | 178 | if (!wait_thread && !wait_all) |