aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/k_condition_variable.cpp
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-06-23 06:31:25 +0200
committercrueter <crueter@eden-emu.dev>2026-06-23 06:31:25 +0200
commit3aa0d462598beb2021308eee1d757d74fe33b312 (patch)
treeed425c3845ba8fa61184d97b0588cb049b518bd7 /src/core/hle/kernel/k_condition_variable.cpp
parentf8facda35fe7f17143f84bbfbdacc4cc48678946 (diff)
[video_core, hle] remove redundant parent references in system structs (#3908)
reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads Signed-off-by: lizzie <lizzie@eden-emu.dev> Co-authored-by: maufeat <sahyno1996@gmail.com> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908 Reviewed-by: Maufeat <sahyno1996@gmail.com> Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/core/hle/kernel/k_condition_variable.cpp')
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp100
1 files changed, 49 insertions, 51 deletions
diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp
index 1a7431df07..3cf8b28e17 100644
--- a/src/core/hle/kernel/k_condition_variable.cpp
+++ b/src/core/hle/kernel/k_condition_variable.cpp
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
+// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -66,14 +66,15 @@ bool UpdateLockAtomic(KernelCore& kernel, u32* out, KProcessAddress address, u32
class ThreadQueueImplForKConditionVariableWaitForAddress final : public KThreadQueue {
public:
explicit ThreadQueueImplForKConditionVariableWaitForAddress(KernelCore& kernel)
- : KThreadQueue(kernel) {}
+ : KThreadQueue(kernel)
+ {}
- void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override {
+ virtual void CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override {
// Remove the thread as a waiter from its owner.
- waiting_thread->GetLockOwner()->RemoveWaiter(waiting_thread);
+ waiting_thread->GetLockOwner(kernel)->RemoveWaiter(kernel, waiting_thread);
// Invoke the base cancel wait handler.
- KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task);
+ KThreadQueue::CancelWait(kernel, waiting_thread, wait_result, cancel_timer_task);
}
};
@@ -82,14 +83,15 @@ private:
KConditionVariable::ThreadTree* m_tree;
public:
- explicit ThreadQueueImplForKConditionVariableWaitConditionVariable(
- KernelCore& kernel, KConditionVariable::ThreadTree* t)
- : KThreadQueue(kernel), m_tree(t) {}
+ explicit ThreadQueueImplForKConditionVariableWaitConditionVariable(KernelCore& kernel, KConditionVariable::ThreadTree* t)
+ : KThreadQueue(kernel)
+ , m_tree(t)
+ {}
- void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override {
+ void CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override {
// Remove the thread as a waiter from its owner.
- if (KThread* owner = waiting_thread->GetLockOwner(); owner != nullptr) {
- owner->RemoveWaiter(waiting_thread);
+ if (KThread* owner = waiting_thread->GetLockOwner(kernel); owner != nullptr) {
+ owner->RemoveWaiter(kernel, waiting_thread);
}
// If the thread is waiting on a condvar, remove it from the tree.
@@ -99,14 +101,15 @@ public:
}
// Invoke the base cancel wait handler.
- KThreadQueue::CancelWait(waiting_thread, wait_result, cancel_timer_task);
+ KThreadQueue::CancelWait(kernel, waiting_thread, wait_result, cancel_timer_task);
}
};
} // namespace
KConditionVariable::KConditionVariable(Core::System& system)
- : m_system{system}, m_kernel{system.Kernel()} {}
+ : m_system{system}
+{}
KConditionVariable::~KConditionVariable() = default;
@@ -119,8 +122,7 @@ Result KConditionVariable::SignalToAddress(KernelCore& kernel, KProcessAddress a
// Remove waiter thread.
bool has_waiters{};
- KThread* const next_owner_thread =
- owner_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
+ KThread* const next_owner_thread = owner_thread->RemoveUserWaiterByKey(kernel, std::addressof(has_waiters), addr);
// Determine the next tag.
u32 next_value{};
@@ -144,15 +146,14 @@ Result KConditionVariable::SignalToAddress(KernelCore& kernel, KProcessAddress a
// If necessary, signal the next owner thread.
if (next_owner_thread != nullptr) {
- next_owner_thread->EndWait(result);
+ next_owner_thread->EndWait(kernel, result);
}
R_RETURN(result);
}
}
-Result KConditionVariable::WaitForAddress(KernelCore& kernel, Handle handle, KProcessAddress addr,
- u32 value) {
+Result KConditionVariable::WaitForAddress(KernelCore& kernel, Handle handle, KProcessAddress addr, u32 value) {
KThread* cur_thread = GetCurrentThreadPointer(kernel);
ThreadQueueImplForKConditionVariableWaitForAddress wait_queue(kernel);
@@ -173,30 +174,30 @@ Result KConditionVariable::WaitForAddress(KernelCore& kernel, Handle handle, KPr
// Get the lock owner thread.
owner_thread = GetCurrentProcess(kernel)
- .GetHandleTable()
- .GetObjectWithoutPseudoHandle<KThread>(handle)
- .ReleasePointerUnsafe();
+ .GetHandleTable()
+ .GetObjectWithoutPseudoHandle<KThread>(kernel, handle)
+ .ReleasePointerUnsafe();
R_UNLESS(owner_thread != nullptr, ResultInvalidHandle);
// Update the lock.
cur_thread->SetUserAddressKey(addr, value);
- owner_thread->AddWaiter(cur_thread);
+ owner_thread->AddWaiter(kernel, cur_thread);
// Begin waiting.
- cur_thread->BeginWait(std::addressof(wait_queue));
+ cur_thread->BeginWait(kernel, std::addressof(wait_queue));
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar);
}
// Close our reference to the owner thread, now that the wait is over.
- owner_thread->Close();
+ owner_thread->Close(kernel);
// Get the wait result.
R_RETURN(cur_thread->GetWaitResult());
}
-void KConditionVariable::SignalImpl(KThread* thread) {
+void KConditionVariable::SignalImpl(KernelCore& kernel, KThread* thread) {
// Check pre-conditions.
- ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel));
+ ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
// Update the tag.
KProcessAddress address = thread->GetAddressKey();
@@ -211,35 +212,33 @@ void KConditionVariable::SignalImpl(KThread* thread) {
// TODO(bunnei): We should call CanAccessAtomic(..) here.
can_access = true;
if (can_access) {
- UpdateLockAtomic(m_kernel, std::addressof(prev_tag), address, own_tag,
- Svc::HandleWaitMask);
+ UpdateLockAtomic(kernel, std::addressof(prev_tag), address, own_tag, Svc::HandleWaitMask);
}
}
if (can_access) {
if (prev_tag == Svc::InvalidHandle) {
// If nobody held the lock previously, we're all good.
- thread->EndWait(ResultSuccess);
+ thread->EndWait(kernel, ResultSuccess);
} else {
// Get the previous owner.
- KThread* owner_thread = GetCurrentProcess(m_kernel)
- .GetHandleTable()
- .GetObjectWithoutPseudoHandle<KThread>(
- static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
- .ReleasePointerUnsafe();
+ KThread* owner_thread = GetCurrentProcess(kernel)
+ .GetHandleTable()
+ .GetObjectWithoutPseudoHandle<KThread>(kernel, Handle(prev_tag & ~Svc::HandleWaitMask))
+ .ReleasePointerUnsafe();
if (owner_thread) {
// Add the thread as a waiter on the owner.
- owner_thread->AddWaiter(thread);
- owner_thread->Close();
+ owner_thread->AddWaiter(kernel, thread);
+ owner_thread->Close(kernel);
} else {
// The lock was tagged with a thread that doesn't exist.
- thread->EndWait(ResultInvalidState);
+ thread->EndWait(kernel, ResultInvalidState);
}
}
} else {
// If the address wasn't accessible, note so.
- thread->EndWait(ResultInvalidCurrentMemory);
+ thread->EndWait(kernel, ResultInvalidCurrentMemory);
}
}
@@ -247,17 +246,16 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
// Perform signaling.
s32 num_waiters{};
{
- KScopedSchedulerLock sl(m_kernel);
+ KScopedSchedulerLock sl(m_system.Kernel());
auto it = m_tree.nfind_key({cv_key, -1});
- while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) &&
- (it->GetConditionVariableKey() == cv_key)) {
+ while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetConditionVariableKey() == cv_key)) {
KThread* target_thread = std::addressof(*it);
it = m_tree.erase(it);
target_thread->ClearConditionVariable();
- this->SignalImpl(target_thread);
+ this->SignalImpl(m_system.Kernel(), target_thread);
++num_waiters;
}
@@ -265,20 +263,20 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
// If we have no waiters, clear the has waiter flag.
if (it == m_tree.end() || it->GetConditionVariableKey() != cv_key) {
constexpr u32 HasNoWaiterFlag = 0;
- WriteToUser(m_kernel, cv_key, HasNoWaiterFlag);
+ WriteToUser(m_system.Kernel(), cv_key, HasNoWaiterFlag);
}
}
}
Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 timeout) {
// Prepare to wait.
- KThread* cur_thread = GetCurrentThreadPointer(m_kernel);
+ KThread* cur_thread = GetCurrentThreadPointer(m_system.Kernel());
KHardwareTimer* timer{};
- ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue(m_kernel,
+ ThreadQueueImplForKConditionVariableWaitConditionVariable wait_queue(m_system.Kernel(),
std::addressof(m_tree));
{
- KScopedSchedulerLockAndSleep slp(m_kernel, std::addressof(timer), cur_thread, timeout);
+ KScopedSchedulerLockAndSleep slp(m_system.Kernel(), std::addressof(timer), cur_thread, timeout);
// Check that the thread isn't terminating.
if (cur_thread->IsTerminationRequested()) {
@@ -291,7 +289,7 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti
// Remove waiter thread.
bool has_waiters{};
KThread* next_owner_thread =
- cur_thread->RemoveUserWaiterByKey(std::addressof(has_waiters), addr);
+ cur_thread->RemoveUserWaiterByKey(m_system.Kernel(), std::addressof(has_waiters), addr);
// Update for the next owner thread.
u32 next_value{};
@@ -303,18 +301,18 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti
}
// Wake up the next owner.
- next_owner_thread->EndWait(ResultSuccess);
+ next_owner_thread->EndWait(m_system.Kernel(), ResultSuccess);
}
// Write to the cv key.
{
constexpr u32 HasWaiterFlag = 1;
- WriteToUser(m_kernel, key, HasWaiterFlag);
+ WriteToUser(m_system.Kernel(), key, HasWaiterFlag);
std::atomic_thread_fence(std::memory_order_seq_cst);
}
// Write the value to userspace.
- if (!WriteToUser(m_kernel, addr, next_value)) {
+ if (!WriteToUser(m_system.Kernel(), addr, next_value)) {
slp.CancelSleep();
R_THROW(ResultInvalidCurrentMemory);
}
@@ -329,7 +327,7 @@ Result KConditionVariable::Wait(KProcessAddress addr, u64 key, u32 value, s64 ti
// Begin waiting.
wait_queue.SetHardwareTimer(timer);
- cur_thread->BeginWait(std::addressof(wait_queue));
+ cur_thread->BeginWait(m_system.Kernel(), std::addressof(wait_queue));
cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::ConditionVar);
}