diff options
| author | 2023-03-06 20:53:58 -0500 | |
|---|---|---|
| committer | 2023-03-12 22:06:53 -0400 | |
| commit | fdf90c6d75c68c4ff1bebbc0ece30d2a507d007d (patch) | |
| tree | cb45b6cd4f5471d09f3b0be6c9221aee372b3f5b /src | |
| parent | kernel: convert KPort, KSession (diff) | |
| download | yuzu-fdf90c6d75c68c4ff1bebbc0ece30d2a507d007d.tar.gz yuzu-fdf90c6d75c68c4ff1bebbc0ece30d2a507d007d.tar.xz yuzu-fdf90c6d75c68c4ff1bebbc0ece30d2a507d007d.zip | |
kernel: convert KConditionVariable, KLightConditionVariable, KLightLock
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_code_memory.cpp | 10 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.cpp | 65 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_condition_variable.h | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_light_condition_variable.cpp | 16 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_light_condition_variable.h | 6 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_light_lock.cpp | 31 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_light_lock.h | 8 |
7 files changed, 77 insertions, 75 deletions
diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp index 6c44a9e99..4167ade2b 100644 --- a/src/core/hle/kernel/k_code_memory.cpp +++ b/src/core/hle/kernel/k_code_memory.cpp | |||
| @@ -45,7 +45,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, VAddr addr, si | |||
| 45 | m_is_mapped = false; | 45 | m_is_mapped = false; |
| 46 | 46 | ||
| 47 | // We succeeded. | 47 | // We succeeded. |
| 48 | return ResultSuccess; | 48 | R_SUCCEED(); |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | void KCodeMemory::Finalize() { | 51 | void KCodeMemory::Finalize() { |
| @@ -80,7 +80,7 @@ Result KCodeMemory::Map(VAddr address, size_t size) { | |||
| 80 | // Mark ourselves as mapped. | 80 | // Mark ourselves as mapped. |
| 81 | m_is_mapped = true; | 81 | m_is_mapped = true; |
| 82 | 82 | ||
| 83 | return ResultSuccess; | 83 | R_SUCCEED(); |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | Result KCodeMemory::Unmap(VAddr address, size_t size) { | 86 | Result KCodeMemory::Unmap(VAddr address, size_t size) { |
| @@ -97,7 +97,7 @@ Result KCodeMemory::Unmap(VAddr address, size_t size) { | |||
| 97 | // Mark ourselves as unmapped. | 97 | // Mark ourselves as unmapped. |
| 98 | m_is_mapped = false; | 98 | m_is_mapped = false; |
| 99 | 99 | ||
| 100 | return ResultSuccess; | 100 | R_SUCCEED(); |
| 101 | } | 101 | } |
| 102 | 102 | ||
| 103 | Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { | 103 | Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission perm) { |
| @@ -131,7 +131,7 @@ Result KCodeMemory::MapToOwner(VAddr address, size_t size, Svc::MemoryPermission | |||
| 131 | // Mark ourselves as mapped. | 131 | // Mark ourselves as mapped. |
| 132 | m_is_owner_mapped = true; | 132 | m_is_owner_mapped = true; |
| 133 | 133 | ||
| 134 | return ResultSuccess; | 134 | R_SUCCEED(); |
| 135 | } | 135 | } |
| 136 | 136 | ||
| 137 | Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { | 137 | Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { |
| @@ -147,7 +147,7 @@ Result KCodeMemory::UnmapFromOwner(VAddr address, size_t size) { | |||
| 147 | // Mark ourselves as unmapped. | 147 | // Mark ourselves as unmapped. |
| 148 | m_is_owner_mapped = false; | 148 | m_is_owner_mapped = false; |
| 149 | 149 | ||
| 150 | return ResultSuccess; | 150 | R_SUCCEED(); |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | } // namespace Kernel | 153 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 458f4c94e..b75957688 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp | |||
| @@ -98,17 +98,17 @@ public: | |||
| 98 | 98 | ||
| 99 | } // namespace | 99 | } // namespace |
| 100 | 100 | ||
| 101 | KConditionVariable::KConditionVariable(Core::System& system_) | 101 | KConditionVariable::KConditionVariable(Core::System& system) |
| 102 | : system{system_}, kernel{system.Kernel()} {} | 102 | : m_system{system}, m_kernel{system.Kernel()} {} |
| 103 | 103 | ||
| 104 | KConditionVariable::~KConditionVariable() = default; | 104 | KConditionVariable::~KConditionVariable() = default; |
| 105 | 105 | ||
| 106 | Result KConditionVariable::SignalToAddress(VAddr addr) { | 106 | Result KConditionVariable::SignalToAddress(VAddr addr) { |
| 107 | KThread* owner_thread = GetCurrentThreadPointer(kernel); | 107 | KThread* owner_thread = GetCurrentThreadPointer(m_kernel); |
| 108 | 108 | ||
| 109 | // Signal the address. | 109 | // Signal the address. |
| 110 | { | 110 | { |
| 111 | KScopedSchedulerLock sl(kernel); | 111 | KScopedSchedulerLock sl(m_kernel); |
| 112 | 112 | ||
| 113 | // Remove waiter thread. | 113 | // Remove waiter thread. |
| 114 | bool has_waiters{}; | 114 | bool has_waiters{}; |
| @@ -129,7 +129,7 @@ Result KConditionVariable::SignalToAddress(VAddr addr) { | |||
| 129 | 129 | ||
| 130 | // Write the value to userspace. | 130 | // Write the value to userspace. |
| 131 | Result result{ResultSuccess}; | 131 | Result result{ResultSuccess}; |
| 132 | if (WriteToUser(system, addr, std::addressof(next_value))) [[likely]] { | 132 | if (WriteToUser(m_system, addr, std::addressof(next_value))) [[likely]] { |
| 133 | result = ResultSuccess; | 133 | result = ResultSuccess; |
| 134 | } else { | 134 | } else { |
| 135 | result = ResultInvalidCurrentMemory; | 135 | result = ResultInvalidCurrentMemory; |
| @@ -145,26 +145,27 @@ Result KConditionVariable::SignalToAddress(VAddr addr) { | |||
| 145 | } | 145 | } |
| 146 | 146 | ||
| 147 | Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { | 147 | Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) { |
| 148 | KThread* cur_thread = GetCurrentThreadPointer(kernel); | 148 | KThread* cur_thread = GetCurrentThreadPointer(m_kernel); |
| 149 | ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel); | 149 | ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(m_kernel); |
| 150 | 150 | ||
| 151 | // Wait for the address. | 151 | // Wait for the address. |
| 152 | KThread* owner_thread{}; | 152 | KThread* owner_thread{}; |
| 153 | { | 153 | { |
| 154 | KScopedSchedulerLock sl(kernel); | 154 | KScopedSchedulerLock sl(m_kernel); |
| 155 | 155 | ||
| 156 | // Check if the thread should terminate. | 156 | // Check if the thread should terminate. |
| 157 | R_UNLESS(!cur_thread->IsTerminationRequested(), ResultTerminationRequested); | 157 | R_UNLESS(!cur_thread->IsTerminationRequested(), ResultTerminationRequested); |
| 158 | 158 | ||
| 159 | // Read the tag from userspace. | 159 | // Read the tag from userspace. |
| 160 | u32 test_tag{}; | 160 | u32 test_tag{}; |
| 161 | R_UNLESS(ReadFromUser(system, std::addressof(test_tag), addr), ResultInvalidCurrentMemory); | 161 | R_UNLESS(ReadFromUser(m_system, std::addressof(test_tag), addr), |
| 162 | ResultInvalidCurrentMemory); | ||
| 162 | 163 | ||
| 163 | // If the tag isn't the handle (with wait mask), we're done. | 164 | // If the tag isn't the handle (with wait mask), we're done. |
| 164 | R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask)); | 165 | R_SUCCEED_IF(test_tag != (handle | Svc::HandleWaitMask)); |
| 165 | 166 | ||
| 166 | // Get the lock owner thread. | 167 | // Get the lock owner thread. |
| 167 | owner_thread = GetCurrentProcess(kernel) | 168 | owner_thread = GetCurrentProcess(m_kernel) |
| 168 | .GetHandleTable() | 169 | .GetHandleTable() |
| 169 | .GetObjectWithoutPseudoHandle<KThread>(handle) | 170 | .GetObjectWithoutPseudoHandle<KThread>(handle) |
| 170 | .ReleasePointerUnsafe(); | 171 | .ReleasePointerUnsafe(); |
| @@ -184,12 +185,12 @@ Result KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 value) | |||
| 184 | owner_thread->Close(); | 185 | owner_thread->Close(); |
| 185 | 186 | ||
| 186 | // Get the wait result. | 187 | // Get the wait result. |
| 187 | return cur_thread->GetWaitResult(); | 188 | R_RETURN(cur_thread->GetWaitResult()); |
| 188 | } | 189 | } |
| 189 | 190 | ||
| 190 | void KConditionVariable::SignalImpl(KThread* thread) { | 191 | void KConditionVariable::SignalImpl(KThread* thread) { |
| 191 | // Check pre-conditions. | 192 | // Check pre-conditions. |
| 192 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | 193 | ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); |
| 193 | 194 | ||
| 194 | // Update the tag. | 195 | // Update the tag. |
| 195 | VAddr address = thread->GetAddressKey(); | 196 | VAddr address = thread->GetAddressKey(); |
| @@ -204,7 +205,7 @@ void KConditionVariable::SignalImpl(KThread* thread) { | |||
| 204 | // TODO(bunnei): We should call CanAccessAtomic(..) here. | 205 | // TODO(bunnei): We should call CanAccessAtomic(..) here. |
| 205 | can_access = true; | 206 | can_access = true; |
| 206 | if (can_access) [[likely]] { | 207 | if (can_access) [[likely]] { |
| 207 | UpdateLockAtomic(system, std::addressof(prev_tag), address, own_tag, | 208 | UpdateLockAtomic(m_system, std::addressof(prev_tag), address, own_tag, |
| 208 | Svc::HandleWaitMask); | 209 | Svc::HandleWaitMask); |
| 209 | } | 210 | } |
| 210 | } | 211 | } |
| @@ -215,7 +216,7 @@ void KConditionVariable::SignalImpl(KThread* thread) { | |||
| 215 | thread->EndWait(ResultSuccess); | 216 | thread->EndWait(ResultSuccess); |
| 216 | } else { | 217 | } else { |
| 217 | // Get the previous owner. | 218 | // Get the previous owner. |
| 218 | KThread* owner_thread = GetCurrentProcess(kernel) | 219 | KThread* owner_thread = GetCurrentProcess(m_kernel) |
| 219 | .GetHandleTable() | 220 | .GetHandleTable() |
| 220 | .GetObjectWithoutPseudoHandle<KThread>( | 221 | .GetObjectWithoutPseudoHandle<KThread>( |
| 221 | static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask)) | 222 | static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask)) |
| @@ -240,14 +241,14 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { | |||
| 240 | // Perform signaling. | 241 | // Perform signaling. |
| 241 | s32 num_waiters{}; | 242 | s32 num_waiters{}; |
| 242 | { | 243 | { |
| 243 | KScopedSchedulerLock sl(kernel); | 244 | KScopedSchedulerLock sl(m_kernel); |
| 244 | 245 | ||
| 245 | auto it = thread_tree.nfind_key({cv_key, -1}); | 246 | auto it = m_tree.nfind_key({cv_key, -1}); |
| 246 | while ((it != thread_tree.end()) && (count <= 0 || num_waiters < count) && | 247 | while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && |
| 247 | (it->GetConditionVariableKey() == cv_key)) { | 248 | (it->GetConditionVariableKey() == cv_key)) { |
| 248 | KThread* target_thread = std::addressof(*it); | 249 | KThread* target_thread = std::addressof(*it); |
| 249 | 250 | ||
| 250 | it = thread_tree.erase(it); | 251 | it = m_tree.erase(it); |
| 251 | target_thread->ClearConditionVariable(); | 252 | target_thread->ClearConditionVariable(); |
| 252 | 253 | ||
| 253 | this->SignalImpl(target_thread); | 254 | this->SignalImpl(target_thread); |
| @@ -256,27 +257,27 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { | |||
| 256 | } | 257 | } |
| 257 | 258 | ||
| 258 | // If we have no waiters, clear the has waiter flag. | 259 | // If we have no waiters, clear the has waiter flag. |
| 259 | if (it == thread_tree.end() || it->GetConditionVariableKey() != cv_key) { | 260 | if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) { |
| 260 | const u32 has_waiter_flag{}; | 261 | const u32 has_waiter_flag{}; |
| 261 | WriteToUser(system, cv_key, std::addressof(has_waiter_flag)); | 262 | WriteToUser(m_system, cv_key, std::addressof(has_waiter_flag)); |
| 262 | } | 263 | } |
| 263 | } | 264 | } |
| 264 | } | 265 | } |
| 265 | 266 | ||
| 266 | Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { | 267 | Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { |
| 267 | // Prepare to wait. | 268 | // Prepare to wait. |
| 268 | KThread* cur_thread = GetCurrentThreadPointer(kernel); | 269 | KThread* cur_thread = GetCurrentThreadPointer(m_kernel); |
| 269 | KHardwareTimer* timer{}; | 270 | KHardwareTimer* timer{}; |
| 270 | ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue( | 271 | ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue(m_kernel, |
| 271 | kernel, std::addressof(thread_tree)); | 272 | std::addressof(m_tree)); |
| 272 | 273 | ||
| 273 | { | 274 | { |
| 274 | KScopedSchedulerLockAndSleep slp(kernel, std::addressof(timer), cur_thread, timeout); | 275 | KScopedSchedulerLockAndSleep slp(m_kernel, std::addressof(timer), cur_thread, timeout); |
| 275 | 276 | ||
| 276 | // Check that the thread isn't terminating. | 277 | // Check that the thread isn't terminating. |
| 277 | if (cur_thread->IsTerminationRequested()) { | 278 | if (cur_thread->IsTerminationRequested()) { |
| 278 | slp.CancelSleep(); | 279 | slp.CancelSleep(); |
| 279 | return ResultTerminationRequested; | 280 | R_THROW(ResultTerminationRequested); |
| 280 | } | 281 | } |
| 281 | 282 | ||
| 282 | // Update the value and process for the next owner. | 283 | // Update the value and process for the next owner. |
| @@ -302,14 +303,14 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { | |||
| 302 | // Write to the cv key. | 303 | // Write to the cv key. |
| 303 | { | 304 | { |
| 304 | const u32 has_waiter_flag = 1; | 305 | const u32 has_waiter_flag = 1; |
| 305 | WriteToUser(system, key, std::addressof(has_waiter_flag)); | 306 | WriteToUser(m_system, key, std::addressof(has_waiter_flag)); |
| 306 | // TODO(bunnei): We should call DataMemoryBarrier(..) here. | 307 | std::atomic_thread_fence(std::memory_order_seq_cst); |
| 307 | } | 308 | } |
| 308 | 309 | ||
| 309 | // Write the value to userspace. | 310 | // Write the value to userspace. |
| 310 | if (!WriteToUser(system, addr, std::addressof(next_value))) { | 311 | if (!WriteToUser(m_system, addr, std::addressof(next_value))) { |
| 311 | slp.CancelSleep(); | 312 | slp.CancelSleep(); |
| 312 | return ResultInvalidCurrentMemory; | 313 | R_THROW(ResultInvalidCurrentMemory); |
| 313 | } | 314 | } |
| 314 | } | 315 | } |
| 315 | 316 | ||
| @@ -317,8 +318,8 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { | |||
| 317 | R_UNLESS(timeout != 0, ResultTimedOut); | 318 | R_UNLESS(timeout != 0, ResultTimedOut); |
| 318 | 319 | ||
| 319 | // Update condition variable tracking. | 320 | // Update condition variable tracking. |
| 320 | cur_thread->SetConditionVariable(std::addressof(thread_tree), addr, key, value); | 321 | cur_thread->SetConditionVariable(std::addressof(m_tree), addr, key, value); |
| 321 | thread_tree.insert(*cur_thread); | 322 | m_tree.insert(*cur_thread); |
| 322 | 323 | ||
| 323 | // Begin waiting. | 324 | // Begin waiting. |
| 324 | wait_queue.SetHardwareTimer(timer); | 325 | wait_queue.SetHardwareTimer(timer); |
| @@ -328,7 +329,7 @@ Result KConditionVariable::Wait(VAddr addr, u64 key, u32 value, s64 timeout) { | |||
| 328 | } | 329 | } |
| 329 | 330 | ||
| 330 | // Get the wait result. | 331 | // Get the wait result. |
| 331 | return cur_thread->GetWaitResult(); | 332 | R_RETURN(cur_thread->GetWaitResult()); |
| 332 | } | 333 | } |
| 333 | 334 | ||
| 334 | } // namespace Kernel | 335 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_condition_variable.h b/src/core/hle/kernel/k_condition_variable.h index fad4ed011..41635a894 100644 --- a/src/core/hle/kernel/k_condition_variable.h +++ b/src/core/hle/kernel/k_condition_variable.h | |||
| @@ -21,24 +21,24 @@ class KConditionVariable { | |||
| 21 | public: | 21 | public: |
| 22 | using ThreadTree = typename KThread::ConditionVariableThreadTreeType; | 22 | using ThreadTree = typename KThread::ConditionVariableThreadTreeType; |
| 23 | 23 | ||
| 24 | explicit KConditionVariable(Core::System& system_); | 24 | explicit KConditionVariable(Core::System& system); |
| 25 | ~KConditionVariable(); | 25 | ~KConditionVariable(); |
| 26 | 26 | ||
| 27 | // Arbitration | 27 | // Arbitration |
| 28 | [[nodiscard]] Result SignalToAddress(VAddr addr); | 28 | Result SignalToAddress(VAddr addr); |
| 29 | [[nodiscard]] Result WaitForAddress(Handle handle, VAddr addr, u32 value); | 29 | Result WaitForAddress(Handle handle, VAddr addr, u32 value); |
| 30 | 30 | ||
| 31 | // Condition variable | 31 | // Condition variable |
| 32 | void Signal(u64 cv_key, s32 count); | 32 | void Signal(u64 cv_key, s32 count); |
| 33 | [[nodiscard]] Result Wait(VAddr addr, u64 key, u32 value, s64 timeout); | 33 | Result Wait(VAddr addr, u64 key, u32 value, s64 timeout); |
| 34 | 34 | ||
| 35 | private: | 35 | private: |
| 36 | void SignalImpl(KThread* thread); | 36 | void SignalImpl(KThread* thread); |
| 37 | 37 | ||
| 38 | ThreadTree thread_tree; | 38 | private: |
| 39 | 39 | Core::System& m_system; | |
| 40 | Core::System& system; | 40 | KernelCore& m_kernel; |
| 41 | KernelCore& kernel; | 41 | ThreadTree m_tree{}; |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| 44 | inline void BeforeUpdatePriority(const KernelCore& kernel, KConditionVariable::ThreadTree* tree, | 44 | inline void BeforeUpdatePriority(const KernelCore& kernel, KConditionVariable::ThreadTree* tree, |
diff --git a/src/core/hle/kernel/k_light_condition_variable.cpp b/src/core/hle/kernel/k_light_condition_variable.cpp index 8fce2bc71..6d5a815aa 100644 --- a/src/core/hle/kernel/k_light_condition_variable.cpp +++ b/src/core/hle/kernel/k_light_condition_variable.cpp | |||
| @@ -13,9 +13,9 @@ namespace { | |||
| 13 | 13 | ||
| 14 | class ThreadQueueImplForKLightConditionVariable final : public KThreadQueue { | 14 | class ThreadQueueImplForKLightConditionVariable final : public KThreadQueue { |
| 15 | public: | 15 | public: |
| 16 | ThreadQueueImplForKLightConditionVariable(KernelCore& kernel_, KThread::WaiterList* wl, | 16 | ThreadQueueImplForKLightConditionVariable(KernelCore& kernel, KThread::WaiterList* wl, |
| 17 | bool term) | 17 | bool term) |
| 18 | : KThreadQueue(kernel_), m_wait_list(wl), m_allow_terminating_thread(term) {} | 18 | : KThreadQueue(kernel), m_wait_list(wl), m_allow_terminating_thread(term) {} |
| 19 | 19 | ||
| 20 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { | 20 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 21 | // Only process waits if we're allowed to. | 21 | // Only process waits if we're allowed to. |
| @@ -39,15 +39,15 @@ private: | |||
| 39 | 39 | ||
| 40 | void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_terminating_thread) { | 40 | void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_terminating_thread) { |
| 41 | // Create thread queue. | 41 | // Create thread queue. |
| 42 | KThread* owner = GetCurrentThreadPointer(kernel); | 42 | KThread* owner = GetCurrentThreadPointer(m_kernel); |
| 43 | KHardwareTimer* timer{}; | 43 | KHardwareTimer* timer{}; |
| 44 | 44 | ||
| 45 | ThreadQueueImplForKLightConditionVariable wait_queue(kernel, std::addressof(wait_list), | 45 | ThreadQueueImplForKLightConditionVariable wait_queue(m_kernel, std::addressof(m_wait_list), |
| 46 | allow_terminating_thread); | 46 | allow_terminating_thread); |
| 47 | 47 | ||
| 48 | // Sleep the thread. | 48 | // Sleep the thread. |
| 49 | { | 49 | { |
| 50 | KScopedSchedulerLockAndSleep lk(kernel, std::addressof(timer), owner, timeout); | 50 | KScopedSchedulerLockAndSleep lk(m_kernel, std::addressof(timer), owner, timeout); |
| 51 | 51 | ||
| 52 | if (!allow_terminating_thread && owner->IsTerminationRequested()) { | 52 | if (!allow_terminating_thread && owner->IsTerminationRequested()) { |
| 53 | lk.CancelSleep(); | 53 | lk.CancelSleep(); |
| @@ -57,7 +57,7 @@ void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_ter | |||
| 57 | lock->Unlock(); | 57 | lock->Unlock(); |
| 58 | 58 | ||
| 59 | // Add the thread to the queue. | 59 | // Add the thread to the queue. |
| 60 | wait_list.push_back(*owner); | 60 | m_wait_list.push_back(*owner); |
| 61 | 61 | ||
| 62 | // Begin waiting. | 62 | // Begin waiting. |
| 63 | wait_queue.SetHardwareTimer(timer); | 63 | wait_queue.SetHardwareTimer(timer); |
| @@ -69,10 +69,10 @@ void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_ter | |||
| 69 | } | 69 | } |
| 70 | 70 | ||
| 71 | void KLightConditionVariable::Broadcast() { | 71 | void KLightConditionVariable::Broadcast() { |
| 72 | KScopedSchedulerLock lk(kernel); | 72 | KScopedSchedulerLock lk(m_kernel); |
| 73 | 73 | ||
| 74 | // Signal all threads. | 74 | // Signal all threads. |
| 75 | for (auto it = wait_list.begin(); it != wait_list.end(); it = wait_list.erase(it)) { | 75 | for (auto it = m_wait_list.begin(); it != m_wait_list.end(); it = m_wait_list.erase(it)) { |
| 76 | it->EndWait(ResultSuccess); | 76 | it->EndWait(ResultSuccess); |
| 77 | } | 77 | } |
| 78 | } | 78 | } |
diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h index 3cabd6b4f..ab612426d 100644 --- a/src/core/hle/kernel/k_light_condition_variable.h +++ b/src/core/hle/kernel/k_light_condition_variable.h | |||
| @@ -13,13 +13,13 @@ class KLightLock; | |||
| 13 | 13 | ||
| 14 | class KLightConditionVariable { | 14 | class KLightConditionVariable { |
| 15 | public: | 15 | public: |
| 16 | explicit KLightConditionVariable(KernelCore& kernel_) : kernel{kernel_} {} | 16 | explicit KLightConditionVariable(KernelCore& kernel) : m_kernel{kernel} {} |
| 17 | 17 | ||
| 18 | void Wait(KLightLock* lock, s64 timeout = -1, bool allow_terminating_thread = true); | 18 | void Wait(KLightLock* lock, s64 timeout = -1, bool allow_terminating_thread = true); |
| 19 | void Broadcast(); | 19 | void Broadcast(); |
| 20 | 20 | ||
| 21 | private: | 21 | private: |
| 22 | KernelCore& kernel; | 22 | KernelCore& m_kernel; |
| 23 | KThread::WaiterList wait_list{}; | 23 | KThread::WaiterList m_wait_list{}; |
| 24 | }; | 24 | }; |
| 25 | } // namespace Kernel | 25 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp index 14cb615da..e87ee8b65 100644 --- a/src/core/hle/kernel/k_light_lock.cpp +++ b/src/core/hle/kernel/k_light_lock.cpp | |||
| @@ -13,7 +13,7 @@ namespace { | |||
| 13 | 13 | ||
| 14 | class ThreadQueueImplForKLightLock final : public KThreadQueue { | 14 | class ThreadQueueImplForKLightLock final : public KThreadQueue { |
| 15 | public: | 15 | public: |
| 16 | explicit ThreadQueueImplForKLightLock(KernelCore& kernel_) : KThreadQueue(kernel_) {} | 16 | explicit ThreadQueueImplForKLightLock(KernelCore& kernel) : KThreadQueue(kernel) {} |
| 17 | 17 | ||
| 18 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { | 18 | void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { |
| 19 | // Remove the thread as a waiter from its owner. | 19 | // Remove the thread as a waiter from its owner. |
| @@ -29,13 +29,13 @@ public: | |||
| 29 | } // namespace | 29 | } // namespace |
| 30 | 30 | ||
| 31 | void KLightLock::Lock() { | 31 | void KLightLock::Lock() { |
| 32 | const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(kernel)); | 32 | const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(m_kernel)); |
| 33 | 33 | ||
| 34 | while (true) { | 34 | while (true) { |
| 35 | uintptr_t old_tag = tag.load(std::memory_order_relaxed); | 35 | uintptr_t old_tag = m_tag.load(std::memory_order_relaxed); |
| 36 | 36 | ||
| 37 | while (!tag.compare_exchange_weak(old_tag, (old_tag == 0) ? cur_thread : (old_tag | 1), | 37 | while (!m_tag.compare_exchange_weak(old_tag, (old_tag == 0) ? cur_thread : (old_tag | 1), |
| 38 | std::memory_order_acquire)) { | 38 | std::memory_order_acquire)) { |
| 39 | } | 39 | } |
| 40 | 40 | ||
| 41 | if (old_tag == 0 || this->LockSlowPath(old_tag | 1, cur_thread)) { | 41 | if (old_tag == 0 || this->LockSlowPath(old_tag | 1, cur_thread)) { |
| @@ -45,30 +45,30 @@ void KLightLock::Lock() { | |||
| 45 | } | 45 | } |
| 46 | 46 | ||
| 47 | void KLightLock::Unlock() { | 47 | void KLightLock::Unlock() { |
| 48 | const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(kernel)); | 48 | const uintptr_t cur_thread = reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(m_kernel)); |
| 49 | 49 | ||
| 50 | uintptr_t expected = cur_thread; | 50 | uintptr_t expected = cur_thread; |
| 51 | if (!tag.compare_exchange_strong(expected, 0, std::memory_order_release)) { | 51 | if (!m_tag.compare_exchange_strong(expected, 0, std::memory_order_release)) { |
| 52 | this->UnlockSlowPath(cur_thread); | 52 | this->UnlockSlowPath(cur_thread); |
| 53 | } | 53 | } |
| 54 | } | 54 | } |
| 55 | 55 | ||
| 56 | bool KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { | 56 | bool KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { |
| 57 | KThread* cur_thread = reinterpret_cast<KThread*>(_cur_thread); | 57 | KThread* cur_thread = reinterpret_cast<KThread*>(_cur_thread); |
| 58 | ThreadQueueImplForKLightLock wait_queue(kernel); | 58 | ThreadQueueImplForKLightLock wait_queue(m_kernel); |
| 59 | 59 | ||
| 60 | // Pend the current thread waiting on the owner thread. | 60 | // Pend the current thread waiting on the owner thread. |
| 61 | { | 61 | { |
| 62 | KScopedSchedulerLock sl{kernel}; | 62 | KScopedSchedulerLock sl{m_kernel}; |
| 63 | 63 | ||
| 64 | // Ensure we actually have locking to do. | 64 | // Ensure we actually have locking to do. |
| 65 | if (tag.load(std::memory_order_relaxed) != _owner) { | 65 | if (m_tag.load(std::memory_order_relaxed) != _owner) { |
| 66 | return false; | 66 | return false; |
| 67 | } | 67 | } |
| 68 | 68 | ||
| 69 | // Add the current thread as a waiter on the owner. | 69 | // Add the current thread as a waiter on the owner. |
| 70 | KThread* owner_thread = reinterpret_cast<KThread*>(_owner & ~1ULL); | 70 | KThread* owner_thread = reinterpret_cast<KThread*>(_owner & ~1ULL); |
| 71 | cur_thread->SetKernelAddressKey(reinterpret_cast<uintptr_t>(std::addressof(tag))); | 71 | cur_thread->SetKernelAddressKey(reinterpret_cast<uintptr_t>(std::addressof(m_tag))); |
| 72 | owner_thread->AddWaiter(cur_thread); | 72 | owner_thread->AddWaiter(cur_thread); |
| 73 | 73 | ||
| 74 | // Begin waiting to hold the lock. | 74 | // Begin waiting to hold the lock. |
| @@ -87,12 +87,12 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { | |||
| 87 | 87 | ||
| 88 | // Unlock. | 88 | // Unlock. |
| 89 | { | 89 | { |
| 90 | KScopedSchedulerLock sl(kernel); | 90 | KScopedSchedulerLock sl(m_kernel); |
| 91 | 91 | ||
| 92 | // Get the next owner. | 92 | // Get the next owner. |
| 93 | bool has_waiters; | 93 | bool has_waiters; |
| 94 | KThread* next_owner = owner_thread->RemoveKernelWaiterByKey( | 94 | KThread* next_owner = owner_thread->RemoveKernelWaiterByKey( |
| 95 | std::addressof(has_waiters), reinterpret_cast<uintptr_t>(std::addressof(tag))); | 95 | std::addressof(has_waiters), reinterpret_cast<uintptr_t>(std::addressof(m_tag))); |
| 96 | 96 | ||
| 97 | // Pass the lock to the next owner. | 97 | // Pass the lock to the next owner. |
| 98 | uintptr_t next_tag = 0; | 98 | uintptr_t next_tag = 0; |
| @@ -114,12 +114,13 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { | |||
| 114 | } | 114 | } |
| 115 | 115 | ||
| 116 | // Write the new tag value. | 116 | // Write the new tag value. |
| 117 | tag.store(next_tag, std::memory_order_release); | 117 | m_tag.store(next_tag, std::memory_order_release); |
| 118 | } | 118 | } |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | bool KLightLock::IsLockedByCurrentThread() const { | 121 | bool KLightLock::IsLockedByCurrentThread() const { |
| 122 | return (tag | 1ULL) == (reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(kernel)) | 1ULL); | 122 | return (m_tag.load() | 1ULL) == |
| 123 | (reinterpret_cast<uintptr_t>(GetCurrentThreadPointer(m_kernel)) | 1ULL); | ||
| 123 | } | 124 | } |
| 124 | 125 | ||
| 125 | } // namespace Kernel | 126 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_light_lock.h b/src/core/hle/kernel/k_light_lock.h index 7edd950c0..626f57596 100644 --- a/src/core/hle/kernel/k_light_lock.h +++ b/src/core/hle/kernel/k_light_lock.h | |||
| @@ -13,7 +13,7 @@ class KernelCore; | |||
| 13 | 13 | ||
| 14 | class KLightLock { | 14 | class KLightLock { |
| 15 | public: | 15 | public: |
| 16 | explicit KLightLock(KernelCore& kernel_) : kernel{kernel_} {} | 16 | explicit KLightLock(KernelCore& kernel) : m_kernel{kernel} {} |
| 17 | 17 | ||
| 18 | void Lock(); | 18 | void Lock(); |
| 19 | 19 | ||
| @@ -24,14 +24,14 @@ public: | |||
| 24 | void UnlockSlowPath(uintptr_t cur_thread); | 24 | void UnlockSlowPath(uintptr_t cur_thread); |
| 25 | 25 | ||
| 26 | bool IsLocked() const { | 26 | bool IsLocked() const { |
| 27 | return tag != 0; | 27 | return m_tag.load() != 0; |
| 28 | } | 28 | } |
| 29 | 29 | ||
| 30 | bool IsLockedByCurrentThread() const; | 30 | bool IsLockedByCurrentThread() const; |
| 31 | 31 | ||
| 32 | private: | 32 | private: |
| 33 | std::atomic<uintptr_t> tag{}; | 33 | std::atomic<uintptr_t> m_tag{}; |
| 34 | KernelCore& kernel; | 34 | KernelCore& m_kernel; |
| 35 | }; | 35 | }; |
| 36 | 36 | ||
| 37 | using KScopedLightLock = KScopedLock<KLightLock>; | 37 | using KScopedLightLock = KScopedLock<KLightLock>; |