diff --git a/.gitignore b/.gitignore index 67bdd8adf4..75e728babe 100644 --- a/.gitignore +++ b/.gitignore @@ -7,7 +7,6 @@ # Build directory /[Bb]uild*/ doc-build/ -out/ AppDir/ uruntime diff --git a/src/audio_core/device/device_session.cpp b/src/audio_core/device/device_session.cpp index 2a1ae1bb3f..2e9da7876f 100644 --- a/src/audio_core/device/device_session.cpp +++ b/src/audio_core/device/device_session.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -39,7 +42,7 @@ Result DeviceSession::Initialize(std::string_view name_, SampleFormat sample_for channel_count = channel_count_; session_id = session_id_; handle = handle_; - handle->Open(); + handle->Open(system.Kernel()); applet_resource_user_id = applet_resource_user_id_; if (type == Sink::StreamType::In) { @@ -60,7 +63,7 @@ void DeviceSession::Finalize() { } if (handle) { - handle->Close(); + handle->Close(system.Kernel()); handle = nullptr; } } diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp index ec1f565736..f71a2df6be 100644 --- a/src/audio_core/in/audio_in_system.cpp +++ b/src/audio_core/in/audio_in_system.cpp @@ -122,7 +122,7 @@ Result System::Stop() { session->SetVolume(0.0f); session->ClearBuffers(); if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) { - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } state = State::Stopped; } @@ -164,7 +164,7 @@ void System::ReleaseBuffers() { if (signal) { // Signal if any buffer was released, or if none are registered, we need more. - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } } @@ -181,7 +181,7 @@ bool System::FlushAudioInBuffers() { buffers.FlushBuffers(buffers_released); if (buffers_released > 0) { - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } return true; } diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp index dcb0d0694e..46f30f19c6 100644 --- a/src/audio_core/out/audio_out_system.cpp +++ b/src/audio_core/out/audio_out_system.cpp @@ -121,7 +121,7 @@ Result System::Stop() { session->SetVolume(0.0f); session->ClearBuffers(); if (buffers.ReleaseBuffers(system.CoreTiming(), *session, true)) { - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } state = State::Stopped; } @@ -162,7 +162,7 @@ void System::ReleaseBuffers() { bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session, false)}; if (signal) { // Signal if any buffer was released, or if none are registered, we need more. - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } } @@ -179,7 +179,7 @@ bool System::FlushAudioOutBuffers() { buffers.FlushBuffers(buffers_released); if (buffers_released > 0) { - buffer_event->Signal(); + buffer_event->Signal(system.Kernel()); } return true; } diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp index 2053ec6dd4..b7675ff5de 100644 --- a/src/audio_core/renderer/system.cpp +++ b/src/audio_core/renderer/system.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 2022 yuzu Emulator Project @@ -540,7 +540,7 @@ Result System::Update(std::span input, std::span performance, std: return result; } - adsp_rendered_event->Clear(); + adsp_rendered_event->Clear(core.Kernel()); num_times_updated++; const auto end_time{core.CoreTiming().GetGlobalTimeNs().count()}; @@ -624,7 +624,7 @@ void System::SendCommandToDsp() { reset_command_buffers = false; command_buffer_size = command_size; if (remaining_command_count == 0) { - adsp_rendered_event->Signal(); + adsp_rendered_event->Signal(core.Kernel()); } } else { audio_renderer.ClearRemainCommandCount(session_id); diff --git a/src/core/core.cpp b/src/core/core.cpp index 36c88d9848..33fece39f6 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -108,7 +108,7 @@ FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, struct System::Impl { explicit Impl(System& system) - : kernel{system}, fs_controller{system}, hid_core{}, cpu_manager{system}, + : kernel{system}, fs_controller{system}, hid_core{system.Kernel()}, cpu_manager{system}, reporter{system}, applet_manager{system}, frontend_applets{system}, profile_manager{} {} u64 program_id; @@ -923,7 +923,7 @@ void System::PushGeneralChannelData(std::vector&& data) { const bool was_empty = impl->general_channel.empty(); impl->general_channel.push_back(std::move(data)); if (was_empty) { - impl->general_channel_event->Signal(); + impl->general_channel_event->Signal(impl->kernel); } } @@ -935,7 +935,7 @@ bool System::TryPopGeneralChannel(std::vector& out_data) { out_data = std::move(impl->general_channel.back()); impl->general_channel.pop_back(); if (impl->general_channel.empty()) { - impl->general_channel_event->Clear(); + impl->general_channel_event->Clear(impl->kernel); } return true; } diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index f90e78f959..d1c767721b 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -81,7 +81,10 @@ namespace Core { class DebuggerImpl : public DebuggerBackend { public: - explicit DebuggerImpl(Core::System& system_, u16 port) : system{system_} { + explicit DebuggerImpl(Core::System& system_, u16 port) + : system{system_} + , debug_process{system_.Kernel()} + { InitializeServer(port); } @@ -121,7 +124,7 @@ public: } void SetActiveThread(Kernel::KThread* thread) override { - state->active_thread = thread; + state->active_thread = {system.Kernel(), thread}; } Kernel::KThread* GetActiveThread() override { @@ -168,14 +171,7 @@ private: frontend = std::make_unique(*this, system, debug_process.GetPointerUnsafe()); // Set the new state. This will tear down any existing state. - state = ConnectionState{ - .client_socket{std::move(peer)}, - .signal_pipe{io_context}, - .info{}, - .active_thread{}, - .client_data{}, - .pipe_data{}, - }; + state.emplace(std::move(peer), io_context, system.Kernel()); // Set up the client signals for new data. AsyncReceiveInto(state->signal_pipe, state->pipe_data, [&](auto d) { PipeData(d); }); @@ -204,7 +200,7 @@ private: PauseEmulation(); // Notify the client. - state->active_thread = state->info.thread; + state->active_thread = {system.Kernel(), state->info.thread}; UpdateActiveThread(); if (state->info.type == SignalType::Watchpoint) { @@ -258,7 +254,7 @@ private: auto* gdb = static_cast(frontend.get()); MarkResumed([this, threads = std::move(gdb->resume_threads)] { state->active_thread->SetStepState(Kernel::StepState::StepPending); - state->active_thread->Resume(Kernel::SuspendType::Debug); + state->active_thread->Resume(system.Kernel(), Kernel::SuspendType::Debug); ResumeThreads(threads, state->active_thread.GetPointerUnsafe()); }); break; @@ -281,7 +277,7 @@ private: // Put all threads to sleep on next scheduler round. for (auto& thread : ThreadList()) { - thread.RequestSuspend(Kernel::SuspendType::Debug); + thread.RequestSuspend(system.Kernel(), Kernel::SuspendType::Debug); } } @@ -296,7 +292,7 @@ private: } thread.SetStepState(Kernel::StepState::NotStepping); - thread.Resume(Kernel::SuspendType::Debug); + thread.Resume(system.Kernel(), Kernel::SuspendType::Debug); } } @@ -312,7 +308,7 @@ private: } thread->SetStepState(Kernel::StepState::NotStepping); - thread->Resume(Kernel::SuspendType::Debug); + thread->Resume(system.Kernel(), Kernel::SuspendType::Debug); } } @@ -332,7 +328,7 @@ private: return; } } - state->active_thread = std::addressof(threads.front()); + state->active_thread = {system.Kernel(), std::addressof(threads.front())}; } private: @@ -354,13 +350,20 @@ private: std::mutex connection_lock; struct ConnectionState { - boost::asio::ip::tcp::socket client_socket; #ifdef USE_BOOST_v1 - boost::process::v1::async_pipe signal_pipe; + using async_pipe = boost::process::v1::async_pipe; #else - boost::process::async_pipe signal_pipe; + using async_pipe = boost::process::async_pipe; #endif + ConnectionState(boost::asio::ip::tcp::socket&& client_socket_, async_pipe signal_pipe_, Kernel::KernelCore& kernel) + : client_socket{std::move(client_socket_)} + , signal_pipe{signal_pipe_} + , active_thread{kernel, nullptr} + {} + + boost::asio::ip::tcp::socket client_socket; + async_pipe signal_pipe; SignalInfo info; Kernel::KScopedAutoObject active_thread; std::array client_data; diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 5d61c819f8..44ddf11c39 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -323,13 +323,13 @@ void GDBStub::HandleBreakpointInsert(std::string_view command) { success = true; break; case BreakpointType::WriteWatch: - success = debug_process->InsertWatchpoint(addr, size, Kernel::DebugWatchpointType::Write); + success = debug_process->InsertWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::Write); break; case BreakpointType::ReadWatch: - success = debug_process->InsertWatchpoint(addr, size, Kernel::DebugWatchpointType::Read); + success = debug_process->InsertWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::Read); break; case BreakpointType::AccessWatch: - success = debug_process->InsertWatchpoint(addr, size, Kernel::DebugWatchpointType::ReadOrWrite); + success = debug_process->InsertWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::ReadOrWrite); break; case BreakpointType::Hardware: default: @@ -368,13 +368,13 @@ void GDBStub::HandleBreakpointRemove(std::string_view sv) { break; } case BreakpointType::WriteWatch: - success = debug_process->RemoveWatchpoint(addr, size, Kernel::DebugWatchpointType::Write); + success = debug_process->RemoveWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::Write); break; case BreakpointType::ReadWatch: - success = debug_process->RemoveWatchpoint(addr, size, Kernel::DebugWatchpointType::Read); + success = debug_process->RemoveWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::Read); break; case BreakpointType::AccessWatch: - success = debug_process->RemoveWatchpoint(addr, size, Kernel::DebugWatchpointType::ReadOrWrite); + success = debug_process->RemoveWatchpoint(system.Kernel(), addr, size, Kernel::DebugWatchpointType::ReadOrWrite); break; case BreakpointType::Hardware: default: diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp index 1052eb47c2..6d1cd030e0 100644 --- a/src/core/hle/kernel/global_scheduler_context.cpp +++ b/src/core/hle/kernel/global_scheduler_context.cpp @@ -70,11 +70,11 @@ void GlobalSchedulerContext::UnregisterDummyThreadForWakeup(KThread* thread) noe } } -void GlobalSchedulerContext::WakeupWaitingDummyThreads() noexcept { +void GlobalSchedulerContext::WakeupWaitingDummyThreads(KernelCore& kernel) noexcept { ASSERT(this->IsLocked()); if (m_woken_dummy_threads.size() > 0) { for (auto* thread : m_woken_dummy_threads) - thread->DummyThreadEndWait(); + thread->DummyThreadEndWait(kernel); m_woken_dummy_threads.clear(); } } diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h index 72815cbe68..dd53477d2d 100644 --- a/src/core/hle/kernel/global_scheduler_context.h +++ b/src/core/hle/kernel/global_scheduler_context.h @@ -54,7 +54,7 @@ public: bool IsLocked() const noexcept; void UnregisterDummyThreadForWakeup(KThread* thread) noexcept; void RegisterDummyThreadForWakeup(KThread* thread) noexcept; - void WakeupWaitingDummyThreads() noexcept; + void WakeupWaitingDummyThreads(KernelCore& kernel) noexcept; private: friend class KScopedSchedulerLock; diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index a0e20bbbb4..5dd8afaf96 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -281,7 +284,7 @@ void KPageBufferSlabHeap::Initialize(Core::System& system) { // Reserve memory from the system resource limit. ASSERT( - kernel.GetSystemResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, slab_size)); + kernel.GetSystemResourceLimit()->Reserve(kernel, LimitableResource::PhysicalMemoryMax, slab_size)); // Allocate memory for the slab. constexpr auto AllocateOption = KMemoryManager::EncodeOption( diff --git a/src/core/hle/kernel/k_address_arbiter.cpp b/src/core/hle/kernel/k_address_arbiter.cpp index 48889253dc..02634f8721 100644 --- a/src/core/hle/kernel/k_address_arbiter.cpp +++ b/src/core/hle/kernel/k_address_arbiter.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -16,8 +19,9 @@ namespace Kernel { -KAddressArbiter::KAddressArbiter(Core::System& system) - : m_system{system}, m_kernel{system.Kernel()} {} +KAddressArbiter::KAddressArbiter(Core::System& system_) + : system{system_} +{} KAddressArbiter::~KAddressArbiter() = default; namespace { @@ -112,7 +116,7 @@ public: explicit ThreadQueueImplForKAddressArbiter(KernelCore& kernel, KAddressArbiter::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 { // If the thread is waiting on an address arbiter, remove it from the tree. if (waiting_thread->IsWaitingForAddressArbiter()) { m_tree->erase(m_tree->iterator_to(*waiting_thread)); @@ -120,7 +124,7 @@ 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); } private: @@ -133,14 +137,14 @@ Result KAddressArbiter::Signal(uint64_t addr, s32 count) { // Perform signaling. s32 num_waiters{}; { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(system.Kernel()); auto it = m_tree.nfind_key({addr, -1}); while ((it != m_tree.end()) && (count <= 0 || num_waiters < count) && (it->GetAddressArbiterKey() == addr)) { // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->EndWait(ResultSuccess); + target_thread->EndWait(system.Kernel(), ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->ClearAddressArbiter(); @@ -156,11 +160,11 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 // Perform signaling. s32 num_waiters{}; { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(system.Kernel()); // Check the userspace value. s32 user_value{}; - R_UNLESS(UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, value + 1), + R_UNLESS(UpdateIfEqual(system.Kernel(), std::addressof(user_value), addr, value, value + 1), ResultInvalidCurrentMemory); R_UNLESS(user_value == value, ResultInvalidState); @@ -169,7 +173,7 @@ Result KAddressArbiter::SignalAndIncrementIfEqual(uint64_t addr, s32 value, s32 (it->GetAddressArbiterKey() == addr)) { // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->EndWait(ResultSuccess); + target_thread->EndWait(system.Kernel(), ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->ClearAddressArbiter(); @@ -185,7 +189,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 // Perform signaling. s32 num_waiters{}; { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(system.Kernel()); auto it = m_tree.nfind_key({addr, -1}); // Determine the updated value. @@ -220,9 +224,9 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 s32 user_value{}; bool succeeded{}; if (value != new_value) { - succeeded = UpdateIfEqual(m_kernel, std::addressof(user_value), addr, value, new_value); + succeeded = UpdateIfEqual(system.Kernel(), std::addressof(user_value), addr, value, new_value); } else { - succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); + succeeded = ReadFromUser(system.Kernel(), std::addressof(user_value), addr); } R_UNLESS(succeeded, ResultInvalidCurrentMemory); @@ -232,7 +236,7 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 (it->GetAddressArbiterKey() == addr)) { // End the thread's wait. KThread* target_thread = std::addressof(*it); - target_thread->EndWait(ResultSuccess); + target_thread->EndWait(system.Kernel(), ResultSuccess); ASSERT(target_thread->IsWaitingForAddressArbiter()); target_thread->ClearAddressArbiter(); @@ -246,12 +250,12 @@ Result KAddressArbiter::SignalAndModifyByWaitingCountIfEqual(uint64_t addr, s32 Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s64 timeout) { // Prepare to wait. - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + KThread* cur_thread = GetCurrentThreadPointer(system.Kernel()); KHardwareTimer* timer{}; - ThreadQueueImplForKAddressArbiter wait_queue(m_kernel, std::addressof(m_tree)); + ThreadQueueImplForKAddressArbiter wait_queue(system.Kernel(), std::addressof(m_tree)); { - KScopedSchedulerLockAndSleep slp{m_kernel, std::addressof(timer), cur_thread, timeout}; + KScopedSchedulerLockAndSleep slp{system.Kernel(), std::addressof(timer), cur_thread, timeout}; // Check that the thread isn't terminating. if (cur_thread->IsTerminationRequested()) { @@ -263,9 +267,9 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, s32 user_value{}; bool succeeded{}; if (decrement) { - succeeded = DecrementIfLessThan(m_kernel, std::addressof(user_value), addr, value); + succeeded = DecrementIfLessThan(system.Kernel(), std::addressof(user_value), addr, value); } else { - succeeded = ReadFromUser(m_kernel, std::addressof(user_value), addr); + succeeded = ReadFromUser(system.Kernel(), std::addressof(user_value), addr); } if (!succeeded) { @@ -291,7 +295,7 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, // Wait for the thread to finish. wait_queue.SetHardwareTimer(timer); - cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->BeginWait(system.Kernel(), std::addressof(wait_queue)); cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } @@ -301,12 +305,12 @@ Result KAddressArbiter::WaitIfLessThan(uint64_t addr, s32 value, bool decrement, Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { // Prepare to wait. - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + KThread* cur_thread = GetCurrentThreadPointer(system.Kernel()); KHardwareTimer* timer{}; - ThreadQueueImplForKAddressArbiter wait_queue(m_kernel, std::addressof(m_tree)); + ThreadQueueImplForKAddressArbiter wait_queue(system.Kernel(), std::addressof(m_tree)); { - KScopedSchedulerLockAndSleep slp{m_kernel, std::addressof(timer), cur_thread, timeout}; + KScopedSchedulerLockAndSleep slp{system.Kernel(), std::addressof(timer), cur_thread, timeout}; // Check that the thread isn't terminating. if (cur_thread->IsTerminationRequested()) { @@ -316,7 +320,7 @@ Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { // Read the value from userspace. s32 user_value{}; - if (!ReadFromUser(m_kernel, std::addressof(user_value), addr)) { + if (!ReadFromUser(system.Kernel(), std::addressof(user_value), addr)) { slp.CancelSleep(); R_THROW(ResultInvalidCurrentMemory); } @@ -339,7 +343,7 @@ Result KAddressArbiter::WaitIfEqual(uint64_t addr, s32 value, s64 timeout) { // Wait for the thread to finish. wait_queue.SetHardwareTimer(timer); - cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->BeginWait(system.Kernel(), std::addressof(wait_queue)); cur_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Arbitration); } diff --git a/src/core/hle/kernel/k_address_arbiter.h b/src/core/hle/kernel/k_address_arbiter.h index 3b70e1ab28..b3afe19476 100644 --- a/src/core/hle/kernel/k_address_arbiter.h +++ b/src/core/hle/kernel/k_address_arbiter.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -60,8 +63,7 @@ private: private: ThreadTree m_tree; - Core::System& m_system; - KernelCore& m_kernel; + Core::System& system; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_auto_object.cpp b/src/core/hle/kernel/k_auto_object.cpp index a7a46d29bb..14d1c4624d 100644 --- a/src/core/hle/kernel/k_auto_object.cpp +++ b/src/core/hle/kernel/k_auto_object.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 @@ -15,8 +15,8 @@ KAutoObject* KAutoObject::Create(KAutoObject* obj) { return obj; } -void KAutoObject::RegisterWithKernel() { - m_kernel.RegisterKernelObject(this); +void KAutoObject::RegisterWithKernel(KernelCore& kernel) { + kernel.RegisterKernelObject(this); } void KAutoObject::UnregisterWithKernel(KernelCore& kernel, KAutoObject* self) { diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 5e8c0030ce..392b9c9f1d 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -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 2022 yuzu Emulator Project @@ -87,21 +87,21 @@ private: KERNEL_AUTOOBJECT_TRAITS_IMPL(KAutoObject, KAutoObject, const); public: - explicit KAutoObject(KernelCore& kernel) : m_kernel(kernel) { + explicit KAutoObject(KernelCore& kernel) { m_class_token = GetStaticTypeObj().GetClassToken(); - RegisterWithKernel(); + RegisterWithKernel(kernel); } virtual ~KAutoObject() = default; static KAutoObject* Create(KAutoObject* ptr); // Destroy is responsible for destroying the auto object's resources when ref_count hits zero. - virtual void Destroy() { + virtual void Destroy(KernelCore& kernel) { UNIMPLEMENTED(); } // Finalize is responsible for cleaning up resource, but does not destroy the object. - virtual void Finalize() {} + virtual void Finalize(KernelCore& kernel) {} virtual KProcess* GetOwner() const { return nullptr; @@ -123,67 +123,50 @@ public: Derived DynamicCast() { static_assert(std::is_pointer_v); using DerivedType = std::remove_pointer_t; - - if (this->IsDerivedFrom(DerivedType::GetStaticTypeObj())) { - return static_cast(this); - } else { - return nullptr; - } + if (this->IsDerivedFrom(DerivedType::GetStaticTypeObj())) + return Derived(this); + return nullptr; } template const Derived DynamicCast() const { static_assert(std::is_pointer_v); using DerivedType = std::remove_pointer_t; - - if (this->IsDerivedFrom(DerivedType::GetStaticTypeObj())) { - return static_cast(this); - } else { - return nullptr; - } + if (this->IsDerivedFrom(DerivedType::GetStaticTypeObj())) + return Derived(this); + return nullptr; } - bool Open() { + bool Open(KernelCore& kernel) { // Atomically increment the reference count, only if it's positive. u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire); do { - if (cur_ref_count == 0) { + if (cur_ref_count == 0) return false; - } ASSERT(cur_ref_count < cur_ref_count + 1); - } while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count + 1, - std::memory_order_relaxed)); - + } while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count + 1, std::memory_order_relaxed)); return true; } - void Close() { + void Close(KernelCore& kernel) { // Atomically decrement the reference count, not allowing it to become negative. u32 cur_ref_count = m_ref_count.load(std::memory_order_acquire); do { - if (cur_ref_count == 0) { + if (cur_ref_count == 0) return; - } ASSERT(cur_ref_count > 0); - } while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1, - std::memory_order_acq_rel)); - + } while (!m_ref_count.compare_exchange_weak(cur_ref_count, cur_ref_count - 1, std::memory_order_acq_rel)); // If ref count hits 1, destroy the object. if (cur_ref_count == 1) { - KernelCore& kernel = m_kernel; - this->Destroy(); + this->Destroy(kernel); KAutoObject::UnregisterWithKernel(kernel, this); } } private: - void RegisterWithKernel(); + void RegisterWithKernel(KernelCore& kernel); static void UnregisterWithKernel(KernelCore& kernel, KAutoObject* self); -protected: - KernelCore& m_kernel; - -private: std::atomic m_ref_count{}; ClassTokenType m_class_token{}; }; @@ -225,17 +208,22 @@ class KScopedAutoObject { public: YUZU_NON_COPYABLE(KScopedAutoObject); - constexpr KScopedAutoObject() = default; + constexpr KScopedAutoObject(KernelCore& kernel_) + : kernel{kernel_} + {} - constexpr KScopedAutoObject(T* o) : m_obj(o) { + constexpr KScopedAutoObject(KernelCore& kernel_, T* o) + : kernel{kernel_} + , m_obj(o) + { if (m_obj != nullptr) { - m_obj->Open(); + m_obj->Open(kernel); } } ~KScopedAutoObject() { if (m_obj != nullptr) { - m_obj->Close(); + m_obj->Close(kernel); } m_obj = nullptr; } @@ -253,7 +241,7 @@ public: if (rhs.m_obj != nullptr) { derived = rhs.m_obj->template DynamicCast(); if (derived == nullptr) { - rhs.m_obj->Close(); + rhs.m_obj->Close(rhs.kernel); } } @@ -274,8 +262,16 @@ public: return *m_obj; } + constexpr void SetObject(T* o) { + if (m_obj) + m_obj->Close(kernel); + m_obj = o; + if (m_obj) + m_obj->Open(kernel); + } + constexpr void Reset(T* o) { - KScopedAutoObject(o).Swap(*this); + KScopedAutoObject(kernel, o).Swap(*this); } constexpr T* GetPointerUnsafe() { @@ -304,6 +300,7 @@ private: friend class KScopedAutoObject; private: + KernelCore& kernel; T* m_obj{}; private: diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp index 68cea978a0..d13995988c 100644 --- a/src/core/hle/kernel/k_client_port.cpp +++ b/src/core/hle/kernel/k_client_port.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2021 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,7 +18,7 @@ namespace Kernel { KClientPort::KClientPort(KernelCore& kernel) : KSynchronizationObject{kernel} {} KClientPort::~KClientPort() = default; -void KClientPort::Initialize(KPort* parent, s32 max_sessions) { +void KClientPort::Initialize(KernelCore& kernel, KPort* parent, s32 max_sessions) { // Set member variables. m_num_sessions = 0; m_peak_sessions = 0; @@ -23,48 +26,48 @@ void KClientPort::Initialize(KPort* parent, s32 max_sessions) { m_max_sessions = max_sessions; } -void KClientPort::OnSessionFinalized() { - KScopedSchedulerLock sl{m_kernel}; +void KClientPort::OnSessionFinalized(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; if (const auto prev = m_num_sessions--; prev == m_max_sessions) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } -void KClientPort::OnServerClosed() {} +void KClientPort::OnServerClosed(KernelCore& kernel) {} -bool KClientPort::IsLight() const { +bool KClientPort::IsLight(KernelCore& kernel) const { return this->GetParent()->IsLight(); } -bool KClientPort::IsServerClosed() const { - return this->GetParent()->IsServerClosed(); +bool KClientPort::IsServerClosed(KernelCore& kernel) const { + return this->GetParent()->IsServerClosed(kernel); } -void KClientPort::Destroy() { +void KClientPort::Destroy(KernelCore& kernel) { // Note with our parent that we're closed. - m_parent->OnClientClosed(); + m_parent->OnClientClosed(kernel); // Close our reference to our parent. - m_parent->Close(); + m_parent->Close(kernel); } -bool KClientPort::IsSignaled() const { +bool KClientPort::IsSignaled(KernelCore& kernel) const { return m_num_sessions.load() < m_max_sessions; } -Result KClientPort::CreateSession(KClientSession** out) { +Result KClientPort::CreateSession(KernelCore& kernel, KClientSession** out) { // Declare the session we're going to allocate. KSession* session{}; // Reserve a new session from the resource limit. - KScopedResourceReservation session_reservation(GetCurrentProcessPointer(m_kernel), + KScopedResourceReservation session_reservation(kernel, GetCurrentProcessPointer(kernel), LimitableResource::SessionCountMax); R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); // Allocate a session normally. // TODO: Dynamic resource limits - session = KSession::Create(m_kernel); + session = KSession::Create(kernel); // Check that we successfully created a session. R_UNLESS(session != nullptr, ResultOutOfResource); @@ -72,7 +75,7 @@ Result KClientPort::CreateSession(KClientSession** out) { // Update the session counts. { ON_RESULT_FAILURE { - session->Close(); + session->Close(kernel); }; // Atomically increment the number of sessions. @@ -100,38 +103,37 @@ Result KClientPort::CreateSession(KClientSession** out) { } // Initialize the session. - session->Initialize(this, m_parent->GetName()); + session->Initialize(kernel, this, m_parent->GetName()); // Commit the session reservation. session_reservation.Commit(); // Register the session. - KSession::Register(m_kernel, session); + KSession::Register(kernel, session); ON_RESULT_FAILURE { - session->GetClientSession().Close(); - session->GetServerSession().Close(); + session->GetClientSession().Close(kernel); + session->GetServerSession().Close(kernel); }; // Enqueue the session with our parent. - R_TRY(m_parent->EnqueueSession(std::addressof(session->GetServerSession()))); + R_TRY(m_parent->EnqueueSession(kernel, std::addressof(session->GetServerSession()))); // We succeeded, so set the output. *out = std::addressof(session->GetClientSession()); R_SUCCEED(); } -Result KClientPort::CreateLightSession(KLightClientSession** out) { +Result KClientPort::CreateLightSession(KernelCore& kernel, KLightClientSession** out) { // Declare the session we're going to allocate. KLightSession* session{}; // Reserve a new session from the resource limit. - KScopedResourceReservation session_reservation(GetCurrentProcessPointer(m_kernel), - Svc::LimitableResource::SessionCountMax); + KScopedResourceReservation session_reservation(kernel, GetCurrentProcessPointer(kernel), Svc::LimitableResource::SessionCountMax); R_UNLESS(session_reservation.Succeeded(), ResultLimitReached); // Allocate a session normally. // TODO: Dynamic resource limits - session = KLightSession::Create(m_kernel); + session = KLightSession::Create(kernel); // Check that we successfully created a session. R_UNLESS(session != nullptr, ResultOutOfResource); @@ -139,7 +141,7 @@ Result KClientPort::CreateLightSession(KLightClientSession** out) { // Update the session counts. { ON_RESULT_FAILURE { - session->Close(); + session->Close(kernel); }; // Atomically increment the number of sessions. @@ -167,20 +169,20 @@ Result KClientPort::CreateLightSession(KLightClientSession** out) { } // Initialize the session. - session->Initialize(this, m_parent->GetName()); + session->Initialize(kernel, this, m_parent->GetName()); // Commit the session reservation. session_reservation.Commit(); // Register the session. - KLightSession::Register(m_kernel, session); + KLightSession::Register(kernel, session); ON_RESULT_FAILURE { - session->GetClientSession().Close(); - session->GetServerSession().Close(); + session->GetClientSession().Close(kernel); + session->GetServerSession().Close(kernel); }; // Enqueue the session with our parent. - R_TRY(m_parent->EnqueueSession(std::addressof(session->GetServerSession()))); + R_TRY(m_parent->EnqueueSession(kernel, std::addressof(session->GetServerSession()))); // We succeeded, so set the output. *out = std::addressof(session->GetClientSession()); diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h index 28b3326081..3e48eeaa00 100644 --- a/src/core/hle/kernel/k_client_port.h +++ b/src/core/hle/kernel/k_client_port.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2016 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -23,9 +26,9 @@ public: explicit KClientPort(KernelCore& kernel); ~KClientPort() override; - void Initialize(KPort* parent, s32 max_sessions); - void OnSessionFinalized(); - void OnServerClosed(); + void Initialize(KernelCore& kernel, KPort* parent, s32 max_sessions); + void OnSessionFinalized(KernelCore& kernel); + void OnServerClosed(KernelCore& kernel); const KPort* GetParent() const { return m_parent; @@ -44,15 +47,15 @@ public: return m_max_sessions; } - bool IsLight() const; - bool IsServerClosed() const; + bool IsLight(KernelCore& kernel) const; + bool IsServerClosed(KernelCore& kernel) const; // Overridden virtual functions. - void Destroy() override; - bool IsSignaled() const override; + void Destroy(KernelCore& kernel) override; + bool IsSignaled(KernelCore& kernel) const override; - Result CreateSession(KClientSession** out); - Result CreateLightSession(KLightClientSession** out); + Result CreateSession(KernelCore& kernel, KClientSession** out); + Result CreateLightSession(KernelCore& kernel, KLightClientSession** out); private: std::atomic m_num_sessions{}; diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp index 3e01e3b67f..95cb9896b9 100644 --- a/src/core/hle/kernel/k_client_session.cpp +++ b/src/core/hle/kernel/k_client_session.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,41 +16,41 @@ namespace Kernel { KClientSession::KClientSession(KernelCore& kernel) : KAutoObject{kernel} {} KClientSession::~KClientSession() = default; -void KClientSession::Destroy() { - m_parent->OnClientClosed(); - m_parent->Close(); +void KClientSession::Destroy(KernelCore& kernel) { + m_parent->OnClientClosed(kernel); + m_parent->Close(kernel); } void KClientSession::OnServerClosed() {} -Result KClientSession::SendSyncRequest(uintptr_t address, size_t size) { +Result KClientSession::SendSyncRequest(KernelCore& kernel, uintptr_t address, size_t size) { // Create a session request. - KSessionRequest* request = KSessionRequest::Create(m_kernel); + KSessionRequest* request = KSessionRequest::Create(kernel); R_UNLESS(request != nullptr, ResultOutOfResource); SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // Initialize the request. - request->Initialize(nullptr, address, size); + request->Initialize(kernel, nullptr, address, size); // Send the request. - R_RETURN(m_parent->OnRequest(request)); + R_RETURN(m_parent->OnRequest(kernel, request)); } -Result KClientSession::SendAsyncRequest(KEvent* event, uintptr_t address, size_t size) { +Result KClientSession::SendAsyncRequest(KernelCore& kernel, KEvent* event, uintptr_t address, size_t size) { // Create a session request. - KSessionRequest* request = KSessionRequest::Create(m_kernel); + KSessionRequest* request = KSessionRequest::Create(kernel); R_UNLESS(request != nullptr, ResultOutOfResource); SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // Initialize the request. - request->Initialize(event, address, size); + request->Initialize(kernel, event, address, size); // Send the request. - R_RETURN(m_parent->OnRequest(request)); + R_RETURN(m_parent->OnRequest(kernel, request)); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h index a39213e17f..876c3fc789 100644 --- a/src/core/hle/kernel/k_client_session.h +++ b/src/core/hle/kernel/k_client_session.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -26,14 +29,14 @@ public: m_parent = parent; } - void Destroy() override; + void Destroy(KernelCore& kernel) override; KSession* GetParent() const { return m_parent; } - Result SendSyncRequest(uintptr_t address, size_t size); - Result SendAsyncRequest(KEvent* event, uintptr_t address, size_t size); + Result SendSyncRequest(KernelCore& kernel, uintptr_t address, size_t size); + Result SendAsyncRequest(KernelCore& kernel, KEvent* event, uintptr_t address, size_t size); void OnServerClosed(); diff --git a/src/core/hle/kernel/k_code_memory.cpp b/src/core/hle/kernel/k_code_memory.cpp index d72183b104..aa8edce832 100644 --- a/src/core/hle/kernel/k_code_memory.cpp +++ b/src/core/hle/kernel/k_code_memory.cpp @@ -22,16 +22,15 @@ namespace Kernel { KCodeMemory::KCodeMemory(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock(kernel) {} -Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddress addr, - size_t size) { +Result KCodeMemory::Initialize(KernelCore& kernel, Core::DeviceMemory& device_memory, KProcessAddress addr, size_t size) { // Set members. - m_owner = GetCurrentProcessPointer(m_kernel); + m_owner = GetCurrentProcessPointer(kernel); // Get the owner page table. auto& page_table = m_owner->GetPageTable(); // Construct the page group. - m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); + m_page_group.emplace(kernel, page_table.GetBlockInfoManager()); // Lock the memory. R_TRY(page_table.LockForCodeMemory(std::addressof(*m_page_group), addr, size)) @@ -42,7 +41,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddres } // Set remaining tracking members. - m_owner->Open(); + m_owner->Open(kernel); m_address = addr; m_is_initialized = true; m_is_owner_mapped = false; @@ -52,7 +51,7 @@ Result KCodeMemory::Initialize(Core::DeviceMemory& device_memory, KProcessAddres R_SUCCEED(); } -void KCodeMemory::Finalize() { +void KCodeMemory::Finalize(KernelCore& kernel) { // Unlock. if (!m_is_mapped && !m_is_owner_mapped) { const size_t size = m_page_group->GetNumPages() * PageSize; @@ -60,14 +59,14 @@ void KCodeMemory::Finalize() { } // Close the page group. - m_page_group->Close(m_kernel); + m_page_group->Close(kernel); m_page_group->Finalize(); // Close our reference to our owner. - m_owner->Close(); + m_owner->Close(kernel); } -Result KCodeMemory::Map(KProcessAddress address, size_t size) { +Result KCodeMemory::Map(KernelCore& kernel, KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -78,7 +77,7 @@ Result KCodeMemory::Map(KProcessAddress address, size_t size) { R_UNLESS(!m_is_mapped, ResultInvalidState); // Map the memory. - R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup( + R_TRY(GetCurrentProcess(kernel).GetPageTable().MapPageGroup( address, *m_page_group, KMemoryState::CodeOut, KMemoryPermission::UserReadWrite)); // Mark ourselves as mapped. @@ -87,7 +86,7 @@ Result KCodeMemory::Map(KProcessAddress address, size_t size) { R_SUCCEED(); } -Result KCodeMemory::Unmap(KProcessAddress address, size_t size) { +Result KCodeMemory::Unmap(KernelCore& kernel, KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -95,7 +94,7 @@ Result KCodeMemory::Unmap(KProcessAddress address, size_t size) { KScopedLightLock lk(m_lock); // Unmap the memory. - R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, + R_TRY(GetCurrentProcess(kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, KMemoryState::CodeOut)); // Mark ourselves as unmapped. @@ -104,7 +103,7 @@ Result KCodeMemory::Unmap(KProcessAddress address, size_t size) { R_SUCCEED(); } -Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm) { +Result KCodeMemory::MapToOwner(KernelCore& kernel, KProcessAddress address, size_t size, Svc::MemoryPermission perm) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -138,7 +137,7 @@ Result KCodeMemory::MapToOwner(KProcessAddress address, size_t size, Svc::Memory R_SUCCEED(); } -Result KCodeMemory::UnmapFromOwner(KProcessAddress address, size_t size) { +Result KCodeMemory::UnmapFromOwner(KernelCore& kernel, KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); diff --git a/src/core/hle/kernel/k_code_memory.h b/src/core/hle/kernel/k_code_memory.h index 26fe6b3dc6..4f3aab6b4f 100644 --- a/src/core/hle/kernel/k_code_memory.h +++ b/src/core/hle/kernel/k_code_memory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -31,18 +34,18 @@ class KCodeMemory final public: explicit KCodeMemory(KernelCore& kernel); - Result Initialize(Core::DeviceMemory& device_memory, KProcessAddress address, size_t size); - void Finalize() override; + Result Initialize(KernelCore& kernel, Core::DeviceMemory& device_memory, KProcessAddress address, size_t size); + void Finalize(KernelCore& kernel) override; - Result Map(KProcessAddress address, size_t size); - Result Unmap(KProcessAddress address, size_t size); - Result MapToOwner(KProcessAddress address, size_t size, Svc::MemoryPermission perm); - Result UnmapFromOwner(KProcessAddress address, size_t size); + Result Map(KernelCore& kernel, KProcessAddress address, size_t size); + Result Unmap(KernelCore& kernel, KProcessAddress address, size_t size); + Result MapToOwner(KernelCore& kernel, KProcessAddress address, size_t size, Svc::MemoryPermission perm); + Result UnmapFromOwner(KernelCore& kernel, KProcessAddress address, size_t size); bool IsInitialized() const override { return m_is_initialized; } - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} KProcess* GetOwner() const override { return m_owner; diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 748a45e49f..3cf8b28e17 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -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,7 +101,7 @@ 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); } }; @@ -120,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{}; @@ -145,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); @@ -181,15 +181,15 @@ Result KConditionVariable::WaitForAddress(KernelCore& kernel, Handle handle, KPr // 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()); @@ -219,7 +219,7 @@ void KConditionVariable::SignalImpl(KernelCore& kernel, KThread* thread) { 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(kernel) @@ -229,16 +229,16 @@ void KConditionVariable::SignalImpl(KernelCore& kernel, KThread* thread) { 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); } } @@ -289,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{}; @@ -301,7 +301,7 @@ 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. @@ -327,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); } diff --git a/src/core/hle/kernel/k_debug.h b/src/core/hle/kernel/k_debug.h index 2290e3bcab..92ff70df74 100644 --- a/src/core/hle/kernel/k_debug.h +++ b/src/core/hle/kernel/k_debug.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -14,7 +17,7 @@ class KDebug final : public KAutoObjectWithSlabHeapAndContainerOpen(); + m_owner->Open(kernel); } // Mark initialized. m_initialized = true; } -void KEvent::Finalize() { - KAutoObjectWithSlabHeapAndContainer::Finalize(); +void KEvent::Finalize(KernelCore& kernel) { + KAutoObjectWithSlabHeapAndContainer::Finalize(kernel); } -Result KEvent::Signal() { - KScopedSchedulerLock sl{m_kernel}; +Result KEvent::Signal(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; R_SUCCEED_IF(m_readable_event_destroyed); - return m_readable_event.Signal(); + return m_readable_event.Signal(kernel); } -Result KEvent::Clear() { - KScopedSchedulerLock sl{m_kernel}; +Result KEvent::Clear(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; R_SUCCEED_IF(m_readable_event_destroyed); - return m_readable_event.Clear(); + return m_readable_event.Clear(kernel); } -void KEvent::PostDestroy(uintptr_t arg) { +void KEvent::PostDestroy(KernelCore& kernel, uintptr_t arg) { // Release the event count resource the owner process holds. KProcess* owner = reinterpret_cast(arg); if (owner != nullptr) { - owner->GetResourceLimit()->Release(LimitableResource::EventCountMax, 1); - owner->Close(); + owner->GetResourceLimit()->Release(kernel, LimitableResource::EventCountMax, 1); + owner->Close(kernel); } } diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index f522b0a84c..75b03efa69 100644 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -19,9 +22,9 @@ public: explicit KEvent(KernelCore& kernel); ~KEvent() override; - void Initialize(KProcess* owner); + void Initialize(KernelCore& kernel, KProcess* owner); - void Finalize() override; + void Finalize(KernelCore& kernel) override; bool IsInitialized() const override { return m_initialized; @@ -39,10 +42,10 @@ public: return m_readable_event; } - static void PostDestroy(uintptr_t arg); + static void PostDestroy(KernelCore& kernel, uintptr_t arg); - Result Signal(); - Result Clear(); + Result Signal(KernelCore& kernel); + Result Clear(KernelCore& kernel); void OnReadableEventDestroyed() { m_readable_event_destroyed = true; diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp index 2037e7fe44..91d805fa79 100644 --- a/src/core/hle/kernel/k_handle_table.cpp +++ b/src/core/hle/kernel/k_handle_table.cpp @@ -21,11 +21,9 @@ void KHandleTable::Finalize(KernelCore& kernel) { } // Close and free all entries. - for (size_t i = 0; i < saved_table_size; i++) { - if (KAutoObject* obj = m_objects[i]; obj != nullptr) { - obj->Close(); - } - } + for (size_t i = 0; i < saved_table_size; i++) + if (KAutoObject* obj = m_objects[i]; obj != nullptr) + obj->Close(kernel); } bool KHandleTable::Remove(KernelCore& kernel, Handle handle) { @@ -58,7 +56,7 @@ bool KHandleTable::Remove(KernelCore& kernel, Handle handle) { // Close the object. kernel.UnregisterInUseObject(obj); - obj->Close(); + obj->Close(kernel); return true; } @@ -77,7 +75,7 @@ Result KHandleTable::Add(KernelCore& kernel, Handle* out_handle, KAutoObject* ob m_entry_infos[index].linear_id = linear_id; m_objects[index] = obj; - obj->Open(); + obj->Open(kernel); *out_handle = EncodeHandle(static_cast(index), linear_id); } @@ -91,10 +89,10 @@ KScopedAutoObject KHandleTable::GetObjectForIpc(KernelCore& kernel, if (handle == Svc::PseudoHandle::CurrentProcess) { auto* const cur_process = cur_thread->GetOwnerProcess(); ASSERT(cur_process != nullptr); - return cur_process; + return {kernel, cur_process}; } if (handle == Svc::PseudoHandle::CurrentThread) { - return cur_thread; + return {kernel, cur_thread}; } return GetObjectForIpcWithoutPseudoHandle(kernel, handle); } @@ -148,7 +146,7 @@ void KHandleTable::Register(KernelCore& kernel, Handle handle, KAutoObject* obj) m_entry_infos[index].linear_id = static_cast(linear_id); m_objects[index] = obj; - obj->Open(); + obj->Open(kernel); } } diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h index ac286af9cc..0704fd56ef 100644 --- a/src/core/hle/kernel/k_handle_table.h +++ b/src/core/hle/kernel/k_handle_table.h @@ -78,12 +78,12 @@ public: KScopedSpinLock lk(m_lock); if constexpr (std::is_same_v) { - return this->GetObjectImpl(handle); + return {kernel, this->GetObjectImpl(handle)}; } else { if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) [[likely]] { - return obj->DynamicCast(); + return {kernel, obj->DynamicCast()}; } else { - return nullptr; + return {kernel, nullptr}; } } } @@ -95,16 +95,15 @@ public: if (handle == Svc::PseudoHandle::CurrentProcess) { auto* const cur_process = GetCurrentProcessPointer(kernel); ASSERT(cur_process != nullptr); - return cur_process; + return {kernel, cur_process}; } } else if constexpr (std::derived_from) { if (handle == Svc::PseudoHandle::CurrentThread) { auto* const cur_thread = GetCurrentThreadPointer(kernel); ASSERT(cur_thread != nullptr); - return cur_thread; + return {kernel, cur_thread}; } } - return this->template GetObjectWithoutPseudoHandle(kernel, handle); } @@ -112,14 +111,14 @@ public: // Lock and look up in table. KScopedDisableDispatch dd{kernel}; KScopedSpinLock lk(m_lock); - return this->GetObjectImpl(handle); + return {kernel, this->GetObjectImpl(handle)}; } KScopedAutoObject GetObjectForIpc(KernelCore& kernel, Handle handle, KThread* cur_thread) const; KScopedAutoObject GetObjectByIndex(KernelCore& kernel, Handle* out_handle, size_t index) const { KScopedDisableDispatch dd{kernel}; KScopedSpinLock lk(m_lock); - return this->GetObjectByIndexImpl(out_handle, index); + return {kernel, this->GetObjectByIndexImpl(out_handle, index)}; } Result Reserve(KernelCore& kernel, Handle* out_handle); @@ -147,14 +146,14 @@ public: } // Cast the current object to the desired type. - T* cur_t = cur_object->DynamicCast(); - if (cur_t == nullptr) [[unlikely]] { + T* cur_thread = cur_object->DynamicCast(); + if (cur_thread == nullptr) [[unlikely]] { break; } // Open a reference to the current object. - cur_t->Open(); - out[num_opened] = cur_t; + cur_thread->Open(kernel); + out[num_opened] = cur_thread; } } @@ -165,7 +164,7 @@ public: // If we didn't convert entry object, close the ones we opened. for (size_t i = 0; i < num_opened; i++) { - out[i]->Close(); + out[i]->Close(kernel); } return false; diff --git a/src/core/hle/kernel/k_hardware_timer_base.h b/src/core/hle/kernel/k_hardware_timer_base.h index 6318b35bdd..75a4a54763 100644 --- a/src/core/hle/kernel/k_hardware_timer_base.h +++ b/src/core/hle/kernel/k_hardware_timer_base.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -45,7 +48,7 @@ protected: this->RemoveTaskFromTree(task); // Handle the task. - task->OnTimer(); + task->OnTimer(m_kernel); } } diff --git a/src/core/hle/kernel/k_interrupt_manager.cpp b/src/core/hle/kernel/k_interrupt_manager.cpp index 22d79569a5..8960d576b5 100644 --- a/src/core/hle/kernel/k_interrupt_manager.cpp +++ b/src/core/hle/kernel/k_interrupt_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,14 +21,14 @@ void HandleInterrupt(KernelCore& kernel, s32 core_id) { if (auto* process = GetCurrentProcessPointer(kernel); process) { // If the user disable count is set, we may need to pin the current thread. - if (current_thread.GetUserDisableCount() && !process->GetPinnedThread(core_id)) { + if (current_thread.GetUserDisableCount(kernel) && !process->GetPinnedThread(core_id)) { KScopedSchedulerLock sl{kernel}; // Pin the current thread. - process->PinCurrentThread(); + process->PinCurrentThread(kernel); // Set the interrupt flag for the thread. - GetCurrentThread(kernel).SetInterruptFlag(); + GetCurrentThread(kernel).SetInterruptFlag(kernel); } } diff --git a/src/core/hle/kernel/k_light_client_session.cpp b/src/core/hle/kernel/k_light_client_session.cpp index 8ce3e1ae49..23f77deffd 100644 --- a/src/core/hle/kernel/k_light_client_session.cpp +++ b/src/core/hle/kernel/k_light_client_session.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,21 +14,21 @@ KLightClientSession::KLightClientSession(KernelCore& kernel) : KAutoObject(kerne KLightClientSession::~KLightClientSession() = default; -void KLightClientSession::Destroy() { - m_parent->OnClientClosed(); +void KLightClientSession::Destroy(KernelCore& kernel) { + m_parent->OnClientClosed(kernel); } -void KLightClientSession::OnServerClosed() {} +void KLightClientSession::OnServerClosed(KernelCore& kernel) {} -Result KLightClientSession::SendSyncRequest(u32* data) { +Result KLightClientSession::SendSyncRequest(KernelCore& kernel, u32* data) { // Get the request thread. - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); // Set the light data. cur_thread->SetLightSessionData(data); // Send the request. - R_RETURN(m_parent->OnRequest(cur_thread)); + R_RETURN(m_parent->OnRequest(kernel, cur_thread)); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_light_client_session.h b/src/core/hle/kernel/k_light_client_session.h index 881a15cbda..c0f48c295e 100644 --- a/src/core/hle/kernel/k_light_client_session.h +++ b/src/core/hle/kernel/k_light_client_session.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,15 +25,15 @@ public: m_parent = parent; } - virtual void Destroy() override; + virtual void Destroy(KernelCore& kernel) override; const KLightSession* GetParent() const { return m_parent; } - Result SendSyncRequest(u32* data); + Result SendSyncRequest(KernelCore& kernel, u32* data); - void OnServerClosed(); + void OnServerClosed(KernelCore& kernel); private: KLightSession* m_parent; diff --git a/src/core/hle/kernel/k_light_condition_variable.cpp b/src/core/hle/kernel/k_light_condition_variable.cpp index 6d5a815aab..2c873162fb 100644 --- a/src/core/hle/kernel/k_light_condition_variable.cpp +++ b/src/core/hle/kernel/k_light_condition_variable.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,11 +16,13 @@ namespace { class ThreadQueueImplForKLightConditionVariable final : public KThreadQueue { public: - ThreadQueueImplForKLightConditionVariable(KernelCore& kernel, KThread::WaiterList* wl, - bool term) - : KThreadQueue(kernel), m_wait_list(wl), m_allow_terminating_thread(term) {} + ThreadQueueImplForKLightConditionVariable(KernelCore& kernel, KThread::WaiterList* wl, bool term) + : KThreadQueue(kernel) + , m_wait_list(wl) + , m_allow_terminating_thread(term) + {} - 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 { // Only process waits if we're allowed to. if (ResultTerminationRequested == wait_result && m_allow_terminating_thread) { return; @@ -27,7 +32,7 @@ public: m_wait_list->erase(m_wait_list->iterator_to(*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); } private: @@ -61,7 +66,7 @@ void KLightConditionVariable::Wait(KLightLock* lock, s64 timeout, bool allow_ter // Begin waiting. wait_queue.SetHardwareTimer(timer); - owner->BeginWait(std::addressof(wait_queue)); + owner->BeginWait(m_kernel, std::addressof(wait_queue)); } // Re-acquire the lock. @@ -73,7 +78,7 @@ void KLightConditionVariable::Broadcast() { // Signal all threads. for (auto it = m_wait_list.begin(); it != m_wait_list.end(); it = m_wait_list.erase(it)) { - it->EndWait(ResultSuccess); + it->EndWait(m_kernel, ResultSuccess); } } diff --git a/src/core/hle/kernel/k_light_lock.cpp b/src/core/hle/kernel/k_light_lock.cpp index e87ee8b652..614e056d13 100644 --- a/src/core/hle/kernel/k_light_lock.cpp +++ b/src/core/hle/kernel/k_light_lock.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,29 +18,25 @@ class ThreadQueueImplForKLightLock final : public KThreadQueue { public: explicit ThreadQueueImplForKLightLock(KernelCore& kernel) : KThreadQueue(kernel) {} - 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); } // 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 void KLightLock::Lock() { - const uintptr_t cur_thread = reinterpret_cast(GetCurrentThreadPointer(m_kernel)); - + const uintptr_t cur_thread = uintptr_t(GetCurrentThreadPointer(m_kernel)); while (true) { uintptr_t old_tag = m_tag.load(std::memory_order_relaxed); - - while (!m_tag.compare_exchange_weak(old_tag, (old_tag == 0) ? cur_thread : (old_tag | 1), - std::memory_order_acquire)) { - } - + while (!m_tag.compare_exchange_weak(old_tag, (old_tag == 0) ? cur_thread : (old_tag | 1), std::memory_order_acquire)) + ; if (old_tag == 0 || this->LockSlowPath(old_tag | 1, cur_thread)) { break; } @@ -69,13 +68,13 @@ bool KLightLock::LockSlowPath(uintptr_t _owner, uintptr_t _cur_thread) { // Add the current thread as a waiter on the owner. KThread* owner_thread = reinterpret_cast(_owner & ~1ULL); cur_thread->SetKernelAddressKey(reinterpret_cast(std::addressof(m_tag))); - owner_thread->AddWaiter(cur_thread); + owner_thread->AddWaiter(m_kernel, cur_thread); // Begin waiting to hold the lock. - cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->BeginWait(m_kernel, std::addressof(wait_queue)); if (owner_thread->IsSuspended()) { - owner_thread->ContinueIfHasKernelWaiters(); + owner_thread->ContinueIfHasKernelWaiters(m_kernel); } } @@ -91,26 +90,25 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { // Get the next owner. bool has_waiters; - KThread* next_owner = owner_thread->RemoveKernelWaiterByKey( - std::addressof(has_waiters), reinterpret_cast(std::addressof(m_tag))); + KThread* next_owner = owner_thread->RemoveKernelWaiterByKey(m_kernel, + std::addressof(has_waiters), uintptr_t(std::addressof(m_tag))); // Pass the lock to the next owner. uintptr_t next_tag = 0; if (next_owner != nullptr) { - next_tag = - reinterpret_cast(next_owner) | static_cast(has_waiters); + next_tag = uintptr_t(next_owner) | uintptr_t(has_waiters); - next_owner->EndWait(ResultSuccess); + next_owner->EndWait(m_kernel, ResultSuccess); if (next_owner->IsSuspended()) { - next_owner->ContinueIfHasKernelWaiters(); + next_owner->ContinueIfHasKernelWaiters(m_kernel); } } // We may have unsuspended in the process of acquiring the lock, so we'll re-suspend now if // so. if (owner_thread->IsSuspended()) { - owner_thread->TrySuspend(); + owner_thread->TrySuspend(m_kernel); } // Write the new tag value. @@ -119,8 +117,7 @@ void KLightLock::UnlockSlowPath(uintptr_t _cur_thread) { } bool KLightLock::IsLockedByCurrentThread() const { - return (m_tag.load() | 1ULL) == - (reinterpret_cast(GetCurrentThreadPointer(m_kernel)) | 1ULL); + return (m_tag.load() | 1ULL) == (uintptr_t(GetCurrentThreadPointer(m_kernel)) | 1ULL); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_light_server_session.cpp b/src/core/hle/kernel/k_light_server_session.cpp index a4d2b11231..6344f418ed 100644 --- a/src/core/hle/kernel/k_light_server_session.cpp +++ b/src/core/hle/kernel/k_light_server_session.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 2023 yuzu Emulator Project @@ -24,21 +24,20 @@ public: ThreadQueueImplForKLightServerSessionRequest(KernelCore& kernel, KThread::WaiterList* wl) : KThreadQueue(kernel), m_wait_list(wl) {} - virtual void EndWait(KThread* waiting_thread, Result wait_result) override { + virtual void EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) override { // Remove the thread from our wait list. m_wait_list->erase(m_wait_list->iterator_to(*waiting_thread)); // Invoke the base end wait handler. - KThreadQueue::EndWait(waiting_thread, wait_result); + KThreadQueue::EndWait(kernel, waiting_thread, wait_result); } - virtual 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 from our wait list. m_wait_list->erase(m_wait_list->iterator_to(*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); } }; @@ -48,9 +47,11 @@ private: public: ThreadQueueImplForKLightServerSessionReceive(KernelCore& kernel, KThread** st) - : KThreadQueue(kernel), m_server_thread(st) {} + : KThreadQueue(kernel) + , m_server_thread(st) + {} - virtual void EndWait(KThread* waiting_thread, Result wait_result) override { + virtual void EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) override { // Clear the server thread. *m_server_thread = nullptr; @@ -58,11 +59,10 @@ public: waiting_thread->ClearCancellable(); // Invoke the base end wait handler. - KThreadQueue::EndWait(waiting_thread, wait_result); + KThreadQueue::EndWait(kernel, waiting_thread, wait_result); } - virtual 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 { // Clear the server thread. *m_server_thread = nullptr; @@ -70,7 +70,7 @@ public: waiting_thread->ClearCancellable(); // 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); } }; @@ -79,24 +79,21 @@ public: KLightServerSession::KLightServerSession(KernelCore& kernel) : KAutoObject(kernel) {} KLightServerSession::~KLightServerSession() = default; -void KLightServerSession::Destroy() { - this->CleanupRequests(); - - m_parent->OnServerClosed(); +void KLightServerSession::Destroy(KernelCore& kernel) { + this->CleanupRequests(kernel); + m_parent->OnServerClosed(kernel); } -void KLightServerSession::OnClientClosed() { - this->CleanupRequests(); +void KLightServerSession::OnClientClosed(KernelCore& kernel) { + this->CleanupRequests(kernel); } -Result KLightServerSession::OnRequest(KThread* request_thread) { - ThreadQueueImplForKLightServerSessionRequest wait_queue(m_kernel, - std::addressof(m_request_list)); - +Result KLightServerSession::OnRequest(KernelCore& kernel, KThread* request_thread) { + ThreadQueueImplForKLightServerSessionRequest wait_queue(kernel, std::addressof(m_request_list)); // Send the request. { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Check that the server isn't closed. R_UNLESS(!m_parent->IsServerClosed(), ResultSessionClosed); @@ -109,11 +106,11 @@ Result KLightServerSession::OnRequest(KThread* request_thread) { // Begin waiting on the request. request_thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); - request_thread->BeginWait(std::addressof(wait_queue)); + request_thread->BeginWait(kernel, std::addressof(wait_queue)); // If we have a server thread, end its wait. if (m_server_thread != nullptr) { - m_server_thread->EndWait(ResultSuccess); + m_server_thread->EndWait(kernel, ResultSuccess); } } @@ -123,13 +120,13 @@ Result KLightServerSession::OnRequest(KThread* request_thread) { R_RETURN(request_thread->GetWaitResult()); } -Result KLightServerSession::ReplyAndReceive(u32* data) { +Result KLightServerSession::ReplyAndReceive(KernelCore& kernel, u32* data) { // Set the server context. - GetCurrentThread(m_kernel).SetLightSessionData(data); + GetCurrentThread(kernel).SetLightSessionData(data); // Reply, if we need to. if (data[0] & KLightSession::ReplyFlag) { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Check that we're open. R_UNLESS(!m_parent->IsClientClosed(), ResultSessionClosed); @@ -139,17 +136,16 @@ Result KLightServerSession::ReplyAndReceive(u32* data) { R_UNLESS(m_current_request != nullptr, ResultInvalidState); // Check that the server thread id is correct. - R_UNLESS(m_server_thread_id == GetCurrentThread(m_kernel).GetId(), ResultInvalidState); + R_UNLESS(m_server_thread_id == GetCurrentThread(kernel).GetId(), ResultInvalidState); // If we can reply, do so. if (!m_current_request->IsTerminationRequested()) { - std::memcpy(m_current_request->GetLightSessionData(), - GetCurrentThread(m_kernel).GetLightSessionData(), KLightSession::DataSize); - m_current_request->EndWait(ResultSuccess); + std::memcpy(m_current_request->GetLightSessionData(), GetCurrentThread(kernel).GetLightSessionData(), KLightSession::DataSize); + m_current_request->EndWait(kernel, ResultSuccess); } // Close our current request. - m_current_request->Close(); + m_current_request->Close(kernel); // Clear our current request. m_current_request = nullptr; @@ -157,14 +153,13 @@ Result KLightServerSession::ReplyAndReceive(u32* data) { } // Create the wait queue for our receive. - ThreadQueueImplForKLightServerSessionReceive wait_queue(m_kernel, - std::addressof(m_server_thread)); + ThreadQueueImplForKLightServerSessionReceive wait_queue(kernel, std::addressof(m_server_thread)); // Receive. while (true) { // Try to receive a request. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Check that we aren't already receiving. R_UNLESS(m_server_thread == nullptr, ResultInvalidState); @@ -175,20 +170,19 @@ Result KLightServerSession::ReplyAndReceive(u32* data) { R_UNLESS(!m_parent->IsServerClosed(), ResultSessionClosed); // Check that we're not terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), - ResultTerminationRequested); + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // If we have a request available, use it. if (auto head = m_request_list.begin(); head != m_request_list.end()) { // Set our current request. m_current_request = std::addressof(*head); - m_current_request->Open(); + m_current_request->Open(kernel); // Set our server thread id. - m_server_thread_id = GetCurrentThread(m_kernel).GetId(); + m_server_thread_id = GetCurrentThread(kernel).GetId(); // Copy the client request data. - std::memcpy(GetCurrentThread(m_kernel).GetLightSessionData(), + std::memcpy(GetCurrentThread(kernel).GetLightSessionData(), m_current_request->GetLightSessionData(), KLightSession::DataSize); // We successfully received. @@ -198,51 +192,51 @@ Result KLightServerSession::ReplyAndReceive(u32* data) { // We need to wait for a request to come in. // Check if we were cancelled. - if (GetCurrentThread(m_kernel).IsWaitCancelled()) { - GetCurrentThread(m_kernel).ClearWaitCancelled(); + if (GetCurrentThread(kernel).IsWaitCancelled()) { + GetCurrentThread(kernel).ClearWaitCancelled(); R_THROW(ResultCancelled); } // Mark ourselves as cancellable. - GetCurrentThread(m_kernel).SetCancellable(); + GetCurrentThread(kernel).SetCancellable(); // Wait for a request to come in. - m_server_thread = GetCurrentThreadPointer(m_kernel); - GetCurrentThread(m_kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + m_server_thread = GetCurrentThreadPointer(kernel); + GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } // We waited to receive a request; if our wait failed, return the failing result. - R_TRY(GetCurrentThread(m_kernel).GetWaitResult()); + R_TRY(GetCurrentThread(kernel).GetWaitResult()); } } -void KLightServerSession::CleanupRequests() { +void KLightServerSession::CleanupRequests(KernelCore& kernel) { // Cleanup all pending requests. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Handle the current request. if (m_current_request != nullptr) { // Reply to the current request. if (!m_current_request->IsTerminationRequested()) { - m_current_request->EndWait(ResultSessionClosed); + m_current_request->EndWait(kernel, ResultSessionClosed); } // Clear our current request. - m_current_request->Close(); + m_current_request->Close(kernel); m_current_request = nullptr; m_server_thread_id = InvalidThreadId; } // Reply to all other requests. for (auto& thread : m_request_list) { - thread.EndWait(ResultSessionClosed); + thread.EndWait(kernel, ResultSessionClosed); } // Wait up our server thread, if we have one. if (m_server_thread != nullptr) { - m_server_thread->EndWait(ResultSessionClosed); + m_server_thread->EndWait(kernel, ResultSessionClosed); } } } diff --git a/src/core/hle/kernel/k_light_server_session.h b/src/core/hle/kernel/k_light_server_session.h index 67db3f76ca..5849a41c7b 100644 --- a/src/core/hle/kernel/k_light_server_session.h +++ b/src/core/hle/kernel/k_light_server_session.h @@ -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 2023 yuzu Emulator Project @@ -34,19 +34,19 @@ public: m_parent = parent; } - virtual void Destroy() override; + virtual void Destroy(KernelCore& kernel) override; constexpr const KLightSession* GetParent() const { return m_parent; } - Result OnRequest(KThread* request_thread); - Result ReplyAndReceive(u32* data); + Result OnRequest(KernelCore& kernel, KThread* request_thread); + Result ReplyAndReceive(KernelCore& kernel, u32* data); - void OnClientClosed(); + void OnClientClosed(KernelCore& kernel); private: - void CleanupRequests(); + void CleanupRequests(KernelCore& kernel); }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_light_session.cpp b/src/core/hle/kernel/k_light_session.cpp index d8b1e69582..add72d404b 100644 --- a/src/core/hle/kernel/k_light_session.cpp +++ b/src/core/hle/kernel/k_light_session.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,15 +13,18 @@ namespace Kernel { KLightSession::KLightSession(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer(kernel), m_server(kernel), m_client(kernel) {} + : KAutoObjectWithSlabHeapAndContainer(kernel) + , m_server(kernel) + , m_client(kernel) +{} KLightSession::~KLightSession() = default; -void KLightSession::Initialize(KClientPort* client_port, uintptr_t name) { +void KLightSession::Initialize(KernelCore& kernel, KClientPort* client_port, uintptr_t name) { // Increment reference count. // Because reference count is one on creation, this will result // in a reference count of two. Thus, when both server and client are closed // this object will be destroyed. - this->Open(); + this->Open(kernel); // Create our sub sessions. KAutoObject::Create(std::addressof(m_server)); @@ -33,49 +39,47 @@ void KLightSession::Initialize(KClientPort* client_port, uintptr_t name) { m_name = name; // Set our owner process. - m_process = GetCurrentProcessPointer(m_kernel); - m_process->Open(); + m_process = GetCurrentProcessPointer(kernel); + m_process->Open(kernel); // Set our port. m_port = client_port; if (m_port != nullptr) { - m_port->Open(); + m_port->Open(kernel); } // Mark initialized. m_initialized = true; } -void KLightSession::Finalize() { +void KLightSession::Finalize(KernelCore& kernel) { if (m_port != nullptr) { - m_port->OnSessionFinalized(); - m_port->Close(); + m_port->OnSessionFinalized(kernel); + m_port->Close(kernel); } } -void KLightSession::OnServerClosed() { +void KLightSession::OnServerClosed(KernelCore& kernel) { if (m_state == State::Normal) { m_state = State::ServerClosed; - m_client.OnServerClosed(); + m_client.OnServerClosed(kernel); } - - this->Close(); + this->Close(kernel); } -void KLightSession::OnClientClosed() { +void KLightSession::OnClientClosed(KernelCore& kernel) { if (m_state == State::Normal) { m_state = State::ClientClosed; - m_server.OnClientClosed(); + m_server.OnClientClosed(kernel); } - - this->Close(); + this->Close(kernel); } -void KLightSession::PostDestroy(uintptr_t arg) { +void KLightSession::PostDestroy(KernelCore& kernel, uintptr_t arg) { // Release the session count resource the owner process holds. KProcess* owner = reinterpret_cast(arg); - owner->ReleaseResource(Svc::LimitableResource::SessionCountMax, 1); - owner->Close(); + owner->ReleaseResource(kernel, Svc::LimitableResource::SessionCountMax, 1); + owner->Close(kernel); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_light_session.h b/src/core/hle/kernel/k_light_session.h index f78d8e6899..5bbb942b35 100644 --- a/src/core/hle/kernel/k_light_session.h +++ b/src/core/hle/kernel/k_light_session.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -43,20 +46,20 @@ public: explicit KLightSession(KernelCore& kernel); ~KLightSession(); - void Initialize(KClientPort* client_port, uintptr_t name); - void Finalize() override; + void Initialize(KernelCore& kernel, KClientPort* client_port, uintptr_t name); + void Finalize(KernelCore& kernel) override; bool IsInitialized() const override { return m_initialized; } uintptr_t GetPostDestroyArgument() const override { - return reinterpret_cast(m_process); + return uintptr_t(m_process); } - static void PostDestroy(uintptr_t arg); + static void PostDestroy(KernelCore& kernel, uintptr_t arg); - void OnServerClosed(); - void OnClientClosed(); + void OnServerClosed(KernelCore& kernel); + void OnClientClosed(KernelCore& kernel); bool IsServerClosed() const { return m_state != State::Normal; @@ -65,8 +68,8 @@ public: return m_state != State::Normal; } - Result OnRequest(KThread* request_thread) { - R_RETURN(m_server.OnRequest(request_thread)); + Result OnRequest(KernelCore& kernel, KThread* request_thread) { + R_RETURN(m_server.OnRequest(kernel, request_thread)); } KLightClientSession& GetClientSession() { diff --git a/src/core/hle/kernel/k_object_name.cpp b/src/core/hle/kernel/k_object_name.cpp index df3a1c4c56..da0b04b450 100644 --- a/src/core/hle/kernel/k_object_name.cpp +++ b/src/core/hle/kernel/k_object_name.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -8,14 +11,14 @@ namespace Kernel { KObjectNameGlobalData::KObjectNameGlobalData(KernelCore& kernel) : m_object_list_lock{kernel} {} KObjectNameGlobalData::~KObjectNameGlobalData() = default; -void KObjectName::Initialize(KAutoObject* obj, const char* name) { +void KObjectName::Initialize(KernelCore& kernel, KAutoObject* obj, const char* name) { // Set member variables. m_object = obj; std::strncpy(m_name.data(), name, sizeof(m_name) - 1); m_name[sizeof(m_name) - 1] = '\x00'; // Open a reference to the object we hold. - m_object->Open(); + m_object->Open(kernel); } bool KObjectName::MatchesName(const char* name) const { @@ -28,7 +31,7 @@ Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char R_UNLESS(new_name != nullptr, ResultOutOfResource); // Initialize the new name. - new_name->Initialize(obj, name); + new_name->Initialize(kernel, obj, name); // Check if there's an existing name. { @@ -47,7 +50,7 @@ Result KObjectName::NewFromName(KernelCore& kernel, KAutoObject* obj, const char } // The object already exists, which is an error condition. Perform cleanup. - obj->Close(); + obj->Close(kernel); KObjectName::Free(kernel, new_name); R_THROW(ResultInvalidState); } @@ -63,7 +66,7 @@ Result KObjectName::Delete(KernelCore& kernel, KAutoObject* obj, const char* com for (auto& name : gd.GetObjectList()) { if (name.MatchesName(compare_name) && obj == name.GetObject()) { // We found a match, clean up its resources. - obj->Close(); + obj->Close(kernel); gd.GetObjectList().erase(gd.GetObjectList().iterator_to(name)); KObjectName::Free(kernel, std::addressof(name)); R_SUCCEED(); @@ -89,14 +92,12 @@ KScopedAutoObject KObjectName::FindImpl(KernelCore& kernel, const c KObjectNameGlobalData& gd{kernel.ObjectNameGlobalData()}; // Try to find a matching object in the global list. - for (const auto& name : gd.GetObjectList()) { - if (name.MatchesName(compare_name)) { - return name.GetObject(); - } - } + for (const auto& name : gd.GetObjectList()) + if (name.MatchesName(compare_name)) + return {kernel, name.GetObject()}; // There's no matching entry in the list. - return nullptr; + return {kernel, nullptr}; } } // namespace Kernel diff --git a/src/core/hle/kernel/k_object_name.h b/src/core/hle/kernel/k_object_name.h index a8876fe370..2ae9edcf51 100644 --- a/src/core/hle/kernel/k_object_name.h +++ b/src/core/hle/kernel/k_object_name.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -41,7 +44,7 @@ public: R_UNLESS(derived != nullptr, ResultNotFound); // Check that the object is closed. - R_UNLESS(derived->IsServerClosed(), ResultInvalidState); + R_UNLESS(derived->IsServerClosed(kernel), ResultInvalidState); R_RETURN(Delete(kernel, obj.GetPointerUnsafe(), name)); } @@ -49,13 +52,13 @@ public: template requires(std::derived_from) static KScopedAutoObject Find(KernelCore& kernel, const char* name) { - return Find(kernel, name); + return {kernel, static_cast(Find(kernel, name).GetPointerUnsafe())}; } private: static KScopedAutoObject FindImpl(KernelCore& kernel, const char* name); - void Initialize(KAutoObject* obj, const char* name); + void Initialize(KernelCore& kernel, KAutoObject* obj, const char* name); bool MatchesName(const char* name) const; KAutoObject* GetObject() const { diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp index f61cdf51a0..a727355a9f 100644 --- a/src/core/hle/kernel/k_page_table_base.cpp +++ b/src/core/hle/kernel/k_page_table_base.cpp @@ -492,14 +492,14 @@ void KPageTableBase::Finalize() { if (auto* const insecure_resource_limit = KSystemControl::GetInsecureMemoryResourceLimit(m_system.Kernel()); insecure_resource_limit != nullptr) { - insecure_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, + insecure_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, m_mapped_insecure_memory); } } // Release any ipc server memory. if (m_mapped_ipc_server_memory) { - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, + m_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, m_mapped_ipc_server_memory); } } @@ -1389,7 +1389,7 @@ Result KPageTableBase::MapInsecureMemory(KProcessAddress address, size_t size) { // Reserve the insecure memory. // NOTE: ResultOutOfMemory is returned here instead of the usual LimitReached. - KScopedResourceReservation memory_reservation(insecure_resource_limit, + KScopedResourceReservation memory_reservation(m_system.Kernel(), insecure_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, size); R_UNLESS(memory_reservation.Succeeded(), ResultOutOfMemory); @@ -1493,7 +1493,7 @@ Result KPageTableBase::UnmapInsecureMemory(KProcessAddress address, size_t size) if (auto* const insecure_resource_limit = KSystemControl::GetInsecureMemoryResourceLimit(m_system.Kernel()); insecure_resource_limit != nullptr) { - insecure_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, size); + insecure_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, size); } R_SUCCEED(); @@ -2158,7 +2158,7 @@ Result KPageTableBase::SetHeapSize(KProcessAddress* out, size_t size) { false, unmap_properties, OperationType::Unmap, false)); // Release the memory from the resource limit. - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, + m_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, num_pages * PageSize); // Apply the memory block update. @@ -2188,7 +2188,7 @@ Result KPageTableBase::SetHeapSize(KProcessAddress* out, size_t size) { } // Reserve memory for the heap extension. - KScopedResourceReservation memory_reservation( + KScopedResourceReservation memory_reservation(m_system.Kernel(), m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, allocation_size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); @@ -4493,7 +4493,7 @@ Result KPageTableBase::SetupForIpcServer(KProcessAddress* out_addr, size_t size, // Reserve space for any partial pages we allocate. const size_t unmapped_size = aligned_src_size - mapping_src_size; - KScopedResourceReservation memory_reservation( + KScopedResourceReservation memory_reservation(m_system.Kernel(), m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, unmapped_size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); @@ -4799,7 +4799,7 @@ Result KPageTableBase::CleanupForIpcServer(KProcessAddress address, size_t size, const KProcessAddress mapping_start = Common::AlignUp(GetInteger(address), PageSize); const KProcessAddress mapping_end = Common::AlignDown(GetInteger(address) + size, PageSize); const size_t mapping_size = (mapping_start < mapping_end) ? mapping_end - mapping_start : 0; - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, + m_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, aligned_size - mapping_size); R_SUCCEED(); @@ -5168,7 +5168,7 @@ Result KPageTableBase::MapPhysicalMemory(KProcessAddress address, size_t size) { // Allocate and map the memory. { // Reserve the memory from the process resource limit. - KScopedResourceReservation memory_reservation( + KScopedResourceReservation memory_reservation(m_system.Kernel(), m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, size - mapped_size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); @@ -5541,7 +5541,7 @@ Result KPageTableBase::UnmapPhysicalMemory(KProcessAddress address, size_t size) // Release the memory resource. m_mapped_physical_memory_size -= mapped_size; - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, mapped_size); + m_resource_limit->Release(m_system.Kernel(), Svc::LimitableResource::PhysicalMemoryMax, mapped_size); // Update memory blocks. m_memory_block_manager.Update(std::addressof(allocator), address, size / PageSize, diff --git a/src/core/hle/kernel/k_port.cpp b/src/core/hle/kernel/k_port.cpp index e5f5d8028c..f64d983e0c 100644 --- a/src/core/hle/kernel/k_port.cpp +++ b/src/core/hle/kernel/k_port.cpp @@ -1,8 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/k_port.h" #include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/svc_results.h" namespace Kernel { @@ -12,15 +16,15 @@ KPort::KPort(KernelCore& kernel) KPort::~KPort() = default; -void KPort::Initialize(s32 max_sessions, bool is_light, uintptr_t name) { +void KPort::Initialize(KernelCore& kernel, s32 max_sessions, bool is_light, uintptr_t name) { // Open a new reference count to the initialized port. - this->Open(); + this->Open(kernel); // Create and initialize our server/client pair. KAutoObject::Create(std::addressof(m_server)); KAutoObject::Create(std::addressof(m_client)); - m_server.Initialize(this); - m_client.Initialize(this, max_sessions); + m_server.Initialize(kernel, this); + m_client.Initialize(kernel, this, max_sessions); // Set our member variables. m_is_light = is_light; @@ -28,42 +32,38 @@ void KPort::Initialize(s32 max_sessions, bool is_light, uintptr_t name) { m_state = State::Normal; } -void KPort::OnClientClosed() { - KScopedSchedulerLock sl{m_kernel}; +void KPort::OnClientClosed(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; if (m_state == State::Normal) { m_state = State::ClientClosed; } } -void KPort::OnServerClosed() { - KScopedSchedulerLock sl{m_kernel}; +void KPort::OnServerClosed(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; if (m_state == State::Normal) { m_state = State::ServerClosed; } } -bool KPort::IsServerClosed() const { - KScopedSchedulerLock sl{m_kernel}; +bool KPort::IsServerClosed(KernelCore& kernel) const { + KScopedSchedulerLock sl{kernel}; return m_state == State::ServerClosed; } -Result KPort::EnqueueSession(KServerSession* session) { - KScopedSchedulerLock sl{m_kernel}; - +Result KPort::EnqueueSession(KernelCore& kernel, KServerSession* session) { + KScopedSchedulerLock sl{kernel}; R_UNLESS(m_state == State::Normal, ResultPortClosed); - - m_server.EnqueueSession(session); + m_server.EnqueueSession(kernel, session); R_SUCCEED(); } -Result KPort::EnqueueSession(KLightServerSession* session) { - KScopedSchedulerLock sl{m_kernel}; - +Result KPort::EnqueueSession(KernelCore& kernel, KLightServerSession* session) { + KScopedSchedulerLock sl{kernel}; R_UNLESS(m_state == State::Normal, ResultPortClosed); - - m_server.EnqueueSession(session); + m_server.EnqueueSession(kernel, session); R_SUCCEED(); } diff --git a/src/core/hle/kernel/k_port.h b/src/core/hle/kernel/k_port.h index 26f5f14eff..698f794538 100644 --- a/src/core/hle/kernel/k_port.h +++ b/src/core/hle/kernel/k_port.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -23,11 +26,11 @@ public: explicit KPort(KernelCore& kernel); ~KPort() override; - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} - void Initialize(s32 max_sessions, bool is_light, uintptr_t name); - void OnClientClosed(); - void OnServerClosed(); + void Initialize(KernelCore& kernel, s32 max_sessions, bool is_light, uintptr_t name); + void OnClientClosed(KernelCore& kernel); + void OnServerClosed(KernelCore& kernel); uintptr_t GetName() const { return m_name; @@ -36,10 +39,10 @@ public: return m_is_light; } - bool IsServerClosed() const; + bool IsServerClosed(KernelCore& kernel) const; - Result EnqueueSession(KServerSession* session); - Result EnqueueSession(KLightServerSession* session); + Result EnqueueSession(KernelCore& kernel, KServerSession* session); + Result EnqueueSession(KernelCore& kernel, KLightServerSession* session); KClientPort& GetClientPort() { return m_client; diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 0265575226..841c5b4d14 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -28,8 +28,7 @@ namespace Kernel { namespace { -Result TerminateChildren(KernelCore& kernel, KProcess* process, - const KThread* thread_to_not_terminate) { +Result TerminateChildren(KernelCore& kernel, KProcess* process, const KThread* thread_to_not_terminate) { // Request that all children threads terminate. { KScopedLightLock proc_lk(process->GetListLock()); @@ -41,14 +40,14 @@ Result TerminateChildren(KernelCore& kernel, KProcess* process, // This is valid because the only caller which uses non-nullptr as argument uses // GetCurrentThreadPointer(), but it's still notable because it seems incorrect at // first glance. - process->UnpinCurrentThread(); + process->UnpinCurrentThread(kernel); } auto& thread_list = process->GetThreadList(); for (auto it = thread_list.begin(); it != thread_list.end(); ++it) { if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) { if (thread->GetState() != ThreadState::Terminated) { - thread->RequestTerminate(); + thread->RequestTerminate(kernel); } } } @@ -65,7 +64,7 @@ Result TerminateChildren(KernelCore& kernel, KProcess* process, for (auto it = thread_list.begin(); it != thread_list.end(); ++it) { if (KThread* thread = std::addressof(*it); thread != thread_to_not_terminate) { if (thread->GetState() != ThreadState::Terminated) { - if (thread->Open()) { + if (thread->Open(kernel)) { cur_child = thread; break; } @@ -81,11 +80,10 @@ Result TerminateChildren(KernelCore& kernel, KProcess* process, // Terminate and close the thread. SCOPE_EXIT { - cur_child->Close(); + cur_child->Close(kernel); }; - if (const Result terminate_result = cur_child->Terminate(); - ResultTerminationRequested == terminate_result) { + if (const Result terminate_result = cur_child->Terminate(kernel); ResultTerminationRequested == terminate_result) { R_THROW(terminate_result); } } @@ -101,21 +99,21 @@ public: explicit ThreadQueueImplForKProcessEnterUserException(KernelCore& kernel, KThread** t) : KThreadQueue(kernel), m_exception_thread(t) {} - virtual void EndWait(KThread* waiting_thread, Result wait_result) override { + virtual void EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) override { // Set the exception thread. *m_exception_thread = waiting_thread; // Invoke the base end wait handler. - KThreadQueue::EndWait(waiting_thread, wait_result); + KThreadQueue::EndWait(kernel, waiting_thread, wait_result); } - virtual void CancelWait(KThread* waiting_thread, Result wait_result, + virtual void CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task) override { // Remove the thread as a waiter on its mutex 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); } }; @@ -128,12 +126,12 @@ void GenerateRandom(std::span out_random) { } // namespace -void KProcess::Finalize() { +void KProcess::Finalize(KernelCore& kernel) { // Delete the process local region. - this->DeleteThreadLocalRegion(m_plr_address); + this->DeleteThreadLocalRegion(kernel, m_plr_address); // Get the used memory size. - const size_t used_memory_size = this->GetUsedNonSystemUserPhysicalMemorySize(); + const size_t used_memory_size = this->GetUsedNonSystemUserPhysicalMemorySize(kernel); // Finalize the page table. m_page_table.Finalize(); @@ -142,10 +140,10 @@ void KProcess::Finalize() { if (m_system_resource) { if (m_system_resource->IsSecureResource()) { // Finalize optimized memory. If memory wasn't optimized, this is a no-op. - m_kernel.MemoryManager().FinalizeOptimizedMemory(this->GetId(), m_memory_pool); + kernel.MemoryManager().FinalizeOptimizedMemory(this->GetId(), m_memory_pool); } - m_system_resource->Close(); + m_system_resource->Close(kernel); m_system_resource = nullptr; } @@ -157,12 +155,12 @@ void KProcess::Finalize() { KSharedMemory* shmem = info->GetSharedMemory(); while (!info->Close()) { - shmem->Close(); + shmem->Close(kernel); } - shmem->Close(); + shmem->Close(kernel); it = m_shared_memory_list.erase(it); - KSharedMemoryInfo::Free(m_kernel, info); + KSharedMemoryInfo::Free(kernel, info); } } @@ -173,9 +171,8 @@ void KProcess::Finalize() { // Release memory to the resource limit. if (m_resource_limit != nullptr) { ASSERT(used_memory_size >= m_memory_release_hint); - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, used_memory_size, - used_memory_size - m_memory_release_hint); - m_resource_limit->Close(); + m_resource_limit->Release(kernel, Svc::LimitableResource::PhysicalMemoryMax, used_memory_size, used_memory_size - m_memory_release_hint); + m_resource_limit->Close(kernel); } // Clear expensive resources, as the destructor is not called for guest objects. @@ -185,15 +182,14 @@ void KProcess::Finalize() { m_exclusive_monitor.reset(); // Perform inherited finalization. - KSynchronizationObject::Finalize(); + KSynchronizationObject::Finalize(kernel); } -Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit, - bool is_real) { +Result KProcess::Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, KResourceLimit* res_limit, bool is_real) { // TODO: remove this special case if (is_real) { // Create and clear the process local region. - R_TRY(this->CreateThreadLocalRegion(std::addressof(m_plr_address))); + R_TRY(this->CreateThreadLocalRegion(kernel, std::addressof(m_plr_address))); this->GetMemory().ZeroBlock(m_plr_address, Svc::ThreadLocalRegionSize); } @@ -256,7 +252,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResource // Open a reference to our resource limit. m_resource_limit = res_limit; - m_resource_limit->Open(); + m_resource_limit->Open(kernel); // We're initialized! m_is_initialized = true; @@ -264,7 +260,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, KResource R_SUCCEED(); } -Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg, +Result KProcess::Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, const KPageGroup& pg, std::span caps, KResourceLimit* res_limit, KMemoryManager::Pool pool, bool immortal) { ASSERT(res_limit != nullptr); @@ -280,34 +276,33 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa if (const size_t system_resource_num_pages = params.system_resource_num_pages; system_resource_num_pages != 0) { // Create a secure system resource. - KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel); + KSecureSystemResource* secure_resource = KSecureSystemResource::Create(kernel); R_UNLESS(secure_resource != nullptr, ResultOutOfResource); ON_RESULT_FAILURE { - secure_resource->Close(); + secure_resource->Close(kernel); }; // Initialize the secure resource. - R_TRY(secure_resource->Initialize(system_resource_num_pages * PageSize, res_limit, - m_memory_pool)); + R_TRY(secure_resource->Initialize(kernel, system_resource_num_pages * PageSize, res_limit, m_memory_pool)); // Set our system resource. m_system_resource = secure_resource; } else { // Use the system-wide system resource. const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication); - m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource() - : m_kernel.GetSystemSystemResource()); + m_system_resource = std::addressof(is_app ? kernel.GetAppSystemResource() + : kernel.GetSystemSystemResource()); m_is_default_application_system_resource = is_app; // Open reference to the system resource. - m_system_resource->Open(); + m_system_resource->Open(kernel); } // Ensure we clean up our secure resource, if we fail. ON_RESULT_FAILURE { - m_system_resource->Close(); + m_system_resource->Close(kernel); m_system_resource = nullptr; }; @@ -327,7 +322,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa // Ensure our memory is initialized. m_memory.SetCurrentPageTable(*this); - m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager()); + m_memory.SetGPUDirtyManagers(kernel.System().GetGPUDirtyMemoryManager()); // Ensure we can insert the code region. R_UNLESS(m_page_table.CanContain(params.code_address, params.code_num_pages * PageSize, @@ -347,18 +342,18 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const KPa } // Initialize the process id. - m_process_id = m_kernel.CreateNewUserProcessID(); + m_process_id = kernel.CreateNewUserProcessID(); ASSERT(InitialProcessIdMin <= m_process_id); ASSERT(m_process_id <= InitialProcessIdMax); // Initialize the rest of the process. - R_TRY(this->Initialize(params, res_limit, true)); + R_TRY(this->Initialize(kernel, params, res_limit, true)); // We succeeded! R_SUCCEED(); } -Result KProcess::Initialize(const Svc::CreateProcessParameter& params, +Result KProcess::Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, std::span user_caps, KResourceLimit* res_limit, KMemoryManager::Pool pool, KProcessAddress aslr_space_start) { ASSERT(res_limit != nullptr); @@ -375,22 +370,22 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, const size_t system_resource_size = system_resource_num_pages * PageSize; // Reserve memory for our code resource. - KScopedResourceReservation memory_reservation( + KScopedResourceReservation memory_reservation(kernel, res_limit, Svc::LimitableResource::PhysicalMemoryMax, code_size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); // Setup our system resource. if (system_resource_num_pages != 0) { // Create a secure system resource. - KSecureSystemResource* secure_resource = KSecureSystemResource::Create(m_kernel); + KSecureSystemResource* secure_resource = KSecureSystemResource::Create(kernel); R_UNLESS(secure_resource != nullptr, ResultOutOfResource); ON_RESULT_FAILURE { - secure_resource->Close(); + secure_resource->Close(kernel); }; // Initialize the secure resource. - R_TRY(secure_resource->Initialize(system_resource_size, res_limit, m_memory_pool)); + R_TRY(secure_resource->Initialize(kernel, system_resource_size, res_limit, m_memory_pool)); // Set our system resource. m_system_resource = secure_resource; @@ -398,18 +393,18 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, } else { // Use the system-wide system resource. const bool is_app = True(params.flags & Svc::CreateProcessFlag::IsApplication); - m_system_resource = std::addressof(is_app ? m_kernel.GetAppSystemResource() - : m_kernel.GetSystemSystemResource()); + m_system_resource = std::addressof(is_app ? kernel.GetAppSystemResource() + : kernel.GetSystemSystemResource()); m_is_default_application_system_resource = is_app; // Open reference to the system resource. - m_system_resource->Open(); + m_system_resource->Open(kernel); } // Ensure we clean up our secure resource, if we fail. ON_RESULT_FAILURE { - m_system_resource->Close(); + m_system_resource->Close(kernel); m_system_resource = nullptr; }; @@ -429,7 +424,7 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, // Ensure our memory is initialized. m_memory.SetCurrentPageTable(*this); - m_memory.SetGPUDirtyManagers(m_kernel.System().GetGPUDirtyMemoryManager()); + m_memory.SetGPUDirtyManagers(kernel.System().GetGPUDirtyMemoryManager()); // Ensure we can insert the code region. R_UNLESS(m_page_table.CanContain(params.code_address, code_size, KMemoryState::Code), @@ -448,101 +443,99 @@ Result KProcess::Initialize(const Svc::CreateProcessParameter& params, } // Initialize the process id. - m_process_id = m_kernel.CreateNewUserProcessID(); + m_process_id = kernel.CreateNewUserProcessID(); ASSERT(ProcessIdMin <= m_process_id); ASSERT(m_process_id <= ProcessIdMax); // If we should optimize memory allocations, do so. if (m_system_resource->IsSecureResource() && True(params.flags & Svc::CreateProcessFlag::OptimizeMemoryAllocation)) { - R_TRY(m_kernel.MemoryManager().InitializeOptimizedMemory(m_process_id, pool)); + R_TRY(kernel.MemoryManager().InitializeOptimizedMemory(m_process_id, pool)); } // Initialize the rest of the process. - R_TRY(this->Initialize(params, res_limit, true)); + R_TRY(this->Initialize(kernel, params, res_limit, true)); // We succeeded, so commit our memory reservation. memory_reservation.Commit(); R_SUCCEED(); } -void KProcess::DoWorkerTaskImpl() { +void KProcess::DoWorkerTaskImpl(KernelCore& kernel) { // Terminate child threads. - TerminateChildren(m_kernel, this, nullptr); + TerminateChildren(kernel, this, nullptr); // Finalize the handle table, if we're not immortal. if (!m_is_immortal && m_is_handle_table_initialized) { - this->FinalizeHandleTable(); + this->FinalizeHandleTable(kernel); } // Finish termination. - this->FinishTermination(); + this->FinishTermination(kernel); } -Result KProcess::StartTermination() { +Result KProcess::StartTermination(KernelCore& kernel) { // Finalize the handle table when we're done, if the process isn't immortal. SCOPE_EXIT { if (!m_is_immortal) { - this->FinalizeHandleTable(); + this->FinalizeHandleTable(kernel); } }; // Terminate child threads other than the current one. - R_RETURN(TerminateChildren(m_kernel, this, GetCurrentThreadPointer(m_kernel))); + R_RETURN(TerminateChildren(kernel, this, GetCurrentThreadPointer(kernel))); } -void KProcess::FinishTermination() { +void KProcess::FinishTermination(KernelCore& kernel) { // Only allow termination to occur if the process isn't immortal. if (!m_is_immortal) { // Release resource limit hint. if (m_resource_limit != nullptr) { - m_memory_release_hint = this->GetUsedNonSystemUserPhysicalMemorySize(); - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, 0, - m_memory_release_hint); + m_memory_release_hint = this->GetUsedNonSystemUserPhysicalMemorySize(kernel); + m_resource_limit->Release(kernel, Svc::LimitableResource::PhysicalMemoryMax, 0, m_memory_release_hint); } // Change state. { - KScopedSchedulerLock sl(m_kernel); - this->ChangeState(State::Terminated); + KScopedSchedulerLock sl(kernel); + this->ChangeState(kernel, State::Terminated); } // Close. - this->Close(); + this->Close(kernel); } } -void KProcess::Exit() { +void KProcess::Exit(KernelCore& kernel) { // Determine whether we need to start terminating bool needs_terminate = false; { KScopedLightLock lk(m_state_lock); - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); ASSERT(m_state != State::Created); ASSERT(m_state != State::CreatedAttached); ASSERT(m_state != State::Crashed); ASSERT(m_state != State::Terminated); - if (m_state == State::Running || m_state == State::RunningAttached || - m_state == State::DebugBreak) { - this->ChangeState(State::Terminating); + if (m_state == State::Running || m_state == State::RunningAttached || m_state == State::DebugBreak) { + this->ChangeState(kernel, State::Terminating); needs_terminate = true; } } // If we need to start termination, do so. if (needs_terminate) { - this->StartTermination(); + this->StartTermination(kernel); // Register the process as a work task. - m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this); + kernel.WorkerTaskManager().AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this); } // Exit the current thread. - GetCurrentThread(m_kernel).Exit(); + GetCurrentThread(kernel).Exit(kernel); } -Result KProcess::Terminate() { +Result KProcess::Terminate(KernelCore& kernel) { // Determine whether we need to start terminating. bool needs_terminate = false; { @@ -552,11 +545,11 @@ Result KProcess::Terminate() { R_UNLESS(m_state != State::Created, ResultInvalidState); R_UNLESS(m_state != State::CreatedAttached, ResultInvalidState); - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); if (m_state == State::Running || m_state == State::RunningAttached || m_state == State::Crashed || m_state == State::DebugBreak) { - this->ChangeState(State::Terminating); + this->ChangeState(kernel, State::Terminating); needs_terminate = true; } } @@ -564,20 +557,19 @@ Result KProcess::Terminate() { // If we need to terminate, do so. if (needs_terminate) { // Start termination. - if (R_SUCCEEDED(this->StartTermination())) { + if (R_SUCCEEDED(this->StartTermination(kernel))) { // Finish termination. - this->FinishTermination(); + this->FinishTermination(kernel); } else { // Register the process as a work task. - m_kernel.WorkerTaskManager().AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, - this); + kernel.WorkerTaskManager().AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this); } } R_SUCCEED(); } -Result KProcess::AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) { +Result KProcess::AddSharedMemory(KernelCore& kernel, KSharedMemory* shmem, KProcessAddress address, size_t size) { // Lock ourselves, to prevent concurrent access. KScopedLightLock lk(m_state_lock); @@ -593,7 +585,7 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, // If we didn't find an info, create one. if (info == nullptr) { // Allocate a new info. - info = KSharedMemoryInfo::Allocate(m_kernel); + info = KSharedMemoryInfo::Allocate(kernel); R_UNLESS(info != nullptr, ResultOutOfResource); // Initialize the info and add it to our list. @@ -602,13 +594,13 @@ Result KProcess::AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, } // Open a reference to the shared memory and its info. - shmem->Open(); + shmem->Open(kernel); info->Open(); R_SUCCEED(); } -void KProcess::RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size) { +void KProcess::RemoveSharedMemory(KernelCore& kernel, KSharedMemory* shmem, KProcessAddress address, size_t size) { // Lock ourselves, to prevent concurrent access. KScopedLightLock lk(m_state_lock); @@ -626,19 +618,19 @@ void KProcess::RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, // Close a reference to the info and its memory. if (info->Close()) { m_shared_memory_list.erase(it); - KSharedMemoryInfo::Free(m_kernel, info); + KSharedMemoryInfo::Free(kernel, info); } - shmem->Close(); + shmem->Close(kernel); } -Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { +Result KProcess::CreateThreadLocalRegion(KernelCore& kernel, KProcessAddress* out) { KThreadLocalPage* tlp = nullptr; KProcessAddress tlr = 0; // See if we can get a region from a partially used TLP. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); if (auto it = m_partially_used_tlp_tree.begin(); it != m_partially_used_tlp_tree.end()) { tlr = it->Reserve(); @@ -656,14 +648,14 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { } // Allocate a new page. - tlp = KThreadLocalPage::Allocate(m_kernel); + tlp = KThreadLocalPage::Allocate(kernel); R_UNLESS(tlp != nullptr, ResultOutOfMemory); ON_RESULT_FAILURE { - KThreadLocalPage::Free(m_kernel, tlp); + KThreadLocalPage::Free(kernel, tlp); }; // Initialize the new page. - R_TRY(tlp->Initialize(m_kernel, this)); + R_TRY(tlp->Initialize(kernel, this)); // Reserve a TLR. tlr = tlp->Reserve(); @@ -671,7 +663,7 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { // Insert into our tree. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); if (tlp->IsAllUsed()) { m_fully_used_tlp_tree.insert(*tlp); } else { @@ -684,12 +676,12 @@ Result KProcess::CreateThreadLocalRegion(KProcessAddress* out) { R_SUCCEED(); } -Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { +Result KProcess::DeleteThreadLocalRegion(KernelCore& kernel, KProcessAddress addr) { KThreadLocalPage* page_to_free = nullptr; // Release the region. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Try to find the page in the partially used list. auto it = m_partially_used_tlp_tree.find_key(Common::AlignDown(GetInteger(addr), PageSize)); @@ -726,57 +718,56 @@ Result KProcess::DeleteThreadLocalRegion(KProcessAddress addr) { if (page_to_free != nullptr) { page_to_free->Finalize(); - KThreadLocalPage::Free(m_kernel, page_to_free); + KThreadLocalPage::Free(kernel, page_to_free); } R_SUCCEED(); } -bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value) { +bool KProcess::ReserveResource(KernelCore& kernel, Svc::LimitableResource which, s64 value) { if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) { - return rl->Reserve(which, value); + return rl->Reserve(kernel, which, value); } else { return true; } } -bool KProcess::ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout) { +bool KProcess::ReserveResource(KernelCore& kernel, Svc::LimitableResource which, s64 value, s64 timeout) { if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) { - return rl->Reserve(which, value, timeout); + return rl->Reserve(kernel, which, value, timeout); } else { return true; } } -void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value) { +void KProcess::ReleaseResource(KernelCore& kernel, Svc::LimitableResource which, s64 value) { if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) { - rl->Release(which, value); + rl->Release(kernel, which, value); } } -void KProcess::ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint) { +void KProcess::ReleaseResource(KernelCore& kernel, Svc::LimitableResource which, s64 value, s64 hint) { if (KResourceLimit* rl = this->GetResourceLimit(); rl != nullptr) { - rl->Release(which, value, hint); + rl->Release(kernel, which, value, hint); } } -void KProcess::IncrementRunningThreadCount() { +void KProcess::IncrementRunningThreadCount(KernelCore& kernel) { ASSERT(m_num_running_threads.load() >= 0); ++m_num_running_threads; } -void KProcess::DecrementRunningThreadCount() { +void KProcess::DecrementRunningThreadCount(KernelCore& kernel) { ASSERT(m_num_running_threads.load() > 0); - if (const auto prev = m_num_running_threads--; prev == 1) { - this->Terminate(); + this->Terminate(kernel); } } -bool KProcess::EnterUserException() { +bool KProcess::EnterUserException(KernelCore& kernel) { // Get the current thread. - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); ASSERT(this == cur_thread->GetOwnerProcess()); // Check that we haven't already claimed the exception thread. @@ -785,13 +776,13 @@ bool KProcess::EnterUserException() { } // Create the wait queue we'll be using. - ThreadQueueImplForKProcessEnterUserException wait_queue(m_kernel, + ThreadQueueImplForKProcessEnterUserException wait_queue(kernel, std::addressof(m_exception_thread)); // Claim the exception thread. { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Check that we're not terminating. if (cur_thread->IsTerminationRequested()) { @@ -801,45 +792,44 @@ bool KProcess::EnterUserException() { // If we don't have an exception thread, we can just claim it directly. if (m_exception_thread == nullptr) { m_exception_thread = cur_thread; - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); return true; } // Otherwise, we need to wait until we don't have an exception thread. // Add the current thread as a waiter on the current exception thread. - cur_thread->SetKernelAddressKey( - reinterpret_cast(std::addressof(m_exception_thread)) | 1); - m_exception_thread->AddWaiter(cur_thread); + cur_thread->SetKernelAddressKey(uintptr_t(std::addressof(m_exception_thread)) | 1); + m_exception_thread->AddWaiter(kernel, cur_thread); // Wait to claim the exception thread. - cur_thread->BeginWait(std::addressof(wait_queue)); + cur_thread->BeginWait(kernel, std::addressof(wait_queue)); } // If our wait didn't end due to thread termination, we succeeded. return ResultTerminationRequested != cur_thread->GetWaitResult(); } -bool KProcess::LeaveUserException() { - return this->ReleaseUserException(GetCurrentThreadPointer(m_kernel)); +bool KProcess::LeaveUserException(KernelCore& kernel) { + return this->ReleaseUserException(kernel, GetCurrentThreadPointer(kernel)); } -bool KProcess::ReleaseUserException(KThread* thread) { - KScopedSchedulerLock sl(m_kernel); +bool KProcess::ReleaseUserException(KernelCore& kernel, KThread* thread) { + KScopedSchedulerLock sl(kernel); if (m_exception_thread == thread) { m_exception_thread = nullptr; // Remove waiter thread. bool has_waiters; - if (KThread* next = thread->RemoveKernelWaiterByKey( + if (KThread* next = thread->RemoveKernelWaiterByKey(kernel, std::addressof(has_waiters), reinterpret_cast(std::addressof(m_exception_thread)) | 1); next != nullptr) { - next->EndWait(ResultSuccess); + next->EndWait(kernel, ResultSuccess); } - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); return true; } else { @@ -847,19 +837,19 @@ bool KProcess::ReleaseUserException(KThread* thread) { } } -void KProcess::RegisterThread(KThread* thread) { +void KProcess::RegisterThread(KernelCore& kernel, KThread* thread) { KScopedLightLock lk(m_list_lock); m_thread_list.push_back(*thread); } -void KProcess::UnregisterThread(KThread* thread) { +void KProcess::UnregisterThread(KernelCore& kernel, KThread* thread) { KScopedLightLock lk(m_list_lock); m_thread_list.erase(m_thread_list.iterator_to(*thread)); } -size_t KProcess::GetUsedUserPhysicalMemorySize() const { +size_t KProcess::GetUsedUserPhysicalMemorySize(KernelCore& kernel) const { const size_t norm_size = m_page_table.GetNormalMemorySize(); const size_t other_size = m_code_size + m_main_thread_stack_size; const size_t sec_size = this->GetRequiredSecureMemorySizeNonDefault(); @@ -867,7 +857,7 @@ size_t KProcess::GetUsedUserPhysicalMemorySize() const { return norm_size + other_size + sec_size; } -size_t KProcess::GetTotalUserPhysicalMemorySize() const { +size_t KProcess::GetTotalUserPhysicalMemorySize(KernelCore& kernel) const { // Get the amount of free and used size. const size_t free_size = m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax); @@ -886,18 +876,18 @@ size_t KProcess::GetTotalUserPhysicalMemorySize() const { if (used_size + free_size > max_size) { return max_size; } else { - return free_size + this->GetUsedUserPhysicalMemorySize(); + return free_size + this->GetUsedUserPhysicalMemorySize(kernel); } } -size_t KProcess::GetUsedNonSystemUserPhysicalMemorySize() const { +size_t KProcess::GetUsedNonSystemUserPhysicalMemorySize(KernelCore& kernel) const { const size_t norm_size = m_page_table.GetNormalMemorySize(); const size_t other_size = m_code_size + m_main_thread_stack_size; return norm_size + other_size; } -size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const { +size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize(KernelCore& kernel) const { // Get the amount of free and used size. const size_t free_size = m_resource_limit->GetFreeValue(Svc::LimitableResource::PhysicalMemoryMax); @@ -916,11 +906,11 @@ size_t KProcess::GetTotalNonSystemUserPhysicalMemorySize() const { if (used_size + free_size > max_size) { return max_size - this->GetRequiredSecureMemorySizeNonDefault(); } else { - return free_size + this->GetUsedNonSystemUserPhysicalMemorySize(); + return free_size + this->GetUsedNonSystemUserPhysicalMemorySize(kernel); } } -Result KProcess::Run(s32 priority, size_t stack_size) { +Result KProcess::Run(KernelCore& kernel, s32 priority, size_t stack_size) { // Lock ourselves, to prevent concurrent access. KScopedLightLock lk(m_state_lock); @@ -929,7 +919,7 @@ Result KProcess::Run(s32 priority, size_t stack_size) { R_UNLESS(state == State::Created || state == State::CreatedAttached, ResultInvalidState); // Place a tentative reservation of a thread for this process. - KScopedResourceReservation thread_reservation(this, Svc::LimitableResource::ThreadCountMax); + KScopedResourceReservation thread_reservation(kernel, this, Svc::LimitableResource::ThreadCountMax); R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); // Ensure that we haven't already allocated stack. @@ -941,7 +931,7 @@ Result KProcess::Run(s32 priority, size_t stack_size) { R_UNLESS(stack_size + m_code_size >= m_code_size, ResultOutOfMemory); // Place a tentative reservation of memory for our new stack. - KScopedResourceReservation mem_reservation(this, Svc::LimitableResource::PhysicalMemoryMax, + KScopedResourceReservation mem_reservation(kernel, this, Svc::LimitableResource::PhysicalMemoryMax, stack_size); R_UNLESS(mem_reservation.Succeeded(), ResultLimitReached); @@ -971,29 +961,29 @@ Result KProcess::Run(s32 priority, size_t stack_size) { (m_main_thread_stack_size + m_code_size))); // Initialize our handle table. - R_TRY(this->InitializeHandleTable(m_capabilities.GetHandleTableSize())); + R_TRY(this->InitializeHandleTable(kernel, m_capabilities.GetHandleTableSize())); ON_RESULT_FAILURE_2 { - this->FinalizeHandleTable(); + this->FinalizeHandleTable(kernel); }; // Create a new thread for the process. - KThread* main_thread = KThread::Create(m_kernel); + KThread* main_thread = KThread::Create(kernel); R_UNLESS(main_thread != nullptr, ResultOutOfResource); SCOPE_EXIT { - main_thread->Close(); + main_thread->Close(kernel); }; // Initialize the thread. - R_TRY(KThread::InitializeUserThread(m_kernel.System(), main_thread, this->GetEntryPoint(), 0, + R_TRY(KThread::InitializeUserThread(kernel.System(), main_thread, this->GetEntryPoint(), 0, stack_top, priority, m_ideal_core_id, this)); // Register the thread, and commit our reservation. - KThread::Register(m_kernel, main_thread); + KThread::Register(kernel, main_thread); thread_reservation.Commit(); // Add the thread to our handle table. Handle thread_handle; - R_TRY(m_handle_table.Add(m_kernel, std::addressof(thread_handle), main_thread)); + R_TRY(m_handle_table.Add(kernel, std::addressof(thread_handle), main_thread)); // Set the thread arguments. main_thread->GetContext().r[0] = 0; @@ -1003,21 +993,21 @@ Result KProcess::Run(s32 priority, size_t stack_size) { this->GetMemory().Write32(GetInteger(main_thread->GetTlsAddress()) + 0x110, thread_handle); // Update our state. - this->ChangeState((state == State::Created) ? State::Running : State::RunningAttached); + this->ChangeState(kernel, (state == State::Created) ? State::Running : State::RunningAttached); ON_RESULT_FAILURE_2 { - this->ChangeState(state); + this->ChangeState(kernel, state); }; // Suspend for debug, if we should. - if (m_kernel.System().DebuggerEnabled()) { - main_thread->RequestSuspend(SuspendType::Debug); + if (kernel.System().DebuggerEnabled()) { + main_thread->RequestSuspend(kernel, SuspendType::Debug); } // Run our thread. - R_TRY(main_thread->Run()); + R_TRY(main_thread->Run(kernel)); // Open a reference to represent that we're running. - this->Open(); + this->Open(kernel); // We succeeded! Commit our memory reservation. mem_reservation.Commit(); @@ -1025,10 +1015,10 @@ Result KProcess::Run(s32 priority, size_t stack_size) { R_SUCCEED(); } -Result KProcess::Reset() { +Result KProcess::Reset(KernelCore& kernel) { // Lock the process and the scheduler. KScopedLightLock lk(m_state_lock); - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Validate that we're in a state that we can reset. R_UNLESS(m_state != State::Terminated, ResultInvalidState); @@ -1039,11 +1029,11 @@ Result KProcess::Reset() { R_SUCCEED(); } -Result KProcess::SetActivity(Svc::ProcessActivity activity) { +Result KProcess::SetActivity(KernelCore& kernel, Svc::ProcessActivity activity) { // Lock ourselves and the scheduler. KScopedLightLock lk(m_state_lock); KScopedLightLock list_lk(m_list_lock); - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Validate our state. R_UNLESS(m_state != State::Terminating, ResultInvalidState); @@ -1057,7 +1047,7 @@ Result KProcess::SetActivity(Svc::ProcessActivity activity) { // Suspend all threads. auto end = this->GetThreadList().end(); for (auto it = this->GetThreadList().begin(); it != end; ++it) { - it->RequestSuspend(SuspendType::Process); + it->RequestSuspend(kernel, SuspendType::Process); } // Set ourselves as suspended. @@ -1071,7 +1061,7 @@ Result KProcess::SetActivity(Svc::ProcessActivity activity) { // Resume all threads. auto end = this->GetThreadList().end(); for (auto it = this->GetThreadList().begin(); it != end; ++it) { - it->Resume(SuspendType::Process); + it->Resume(kernel, SuspendType::Process); } // Set ourselves as resumed. @@ -1081,54 +1071,54 @@ Result KProcess::SetActivity(Svc::ProcessActivity activity) { R_SUCCEED(); } -void KProcess::PinCurrentThread() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); +void KProcess::PinCurrentThread(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Get the current thread. - const s32 core_id = GetCurrentCoreId(m_kernel); - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + const s32 core_id = GetCurrentCoreId(kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); // If the thread isn't terminated, pin it. if (!cur_thread->IsTerminationRequested()) { // Pin it. this->PinThread(core_id, cur_thread); - cur_thread->Pin(core_id); + cur_thread->Pin(kernel, core_id); // An update is needed. - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } } -void KProcess::UnpinCurrentThread() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); +void KProcess::UnpinCurrentThread(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Get the current thread. - const s32 core_id = GetCurrentCoreId(m_kernel); - KThread* cur_thread = GetCurrentThreadPointer(m_kernel); + const s32 core_id = GetCurrentCoreId(kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); // Unpin it. - cur_thread->Unpin(); + cur_thread->Unpin(kernel); this->UnpinThread(core_id, cur_thread); // An update is needed. - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } -void KProcess::UnpinThread(KThread* thread) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); +void KProcess::UnpinThread(KernelCore& kernel, KThread* thread) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Get the thread's core id. const auto core_id = thread->GetActiveCore(); // Unpin it. this->UnpinThread(core_id, thread); - thread->Unpin(); + thread->Unpin(kernel); // An update is needed. - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } -Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, +Result KProcess::GetThreadList(KernelCore& kernel, s32* out_num_threads, KProcessAddress out_thread_ids, s32 max_out_count) { auto& memory = this->GetMemory(); @@ -1158,7 +1148,7 @@ Result KProcess::GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ R_SUCCEED(); } -void KProcess::Switch(KProcess* cur_process, KProcess* next_process) {} +void KProcess::Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process) {} KProcess::KProcess(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer(kernel) @@ -1174,17 +1164,17 @@ KProcess::KProcess(KernelCore& kernel) KProcess::~KProcess() = default; -Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, +Result KProcess::LoadFromMetadata(KernelCore& kernel, const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl) { // Create a resource limit for the process. const auto pool = static_cast(metadata.GetPoolPartition()); - const auto physical_memory_size = m_kernel.MemoryManager().GetSize(pool); + const auto physical_memory_size = kernel.MemoryManager().GetSize(pool); auto* res_limit = - Kernel::CreateResourceLimitForProcess(m_kernel.System(), physical_memory_size); + Kernel::CreateResourceLimitForProcess(kernel.System(), physical_memory_size); // Ensure we maintain a clean state on exit. SCOPE_EXIT { - res_limit->Close(); + res_limit->Close(kernel); }; // Declare flags and code address. @@ -1243,23 +1233,21 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std: std::memcpy(params.name.data(), name.data(), sizeof(params.name)); // Initialize for application process. - R_TRY(this->Initialize(params, metadata.GetKernelCapabilities(), res_limit, pool, - aslr_space_start)); + R_TRY(this->Initialize(kernel, params, metadata.GetKernelCapabilities(), res_limit, pool, aslr_space_start)); // Assign remaining properties. m_is_hbl = is_hbl; m_ideal_core_id = metadata.GetMainThreadCore(); // Set up emulation context. - this->InitializeInterfaces(); + this->InitializeInterfaces(kernel); // We succeeded. R_SUCCEED(); } -void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { - const auto ReprotectSegment = [&](const CodeSet::Segment& segment, - Svc::MemoryPermission permission) { +void KProcess::LoadModule(KernelCore& kernel, CodeSet code_set, KProcessAddress base_addr) { + const auto ReprotectSegment = [&](const CodeSet::Segment& segment, Svc::MemoryPermission permission) { m_page_table.SetProcessMemoryPermission(segment.addr + base_addr, segment.size, permission); }; @@ -1273,7 +1261,7 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { const auto& patch = code_set.PatchSegment(); const auto& post_patch = code_set.PostPatchSegment(); if (this->IsApplication() && Settings::IsNceEnabled() && patch.size != 0) { - auto& buffer = m_kernel.System().DeviceMemory().buffer; + auto& buffer = kernel.System().DeviceMemory().buffer; const auto& code = code_set.CodeSegment(); buffer.Protect(GetInteger(base_addr + code.addr), code.size, Common::MemoryPermission::Read | Common::MemoryPermission::Execute); @@ -1292,32 +1280,32 @@ void KProcess::LoadModule(CodeSet code_set, KProcessAddress base_addr) { #endif } -void KProcess::InitializeInterfaces() { +void KProcess::InitializeInterfaces(KernelCore& kernel) { m_exclusive_monitor = Core::MakeExclusiveMonitor(this->GetMemory(), Core::Hardware::NUM_CPU_CORES); #ifdef HAS_NCE if (this->IsApplication() && Settings::IsNceEnabled()) { for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) - m_arm_interfaces[i] = std::make_unique(m_kernel.System(), true, i); + m_arm_interfaces[i] = std::make_unique(kernel.System(), true, i); } else #endif if (this->Is64Bit()) { for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { m_arm_interfaces[i] = std::make_unique( - m_kernel.System(), m_kernel.IsMulticore(), this, + kernel.System(), kernel.IsMulticore(), this, static_cast(*m_exclusive_monitor), i); } } else { for (size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { m_arm_interfaces[i] = std::make_unique( - m_kernel.System(), m_kernel.IsMulticore(), this, + kernel.System(), kernel.IsMulticore(), this, static_cast(*m_exclusive_monitor), i); } } } -bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { +bool KProcess::InsertWatchpoint(KernelCore& kernel, KProcessAddress addr, u64 size, DebugWatchpointType type) { const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { return wp.type == DebugWatchpointType::None; })}; @@ -1339,7 +1327,7 @@ bool KProcess::InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointT return true; } -bool KProcess::RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type) { +bool KProcess::RemoveWatchpoint(KernelCore& kernel, KProcessAddress addr, u64 size, DebugWatchpointType type) { const auto watch{std::find_if(m_watchpoints.begin(), m_watchpoints.end(), [&](const auto& wp) { return wp.start_address == addr && wp.end_address == addr + size && wp.type == type; })}; diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 5ddc64754e..ddd9e5eea9 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -139,8 +139,8 @@ private: bool m_is_handle_table_initialized : 1 = false; private: - Result StartTermination(); - void FinishTermination(); + Result StartTermination(KernelCore& kernel); + void FinishTermination(KernelCore& kernel); void PinThread(s32 core_id, KThread* thread) { ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); @@ -160,16 +160,16 @@ public: explicit KProcess(KernelCore& kernel); ~KProcess() override; - Result Initialize(const Svc::CreateProcessParameter& params, KResourceLimit* res_limit, + Result Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, KResourceLimit* res_limit, bool is_real); - Result Initialize(const Svc::CreateProcessParameter& params, const KPageGroup& pg, + Result Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, const KPageGroup& pg, std::span caps, KResourceLimit* res_limit, KMemoryManager::Pool pool, bool immortal); - Result Initialize(const Svc::CreateProcessParameter& params, std::span user_caps, + Result Initialize(KernelCore& kernel, const Svc::CreateProcessParameter& params, std::span user_caps, KResourceLimit* res_limit, KMemoryManager::Pool pool, KProcessAddress aslr_space_start); - void Exit(); + void Exit(KernelCore& kernel); const char* GetName() const { return m_name.data(); @@ -255,7 +255,7 @@ public: m_pointer_buffer_size = size; } - Result Terminate(); + Result Terminate(KernelCore& kernel); bool IsTerminated() const { return m_state == State::Terminated; @@ -292,9 +292,9 @@ public: return m_thread_list; } - bool EnterUserException(); - bool LeaveUserException(); - bool ReleaseUserException(KThread* thread); + bool EnterUserException(KernelCore& kernel); + bool LeaveUserException(KernelCore& kernel); + bool ReleaseUserException(KernelCore& kernel, KThread* thread); KThread* GetPinnedThread(s32 core_id) const { ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); @@ -309,10 +309,10 @@ public: return m_resource_limit; } - bool ReserveResource(Svc::LimitableResource which, s64 value); - bool ReserveResource(Svc::LimitableResource which, s64 value, s64 timeout); - void ReleaseResource(Svc::LimitableResource which, s64 value); - void ReleaseResource(Svc::LimitableResource which, s64 value, s64 hint); + bool ReserveResource(KernelCore& kernel, Svc::LimitableResource which, s64 value); + bool ReserveResource(KernelCore& kernel, Svc::LimitableResource which, s64 value, s64 timeout); + void ReleaseResource(KernelCore& kernel, Svc::LimitableResource which, s64 value); + void ReleaseResource(KernelCore& kernel, Svc::LimitableResource which, s64 value, s64 hint); KLightLock& GetStateLock() { return m_state_lock; @@ -335,16 +335,16 @@ public: return m_handle_table; } - size_t GetUsedUserPhysicalMemorySize() const; - size_t GetTotalUserPhysicalMemorySize() const; - size_t GetUsedNonSystemUserPhysicalMemorySize() const; - size_t GetTotalNonSystemUserPhysicalMemorySize() const; + size_t GetUsedUserPhysicalMemorySize(KernelCore& kernel) const; + size_t GetTotalUserPhysicalMemorySize(KernelCore& kernel) const; + size_t GetUsedNonSystemUserPhysicalMemorySize(KernelCore& kernel) const; + size_t GetTotalNonSystemUserPhysicalMemorySize(KernelCore& kernel) const; - Result AddSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); - void RemoveSharedMemory(KSharedMemory* shmem, KProcessAddress address, size_t size); + Result AddSharedMemory(KernelCore& kernel, KSharedMemory* shmem, KProcessAddress address, size_t size); + void RemoveSharedMemory(KernelCore& kernel, KSharedMemory* shmem, KProcessAddress address, size_t size); - Result CreateThreadLocalRegion(KProcessAddress* out); - Result DeleteThreadLocalRegion(KProcessAddress addr); + Result CreateThreadLocalRegion(KernelCore& kernel, KProcessAddress* out); + Result DeleteThreadLocalRegion(KernelCore& kernel, KProcessAddress addr); KProcessAddress GetProcessLocalRegionAddress() const { return m_plr_address; @@ -368,8 +368,8 @@ public: ++m_schedule_count; } - void IncrementRunningThreadCount(); - void DecrementRunningThreadCount(); + void IncrementRunningThreadCount(KernelCore& kernel); + void DecrementRunningThreadCount(KernelCore& kernel); size_t GetRequiredSecureMemorySizeNonDefault() const { if (!this->IsDefaultApplicationSystemResource() && m_system_resource->IsSecureResource()) { @@ -414,11 +414,9 @@ public: } void ClearRunningThread(KThread* thread) { - for (size_t i = 0; i < m_running_threads.size(); ++i) { - if (m_running_threads[i] == thread) { + for (size_t i = 0; i < m_running_threads.size(); ++i) + if (m_running_threads[i] == thread) m_running_threads[i] = nullptr; - } - } } const KSystemResource& GetSystemResource() const { @@ -445,30 +443,27 @@ public: return m_running_thread_switch_counts[core]; } - void RegisterThread(KThread* thread); - void UnregisterThread(KThread* thread); + void RegisterThread(KernelCore& kernel, KThread* thread); + void UnregisterThread(KernelCore& kernel, KThread* thread); + Result Run(KernelCore& kernel, s32 priority, size_t stack_size); + Result Reset(KernelCore& kernel); - Result Run(s32 priority, size_t stack_size); - - Result Reset(); - - void SetDebugBreak() { + void SetDebugBreak(KernelCore& kernel) { if (m_state == State::RunningAttached) { - this->ChangeState(State::DebugBreak); + this->ChangeState(kernel, State::DebugBreak); } } - void SetAttached() { + void SetAttached(KernelCore& kernel) { if (m_state == State::DebugBreak) { - this->ChangeState(State::RunningAttached); + this->ChangeState(kernel, State::RunningAttached); } } - Result SetActivity(Svc::ProcessActivity activity); - - void PinCurrentThread(); - void UnpinCurrentThread(); - void UnpinThread(KThread* thread); + Result SetActivity(KernelCore& kernel, Svc::ProcessActivity activity); + void PinCurrentThread(KernelCore& kernel); + void UnpinCurrentThread(KernelCore& kernel); + void UnpinThread(KernelCore& kernel, KThread* thread); void SignalConditionVariable(uintptr_t cv_key, int32_t count) { return m_cond_var.Signal(cv_key, count); @@ -478,19 +473,17 @@ public: R_RETURN(m_cond_var.Wait(address, cv_key, tag, ns)); } - Result SignalAddressArbiter(uintptr_t address, Svc::SignalType signal_type, s32 value, - s32 count) { + Result SignalAddressArbiter(uintptr_t address, Svc::SignalType signal_type, s32 value, s32 count) { R_RETURN(m_address_arbiter.SignalToAddress(address, signal_type, value, count)); } - Result WaitAddressArbiter(uintptr_t address, Svc::ArbitrationType arb_type, s32 value, - s64 timeout) { + Result WaitAddressArbiter(uintptr_t address, Svc::ArbitrationType arb_type, s32 value, s64 timeout) { R_RETURN(m_address_arbiter.WaitForAddress(address, arb_type, value, timeout)); } - Result GetThreadList(s32* out_num_threads, KProcessAddress out_thread_ids, s32 max_out_count); + Result GetThreadList(KernelCore& kernel, s32* out_num_threads, KProcessAddress out_thread_ids, s32 max_out_count); - static void Switch(KProcess* cur_process, KProcess* next_process); + static void Switch(KernelCore& kernel, KProcess* cur_process, KProcess* next_process); #ifdef HAS_NCE ankerl::unordered_dense::map& GetPostHandlers() noexcept { @@ -504,22 +497,21 @@ public: public: // Attempts to insert a watchpoint into a free slot. Returns false if none are available. - bool InsertWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); + bool InsertWatchpoint(KernelCore& kernel, KProcessAddress addr, u64 size, DebugWatchpointType type); // Attempts to remove the watchpoint specified by the given parameters. - bool RemoveWatchpoint(KProcessAddress addr, u64 size, DebugWatchpointType type); + bool RemoveWatchpoint(KernelCore& kernel, KProcessAddress addr, u64 size, DebugWatchpointType type); const std::array& GetWatchpoints() const { return m_watchpoints; } public: - Result LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size, - KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl); + Result LoadFromMetadata(KernelCore& kernel, const FileSys::ProgramMetadata& metadata, std::size_t code_size, KProcessAddress aslr_space_start, size_t aslr_space_offset, bool is_hbl); - void LoadModule(CodeSet code_set, KProcessAddress base_addr); + void LoadModule(KernelCore& kernel, CodeSet code_set, KProcessAddress base_addr); - void InitializeInterfaces(); + void InitializeInterfaces(KernelCore& kernel); Core::Memory::Memory& GetMemory() { return m_memory; @@ -535,9 +527,9 @@ public: return m_is_initialized; } - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} - void Finalize() override; + void Finalize(KernelCore& kernel) override; u64 GetIdImpl() const { return this->GetProcessId(); @@ -546,34 +538,34 @@ public: return this->GetIdImpl(); } - virtual bool IsSignaled() const override { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + virtual bool IsSignaled(KernelCore& kernel) const override { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); return m_is_signaled; } - void DoWorkerTaskImpl(); + void DoWorkerTaskImpl(KernelCore& kernel); private: - void ChangeState(State new_state) { + void ChangeState(KernelCore& kernel, State new_state) { if (m_state != new_state) { m_state = new_state; m_is_signaled = true; - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } - Result InitializeHandleTable(s32 size) { + Result InitializeHandleTable(KernelCore& kernel, s32 size) { // Try to initialize the handle table. - R_TRY(m_handle_table.Initialize(m_kernel, size)); + R_TRY(m_handle_table.Initialize(kernel, size)); // We succeeded, so note that we did. m_is_handle_table_initialized = true; R_SUCCEED(); } - void FinalizeHandleTable() { + void FinalizeHandleTable(KernelCore& kernel) { // Finalize the table. - m_handle_table.Finalize(m_kernel); + m_handle_table.Finalize(kernel); // Note that the table is finalized. m_is_handle_table_initialized = false; diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index c30662666b..a00941bc1e 100644 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,50 +18,45 @@ KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kern KReadableEvent::~KReadableEvent() = default; -void KReadableEvent::Initialize(KEvent* parent) { +void KReadableEvent::Initialize(KernelCore& kernel, KEvent* parent) { m_is_signaled = false; m_parent = parent; - if (m_parent != nullptr) { - m_parent->Open(); + m_parent->Open(kernel); } } -bool KReadableEvent::IsSignaled() const { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); - +bool KReadableEvent::IsSignaled(KernelCore& kernel) const { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); return m_is_signaled; } -void KReadableEvent::Destroy() { +void KReadableEvent::Destroy(KernelCore& kernel) { if (m_parent) { { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; m_parent->OnReadableEventDestroyed(); } - m_parent->Close(); + m_parent->Close(kernel); } } -Result KReadableEvent::Signal() { - KScopedSchedulerLock lk{m_kernel}; - +Result KReadableEvent::Signal(KernelCore& kernel) { + KScopedSchedulerLock lk{kernel}; if (!m_is_signaled) { m_is_signaled = true; - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } - R_SUCCEED(); } -Result KReadableEvent::Clear() { - this->Reset(); - +Result KReadableEvent::Clear(KernelCore& kernel) { + this->Reset(kernel); R_SUCCEED(); } -Result KReadableEvent::Reset() { - KScopedSchedulerLock lk{m_kernel}; +Result KReadableEvent::Reset(KernelCore& kernel) { + KScopedSchedulerLock lk{kernel}; R_UNLESS(m_is_signaled, ResultInvalidState); diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index d2ec363233..63a6e8de60 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -20,19 +23,17 @@ public: explicit KReadableEvent(KernelCore& kernel); ~KReadableEvent() override; - void Initialize(KEvent* parent); + void Initialize(KernelCore& kernel, KEvent* parent); KEvent* GetParent() const { return m_parent; } - Result Signal(); - Result Clear(); - - bool IsSignaled() const override; - void Destroy() override; - - Result Reset(); + Result Signal(KernelCore& kernel); + Result Clear(KernelCore& kernel); + bool IsSignaled(KernelCore& kernel) const override; + void Destroy(KernelCore& kernel) override; + Result Reset(KernelCore& kernel); private: bool m_is_signaled{}; diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index e886f97ebd..1a2c92a665 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.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 2020 yuzu Emulator Project @@ -16,12 +16,15 @@ namespace Kernel { constexpr s64 DefaultTimeout = 10000000000; // 10 seconds KResourceLimit::KResourceLimit(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock{m_kernel}, m_cond_var{m_kernel} {} + : KAutoObjectWithSlabHeapAndContainer{kernel} + , m_lock{kernel} + , m_cond_var{kernel} +{} KResourceLimit::~KResourceLimit() = default; void KResourceLimit::Initialize() {} -void KResourceLimit::Finalize() {} +void KResourceLimit::Finalize(KernelCore& kernel) {} s64 KResourceLimit::GetLimitValue(LimitableResource which) const { const auto index = static_cast(which); @@ -87,11 +90,11 @@ Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { R_SUCCEED(); } -bool KResourceLimit::Reserve(LimitableResource which, s64 value) { - return Reserve(which, value, m_kernel.HardwareTimer().GetTick() + DefaultTimeout); +bool KResourceLimit::Reserve(KernelCore& kernel, LimitableResource which, s64 value) { + return Reserve(kernel, which, value, kernel.HardwareTimer().GetTick() + DefaultTimeout); } -bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { +bool KResourceLimit::Reserve(KernelCore& kernel, LimitableResource which, s64 value, s64 timeout) { ASSERT(value >= 0); const auto index = static_cast(which); KScopedLightLock lk(m_lock); @@ -119,7 +122,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { } if (m_current_hints[index] + value <= m_limit_values[index] && - (timeout < 0 || m_kernel.HardwareTimer().GetTick() < timeout)) { + (timeout < 0 || kernel.HardwareTimer().GetTick() < timeout)) { m_waiter_count++; m_cond_var.Wait(std::addressof(m_lock), timeout, false); m_waiter_count--; @@ -131,11 +134,11 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { return false; } -void KResourceLimit::Release(LimitableResource which, s64 value) { - Release(which, value, value); +void KResourceLimit::Release(KernelCore& kernel, LimitableResource which, s64 value) { + Release(kernel, which, value, value); } -void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { +void KResourceLimit::Release(KernelCore& kernel, LimitableResource which, s64 value, s64 hint) { ASSERT(value >= 0); ASSERT(hint >= 0); diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index b733ec8f81..eb45d23bab 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -32,7 +35,7 @@ public: ~KResourceLimit() override; void Initialize(); - void Finalize() override; + void Finalize(KernelCore& kernel) override; s64 GetLimitValue(LimitableResource which) const; s64 GetCurrentValue(LimitableResource which) const; @@ -41,12 +44,12 @@ public: Result SetLimitValue(LimitableResource which, s64 value); - bool Reserve(LimitableResource which, s64 value); - bool Reserve(LimitableResource which, s64 value, s64 timeout); - void Release(LimitableResource which, s64 value); - void Release(LimitableResource which, s64 value, s64 hint); + bool Reserve(KernelCore& kernel, LimitableResource which, s64 value); + bool Reserve(KernelCore& kernel, LimitableResource which, s64 value, s64 timeout); + void Release(KernelCore& kernel, LimitableResource which, s64 value); + void Release(KernelCore& kernel, LimitableResource which, s64 value, s64 hint); - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} private: using ResourceArray = std::array(LimitableResource::Count)>; diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 4b76e18950..2c4d505d77 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -57,7 +57,7 @@ void KScheduler::RequestScheduleOnInterrupt() { void KScheduler::DisableScheduling(KernelCore& kernel) { ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() >= 0); - GetCurrentThread(kernel).DisableDispatch(); + GetCurrentThread(kernel).DisableDispatch(kernel); } void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduling) { @@ -74,7 +74,7 @@ void KScheduler::EnableScheduling(KernelCore& kernel, u64 cores_needing_scheduli scheduler->RescheduleOtherCores(cores_needing_scheduling); if (GetCurrentThread(kernel).GetDisableDispatchCount() > 1) { - GetCurrentThread(kernel).EnableDispatch(); + GetCurrentThread(kernel).EnableDispatch(kernel); } else { scheduler->RescheduleCurrentCore(); } @@ -85,10 +85,10 @@ void KScheduler::RescheduleCurrentHLEThread(KernelCore& kernel) { ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() == 1); // Ensure dummy threads that are waiting block. - GetCurrentThread(kernel).DummyThreadBeginWait(); + GetCurrentThread(kernel).DummyThreadBeginWait(kernel); ASSERT(GetCurrentThread(kernel).GetState() != ThreadState::Waiting); - GetCurrentThread(kernel).EnableDispatch(); + GetCurrentThread(kernel).EnableDispatch(kernel); } u64 KScheduler::UpdateHighestPriorityThreads(KernelCore& kernel) { @@ -107,13 +107,13 @@ void KScheduler::Schedule() { } void KScheduler::ScheduleOnInterrupt() { - GetCurrentThread(m_kernel).DisableDispatch(); + GetCurrentThread(m_kernel).DisableDispatch(m_kernel); Schedule(); - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } void KScheduler::PreemptSingleCore() { - GetCurrentThread(m_kernel).DisableDispatch(); + GetCurrentThread(m_kernel).DisableDispatch(m_kernel); auto* thread = GetCurrentThreadPointer(m_kernel); auto& previous_scheduler = m_kernel.Scheduler(thread->GetCurrentCore()); @@ -121,14 +121,14 @@ void KScheduler::PreemptSingleCore() { Common::Fiber::YieldTo(thread->GetHostContext(), *m_switch_fiber); - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } void KScheduler::RescheduleCurrentCore() { ASSERT(!m_kernel.IsPhantomModeForSingleCore()); ASSERT(GetCurrentThread(m_kernel).GetDisableDispatchCount() == 1); - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); if (m_state.needs_scheduling.load()) { // Disable interrupts, and then check again if rescheduling is needed. @@ -141,9 +141,9 @@ void KScheduler::RescheduleCurrentCore() { void KScheduler::RescheduleCurrentCoreImpl() { // Check that scheduling is needed. if (m_state.needs_scheduling.load()) [[likely]] { - GetCurrentThread(m_kernel).DisableDispatch(); + GetCurrentThread(m_kernel).DisableDispatch(m_kernel); Schedule(); - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } } @@ -179,7 +179,7 @@ void KScheduler::Activate() { } void KScheduler::OnThreadStart() { - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { @@ -319,13 +319,13 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) { } // HACK: any waiting dummy threads can wake up now. - kernel.GlobalSchedulerContext().WakeupWaitingDummyThreads(); + kernel.GlobalSchedulerContext().WakeupWaitingDummyThreads(kernel); // HACK: if we are a dummy thread, and we need to go sleep, indicate // that for when the lock is released. KThread* const cur_thread = GetCurrentThreadPointer(kernel); if (cur_thread->IsDummyThread() && cur_thread->GetState() != ThreadState::Runnable) { - cur_thread->RequestDummyThreadWait(); + cur_thread->RequestDummyThreadWait(kernel); } return cores_needing_scheduling; @@ -386,7 +386,7 @@ void KScheduler::SwitchThread(KThread* next_thread) { // cpu::SwitchThreadLocalRegion(GetInteger(next_thread->GetThreadLocalRegionAddress())); // Update the thread's cpu time differential in TLS, if relevant. - next_thread->UpdateTlsThreadCpuTime(cur_tick); + next_thread->UpdateTlsThreadCpuTime(m_kernel, cur_tick); } void KScheduler::ScheduleImpl() { diff --git a/src/core/hle/kernel/k_scoped_resource_reservation.h b/src/core/hle/kernel/k_scoped_resource_reservation.h index 2cc464612a..4fc66af725 100644 --- a/src/core/hle/kernel/k_scoped_resource_reservation.h +++ b/src/core/hle/kernel/k_scoped_resource_reservation.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,34 +14,42 @@ namespace Kernel { class KScopedResourceReservation { public: - explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v, s64 timeout) - : m_limit(l), m_value(v), m_resource(r) { + explicit KScopedResourceReservation(KernelCore& kernel, KResourceLimit* l, LimitableResource r, s64 v, s64 timeout) + : m_kernel{kernel} + , m_limit(l) + , m_value(v) + , m_resource(r) + { if (m_limit && m_value) { - m_succeeded = m_limit->Reserve(m_resource, m_value, timeout); + m_succeeded = m_limit->Reserve(kernel, m_resource, m_value, timeout); } else { m_succeeded = true; } } - explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v = 1) - : m_limit(l), m_value(v), m_resource(r) { + explicit KScopedResourceReservation(KernelCore& kernel, KResourceLimit* l, LimitableResource r, s64 v = 1) + : m_kernel{kernel} + , m_limit(l) + , m_value(v) + , m_resource(r) + { if (m_limit && m_value) { - m_succeeded = m_limit->Reserve(m_resource, m_value); + m_succeeded = m_limit->Reserve(kernel, m_resource, m_value); } else { m_succeeded = true; } } - explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v, s64 t) - : KScopedResourceReservation(p->GetResourceLimit(), r, v, t) {} + explicit KScopedResourceReservation(KernelCore& kernel, const KProcess* p, LimitableResource r, s64 v, s64 t) + : KScopedResourceReservation(kernel, p->GetResourceLimit(), r, v, t) {} - explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v = 1) - : KScopedResourceReservation(p->GetResourceLimit(), r, v) {} + explicit KScopedResourceReservation(KernelCore& kernel, const KProcess* p, LimitableResource r, s64 v = 1) + : KScopedResourceReservation(kernel, p->GetResourceLimit(), r, v) {} ~KScopedResourceReservation() noexcept { if (m_limit && m_value && m_succeeded) { // Resource was not committed, release the reservation. - m_limit->Release(m_resource, m_value); + m_limit->Release(m_kernel, m_resource, m_value); } } @@ -52,6 +63,7 @@ public: } private: + KernelCore& m_kernel; KResourceLimit* m_limit{}; s64 m_value{}; LimitableResource m_resource{}; diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp index bb6632f58e..dad6ef0678 100644 --- a/src/core/hle/kernel/k_server_port.cpp +++ b/src/core/hle/kernel/k_server_port.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -15,18 +18,18 @@ namespace Kernel { KServerPort::KServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {} KServerPort::~KServerPort() = default; -void KServerPort::Initialize(KPort* parent) { +void KServerPort::Initialize(KernelCore& kernel, KPort* parent) { // Set member variables. m_parent = parent; } -bool KServerPort::IsLight() const { +bool KServerPort::IsLight(KernelCore& kernel) const { return this->GetParent()->IsLight(); } -void KServerPort::CleanupSessions() { +void KServerPort::CleanupSessions(KernelCore& kernel) { // Ensure our preconditions are met. - if (this->IsLight()) { + if (this->IsLight(kernel)) { ASSERT(m_session_list.empty()); } else { ASSERT(m_light_session_list.empty()); @@ -37,7 +40,7 @@ void KServerPort::CleanupSessions() { // Get the last session in the list. KServerSession* session = nullptr; { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (!m_session_list.empty()) { session = std::addressof(m_session_list.front()); m_session_list.pop_front(); @@ -46,7 +49,7 @@ void KServerPort::CleanupSessions() { // Close the session. if (session != nullptr) { - session->Close(); + session->Close(kernel); } else { break; } @@ -57,7 +60,7 @@ void KServerPort::CleanupSessions() { // Get the last session in the list. KLightServerSession* session = nullptr; { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (!m_light_session_list.empty()) { session = std::addressof(m_light_session_list.front()); m_light_session_list.pop_front(); @@ -66,60 +69,60 @@ void KServerPort::CleanupSessions() { // Close the session. if (session != nullptr) { - session->Close(); + session->Close(kernel); } else { break; } } } -void KServerPort::Destroy() { +void KServerPort::Destroy(KernelCore& kernel) { // Note with our parent that we're closed. - m_parent->OnServerClosed(); + m_parent->OnServerClosed(kernel); // Perform necessary cleanup of our session lists. - this->CleanupSessions(); + this->CleanupSessions(kernel); // Close our reference to our parent. - m_parent->Close(); + m_parent->Close(kernel); } -bool KServerPort::IsSignaled() const { - if (this->IsLight()) { +bool KServerPort::IsSignaled(KernelCore& kernel) const { + if (this->IsLight(kernel)) { return !m_light_session_list.empty(); } else { return !m_session_list.empty(); } } -void KServerPort::EnqueueSession(KServerSession* session) { - ASSERT(!this->IsLight()); +void KServerPort::EnqueueSession(KernelCore& kernel, KServerSession* session) { + ASSERT(!this->IsLight(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Add the session to our queue. m_session_list.push_back(*session); if (m_session_list.size() == 1) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } -void KServerPort::EnqueueSession(KLightServerSession* session) { - ASSERT(this->IsLight()); +void KServerPort::EnqueueSession(KernelCore& kernel, KLightServerSession* session) { + ASSERT(this->IsLight(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Add the session to our queue. m_light_session_list.push_back(*session); if (m_light_session_list.size() == 1) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } -KServerSession* KServerPort::AcceptSession() { - ASSERT(!this->IsLight()); +KServerSession* KServerPort::AcceptSession(KernelCore& kernel) { + ASSERT(!this->IsLight(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Return the first session in the list. if (m_session_list.empty()) { @@ -131,10 +134,10 @@ KServerSession* KServerPort::AcceptSession() { return session; } -KLightServerSession* KServerPort::AcceptLightSession() { - ASSERT(this->IsLight()); +KLightServerSession* KServerPort::AcceptLightSession(KernelCore& kernel) { + ASSERT(this->IsLight(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Return the first session in the list. if (m_light_session_list.empty()) { diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h index 72fdb6734a..5996a3a3ee 100644 --- a/src/core/hle/kernel/k_server_port.h +++ b/src/core/hle/kernel/k_server_port.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -26,29 +29,29 @@ public: explicit KServerPort(KernelCore& kernel); ~KServerPort() override; - void Initialize(KPort* parent); + void Initialize(KernelCore& kernel, KPort* parent); - void EnqueueSession(KServerSession* session); - void EnqueueSession(KLightServerSession* session); + void EnqueueSession(KernelCore& kernel, KServerSession* session); + void EnqueueSession(KernelCore& kernel, KLightServerSession* session); - KServerSession* AcceptSession(); - KLightServerSession* AcceptLightSession(); + KServerSession* AcceptSession(KernelCore& kernel); + KLightServerSession* AcceptLightSession(KernelCore& kernel); const KPort* GetParent() const { return m_parent; } - bool IsLight() const; + bool IsLight(KernelCore& kernel) const; // Overridden virtual functions. - void Destroy() override; - bool IsSignaled() const override; + void Destroy(KernelCore& kernel) override; + bool IsSignaled(KernelCore& kernel) const override; private: using SessionList = Common::IntrusiveListBaseTraits::ListType; using LightSessionList = Common::IntrusiveListBaseTraits::ListType; - void CleanupSessions(); + void CleanupSessions(KernelCore& kernel); SessionList m_session_list{}; LightSessionList m_light_session_list{}; diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index b35b9e0bb8..e3cfe6b6c2 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -554,7 +554,7 @@ Result ReceiveMessage(KernelCore& kernel, bool& recv_list_broken, uint64_t dst_m recv_list_broken = false; // Set the server process for the request. - request->SetServerProcess(std::addressof(dst_process)); + request->SetServerProcess(kernel, std::addressof(dst_process)); // Determine the message buffers. u32 *dst_msg_ptr, *src_msg_ptr; @@ -1076,19 +1076,17 @@ void ReplyAsyncError(KProcess* to_process, uint64_t to_msg_buf, size_t to_msg_bu } // namespace KServerSession::KServerSession(KernelCore& kernel) - : KSynchronizationObject{kernel}, m_lock{m_kernel} {} + : KSynchronizationObject{kernel}, m_lock{kernel} {} KServerSession::~KServerSession() = default; -void KServerSession::Destroy() { - m_parent->OnServerClosed(); - - this->CleanupRequests(); - - m_parent->Close(); +void KServerSession::Destroy(KernelCore& kernel) { + m_parent->OnServerClosed(kernel); + this->CleanupRequests(kernel); + m_parent->Close(kernel); } -Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server_buffer_size, +Result KServerSession::ReceiveRequest(KernelCore& kernel, uintptr_t server_message, uintptr_t server_buffer_size, KPhysicalAddress server_message_paddr, std::shared_ptr* out_context, std::weak_ptr manager) { @@ -1100,7 +1098,7 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server KThread* client_thread; { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Ensure that we can service the request. R_UNLESS(!m_parent->IsClientClosed(), ResultSessionClosed); @@ -1120,11 +1118,11 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server R_UNLESS(client_thread != nullptr, ResultSessionClosed); // Open the client thread. - client_thread->Open(); + client_thread->Open(kernel); } SCOPE_EXIT { - client_thread->Close(); + client_thread->Close(kernel); }; // Set the request as our current. @@ -1146,13 +1144,13 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server Core::Memory::Memory& memory{client_thread->GetOwnerProcess()->GetMemory()}; u32* cmd_buf{reinterpret_cast(memory.GetPointer(client_message))}; *out_context = - std::make_shared(m_kernel, memory, this, client_thread); + std::make_shared(kernel, memory, this, client_thread); (*out_context)->SetSessionRequestManager(manager); (*out_context)->PopulateFromIncomingCommandBuffer(cmd_buf); // We succeeded. R_SUCCEED(); } else { - result = ReceiveMessage(m_kernel, recv_list_broken, server_message, server_buffer_size, + result = ReceiveMessage(kernel, recv_list_broken, server_message, server_buffer_size, server_message_paddr, *client_thread, client_message, client_buffer_size, this, request); } @@ -1164,11 +1162,11 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server // Clear the current request. { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); ASSERT(m_current_request == request); m_current_request = nullptr; if (!m_request_list.empty()) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } @@ -1176,7 +1174,7 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server { // After we reply, close our reference to the request. SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // Get the event to check whether the request is async. @@ -1195,13 +1193,13 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server client_pt.UnlockForIpcUserBuffer(client_message, client_buffer_size); // Signal the event. - event->Signal(); + event->Signal(kernel); } else { // End the client thread's wait. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); if (!client_thread->IsTerminationRequested()) { - client_thread->EndWait(result_for_client); + client_thread->EndWait(kernel, result_for_client); } } } @@ -1217,7 +1215,7 @@ Result KServerSession::ReceiveRequest(uintptr_t server_message, uintptr_t server R_RETURN(result); } -Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buffer_size, +Result KServerSession::SendReply(KernelCore& kernel, uintptr_t server_message, uintptr_t server_buffer_size, KPhysicalAddress server_message_paddr, bool is_hle) { // Lock the session. KScopedLightLock lk{m_lock}; @@ -1225,7 +1223,7 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff // Get the request. KSessionRequest* request; { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Get the current request. request = m_current_request; @@ -1234,13 +1232,13 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff // Clear the current request, since we're processing it. m_current_request = nullptr; if (!m_request_list.empty()) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } } // Close reference to the request once we're done processing it. SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // Extract relevant information from the request. @@ -1259,7 +1257,7 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff // HLE servers write directly to a pointer to the thread command buffer. Therefore // the reply has already been written in this case. } else { - result = SendMessage(m_kernel, server_message, server_buffer_size, server_message_paddr, + result = SendMessage(kernel, server_message, server_buffer_size, server_message_paddr, *client_thread, client_message, client_buffer_size, this, request); } } else if (!is_hle) { @@ -1271,7 +1269,7 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff (client_process != nullptr) ? std::addressof(client_process->GetPageTable()) : nullptr; // Cleanup server handles. - result = CleanupServerHandles(m_kernel, server_message, server_buffer_size, + result = CleanupServerHandles(kernel, server_message, server_buffer_size, server_message_paddr); // Cleanup mappings. @@ -1309,13 +1307,13 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); // Signal the event. - event->Signal(); + event->Signal(kernel); } else { // End the client thread's wait. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (!client_thread->IsTerminationRequested()) { - client_thread->EndWait(client_result); + client_thread->EndWait(kernel, client_result); } } } @@ -1323,45 +1321,45 @@ Result KServerSession::SendReply(uintptr_t server_message, uintptr_t server_buff R_RETURN(result); } -Result KServerSession::OnRequest(KSessionRequest* request) { +Result KServerSession::OnRequest(KernelCore& kernel, KSessionRequest* request) { // Create the wait queue. - ThreadQueueImplForKServerSessionRequest wait_queue{m_kernel}; + ThreadQueueImplForKServerSessionRequest wait_queue{kernel}; { // Lock the scheduler. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Ensure that we can handle new requests. R_UNLESS(!m_parent->IsServerClosed(), ResultSessionClosed); // Check that we're not terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), ResultTerminationRequested); + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Get whether we're empty. const bool was_empty = m_request_list.empty(); // Add the request to the list. - request->Open(); + request->Open(kernel); m_request_list.push_back(*request); // If we were empty, signal. if (was_empty) { - this->NotifyAvailable(); + this->NotifyAvailable(kernel); } // If we have a request event, this is asynchronous, and we don't need to wait. R_SUCCEED_IF(request->GetEvent() != nullptr); // This is a synchronous request, so we should wait for our request to complete. - GetCurrentThread(m_kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } - return GetCurrentThread(m_kernel).GetWaitResult(); + return GetCurrentThread(kernel).GetWaitResult(); } -bool KServerSession::IsSignaled() const { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); +bool KServerSession::IsSignaled(KernelCore& kernel) const { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // If the client is closed, we're always signaled. if (m_parent->IsClientClosed()) { @@ -1372,7 +1370,7 @@ bool KServerSession::IsSignaled() const { return !m_request_list.empty() && m_current_request == nullptr; } -void KServerSession::CleanupRequests() { +void KServerSession::CleanupRequests(KernelCore& kernel) { KScopedLightLock lk(m_lock); // Clean up any pending requests. @@ -1380,7 +1378,7 @@ void KServerSession::CleanupRequests() { // Get the next request. KSessionRequest* request = nullptr; { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (m_current_request) { // Choose the current request if we have one. @@ -1400,7 +1398,7 @@ void KServerSession::CleanupRequests() { // Close a reference to the request once it's cleaned up. SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // Extract relevant information from the request. @@ -1430,20 +1428,20 @@ void KServerSession::CleanupRequests() { client_page_table->UnlockForIpcUserBuffer(client_message, client_buffer_size); // Signal the event. - event->Signal(); + event->Signal(kernel); } else { // End the client thread's wait. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (!client_thread->IsTerminationRequested()) { - client_thread->EndWait(ResultSessionClosed); + client_thread->EndWait(kernel, ResultSessionClosed); } } } } } -void KServerSession::OnClientClosed() { +void KServerSession::OnClientClosed(KernelCore& kernel) { KScopedLightLock lk{m_lock}; // Handle any pending requests. @@ -1458,12 +1456,12 @@ void KServerSession::OnClientClosed() { // Get the next request. { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; if (m_current_request != nullptr && m_current_request != prev_request) { // Set the request, open a reference as we process it. request = m_current_request; - request->Open(); + request->Open(kernel); cur_request = true; // Get thread and event for the request. @@ -1499,14 +1497,14 @@ void KServerSession::OnClientClosed() { // Ensure that we close the request when done. SCOPE_EXIT { - request->Close(); + request->Close(kernel); }; // If we're terminating, close a reference to the thread and event. if (terminate) { - thread->Close(); + thread->Close(kernel); if (event != nullptr) { - event->Close(); + event->Close(kernel); } } @@ -1530,12 +1528,12 @@ void KServerSession::OnClientClosed() { client_pt.UnlockForIpcUserBuffer(request->GetAddress(), request->GetSize()); // Signal the event. - event->Signal(); + event->Signal(kernel); } } // Notify. - this->NotifyAvailable(ResultSessionClosed); + this->NotifyAvailable(kernel, ResultSessionClosed); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index 2876c231b2..217e7dc7be 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -36,7 +39,7 @@ public: explicit KServerSession(KernelCore& kernel); ~KServerSession() override; - void Destroy() override; + void Destroy(KernelCore& kernel) override; void Initialize(KSession* p) { m_parent = p; @@ -46,29 +49,29 @@ public: return m_parent; } - bool IsSignaled() const override; - void OnClientClosed(); + bool IsSignaled(KernelCore& kernel) const override; + void OnClientClosed(KernelCore& kernel); - Result OnRequest(KSessionRequest* request); - Result SendReply(uintptr_t server_message, uintptr_t server_buffer_size, + Result OnRequest(KernelCore& kernel, KSessionRequest* request); + Result SendReply(KernelCore& kernel, uintptr_t server_message, uintptr_t server_buffer_size, KPhysicalAddress server_message_paddr, bool is_hle = false); - Result ReceiveRequest(uintptr_t server_message, uintptr_t server_buffer_size, + Result ReceiveRequest(KernelCore& kernel, uintptr_t server_message, uintptr_t server_buffer_size, KPhysicalAddress server_message_paddr, std::shared_ptr* out_context = nullptr, std::weak_ptr manager = {}); - Result SendReplyHLE() { - R_RETURN(this->SendReply(0, 0, 0, true)); + Result SendReplyHLE(KernelCore& kernel) { + R_RETURN(this->SendReply(kernel, 0, 0, 0, true)); } - Result ReceiveRequestHLE(std::shared_ptr* out_context, + Result ReceiveRequestHLE(KernelCore& kernel, std::shared_ptr* out_context, std::weak_ptr manager) { - R_RETURN(this->ReceiveRequest(0, 0, 0, out_context, manager)); + R_RETURN(this->ReceiveRequest(kernel, 0, 0, 0, out_context, manager)); } private: /// Frees up waiting client sessions when this server session is about to die - void CleanupRequests(); + void CleanupRequests(KernelCore& kernel); /// KSession that owns this KServerSession KSession* m_parent{}; diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp index 4a1f6027ee..58b0d5de67 100644 --- a/src/core/hle/kernel/k_session.cpp +++ b/src/core/hle/kernel/k_session.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -13,12 +16,12 @@ KSession::KSession(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel}, m_server{kernel}, m_client{kernel} {} KSession::~KSession() = default; -void KSession::Initialize(KClientPort* client_port, uintptr_t name) { +void KSession::Initialize(KernelCore& kernel, KClientPort* client_port, uintptr_t name) { // Increment reference count. // Because reference count is one on creation, this will result // in a reference count of two. Thus, when both server and client are closed // this object will be destroyed. - this->Open(); + this->Open(kernel); // Create our sub sessions. KAutoObject::Create(std::addressof(m_server)); @@ -33,45 +36,45 @@ void KSession::Initialize(KClientPort* client_port, uintptr_t name) { m_name = name; // Set our owner process. - m_process = GetCurrentProcessPointer(m_kernel); - m_process->Open(); + m_process = GetCurrentProcessPointer(kernel); + m_process->Open(kernel); // Set our port. m_port = client_port; if (m_port != nullptr) { - m_port->Open(); + m_port->Open(kernel); } // Mark initialized. m_initialized = true; } -void KSession::Finalize() { +void KSession::Finalize(KernelCore& kernel) { if (m_port != nullptr) { - m_port->OnSessionFinalized(); - m_port->Close(); + m_port->OnSessionFinalized(kernel); + m_port->Close(kernel); } } -void KSession::OnServerClosed() { +void KSession::OnServerClosed(KernelCore& kernel) { if (this->GetState() == State::Normal) { this->SetState(State::ServerClosed); m_client.OnServerClosed(); } } -void KSession::OnClientClosed() { +void KSession::OnClientClosed(KernelCore& kernel) { if (this->GetState() == State::Normal) { - SetState(State::ClientClosed); - m_server.OnClientClosed(); + this->SetState(State::ClientClosed); + m_server.OnClientClosed(kernel); } } -void KSession::PostDestroy(uintptr_t arg) { +void KSession::PostDestroy(KernelCore& kernel, uintptr_t arg) { // Release the session count resource the owner process holds. KProcess* owner = reinterpret_cast(arg); - owner->GetResourceLimit()->Release(LimitableResource::SessionCountMax, 1); - owner->Close(); + owner->GetResourceLimit()->Release(kernel, LimitableResource::SessionCountMax, 1); + owner->Close(kernel); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h index 3f4dd5989f..0d77bc1fd4 100644 --- a/src/core/hle/kernel/k_session.h +++ b/src/core/hle/kernel/k_session.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -21,8 +24,8 @@ public: explicit KSession(KernelCore& kernel); ~KSession() override; - void Initialize(KClientPort* port, uintptr_t name); - void Finalize() override; + void Initialize(KernelCore& kernel, KClientPort* port, uintptr_t name); + void Finalize(KernelCore& kernel) override; bool IsInitialized() const override { return m_initialized; @@ -32,11 +35,9 @@ public: return reinterpret_cast(m_process); } - static void PostDestroy(uintptr_t arg); - - void OnServerClosed(); - - void OnClientClosed(); + static void PostDestroy(KernelCore& kernel, uintptr_t arg); + void OnServerClosed(KernelCore& kernel); + void OnClientClosed(KernelCore& kernel); bool IsServerClosed() const { return this->GetState() != State::Normal; @@ -46,8 +47,8 @@ public: return this->GetState() != State::Normal; } - Result OnRequest(KSessionRequest* request) { - R_RETURN(m_server.OnRequest(request)); + Result OnRequest(KernelCore& kernel, KSessionRequest* request) { + R_RETURN(m_server.OnRequest(kernel, request)); } KClientSession& GetClientSession() { diff --git a/src/core/hle/kernel/k_session_request.cpp b/src/core/hle/kernel/k_session_request.cpp index 9a69b4ffc1..25451a3922 100644 --- a/src/core/hle/kernel/k_session_request.cpp +++ b/src/core/hle/kernel/k_session_request.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,7 +21,7 @@ Result KSessionRequest::SessionMappings::PushMap(KProcessAddress client, KProces } else { // Allocate a page for the extra mappings. if (m_mappings == nullptr) { - KPageBuffer* page_buffer = KPageBuffer::Allocate(m_kernel); + KPageBuffer* page_buffer = KPageBuffer::Allocate(kernel); R_UNLESS(page_buffer != nullptr, ResultOutOfMemory); m_mappings = reinterpret_cast(page_buffer); @@ -54,7 +57,7 @@ Result KSessionRequest::SessionMappings::PushExchange(KProcessAddress client, void KSessionRequest::SessionMappings::Finalize() { if (m_mappings) { - KPageBuffer::Free(m_kernel, reinterpret_cast(m_mappings)); + KPageBuffer::Free(kernel, reinterpret_cast(m_mappings)); m_mappings = nullptr; } } diff --git a/src/core/hle/kernel/k_session_request.h b/src/core/hle/kernel/k_session_request.h index 283669e0ac..c788ff5f25 100644 --- a/src/core/hle/kernel/k_session_request.h +++ b/src/core/hle/kernel/k_session_request.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -56,7 +59,7 @@ public: }; public: - explicit SessionMappings(KernelCore& kernel) : m_kernel(kernel) {} + explicit SessionMappings(KernelCore& kernel) : kernel(kernel) {} void Initialize() {} void Finalize(); @@ -155,7 +158,7 @@ public: } private: - KernelCore& m_kernel; + KernelCore& kernel; std::array m_static_mappings{}; Mapping* m_mappings{}; u8 m_num_send{}; @@ -174,26 +177,26 @@ public: return req; } - void Destroy() override { - this->Finalize(); - KSessionRequest::Free(m_kernel, this); + void Destroy(KernelCore& kernel) override { + this->Finalize(kernel); + KSessionRequest::Free(kernel, this); } - void Initialize(KEvent* event, uintptr_t address, size_t size) { + void Initialize(KernelCore& kernel, KEvent* event, uintptr_t address, size_t size) { m_mappings.Initialize(); - m_thread = GetCurrentThreadPointer(m_kernel); + m_thread = GetCurrentThreadPointer(kernel); m_event = event; m_address = address; m_size = size; - m_thread->Open(); + m_thread->Open(kernel); if (m_event != nullptr) { - m_event->Open(); + m_event->Open(kernel); } } - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} KThread* GetThread() const { return m_thread; @@ -211,9 +214,9 @@ public: return m_server; } - void SetServerProcess(KProcess* process) { + void SetServerProcess(KernelCore& kernel, KProcess* process) { m_server = process; - m_server->Open(); + m_server->Open(kernel); } void ClearThread() { @@ -289,17 +292,16 @@ public: private: // NOTE: This is public and virtual in Nintendo's kernel. - void Finalize() override { + void Finalize(KernelCore& kernel) override { m_mappings.Finalize(); - if (m_thread) { - m_thread->Close(); + m_thread->Close(kernel); } if (m_event) { - m_event->Close(); + m_event->Close(kernel); } if (m_server) { - m_server->Close(); + m_server->Close(kernel); } } diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index b457e6cc1e..61f2872560 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -18,7 +18,7 @@ namespace Kernel { KSharedMemory::KSharedMemory(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} KSharedMemory::~KSharedMemory() = default; -Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory, KProcess* owner_process, +Result KSharedMemory::Initialize(KernelCore& kernel, Core::DeviceMemory& device_memory, KProcess* owner_process, Svc::MemoryPermission owner_permission, Svc::MemoryPermission user_permission, std::size_t size) { // Set members. @@ -31,11 +31,10 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory, KProcess* ow const size_t num_pages = Common::DivideUp(size, PageSize); // Get the resource limit. - KResourceLimit* reslimit = m_kernel.GetSystemResourceLimit(); + KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); // Reserve memory for ourselves. - KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemoryMax, - size); + KScopedResourceReservation memory_reservation(kernel, reslimit, LimitableResource::PhysicalMemoryMax, size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); // Allocate the memory. @@ -43,12 +42,11 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory, KProcess* ow //! HACK: Open continuous mapping from sysmodule pool. auto option = KMemoryManager::EncodeOption(KMemoryManager::Pool::Secure, KMemoryManager::Direction::FromBack); - m_physical_address = m_kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, option); + m_physical_address = kernel.MemoryManager().AllocateAndOpenContinuous(num_pages, 1, option); R_UNLESS(m_physical_address != 0, ResultOutOfMemory); //! Insert the result into our page group. - m_page_group.emplace(m_kernel, - std::addressof(m_kernel.GetSystemSystemResource().GetBlockInfoManager())); + m_page_group.emplace(kernel, std::addressof(kernel.GetSystemSystemResource().GetBlockInfoManager())); m_page_group->AddBlock(m_physical_address, num_pages); // Commit our reservation. @@ -56,7 +54,7 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory, KProcess* ow // Set our resource limit. m_resource_limit = reslimit; - m_resource_limit->Open(); + m_resource_limit->Open(kernel); // Mark initialized. m_is_initialized = true; @@ -69,14 +67,14 @@ Result KSharedMemory::Initialize(Core::DeviceMemory& device_memory, KProcess* ow R_SUCCEED(); } -void KSharedMemory::Finalize() { +void KSharedMemory::Finalize(KernelCore& kernel) { // Close and finalize the page group. - m_page_group->Close(m_kernel); + m_page_group->Close(kernel); m_page_group->Finalize(); // Release the memory reservation. - m_resource_limit->Release(LimitableResource::PhysicalMemoryMax, m_size); - m_resource_limit->Close(); + m_resource_limit->Release(kernel, LimitableResource::PhysicalMemoryMax, m_size); + m_resource_limit->Close(kernel); } Result KSharedMemory::Map(KProcess& target_process, KProcessAddress address, std::size_t map_size, diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 54b23d7ac2..3aede457c9 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2014 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -26,7 +29,7 @@ public: explicit KSharedMemory(KernelCore& kernel); ~KSharedMemory() override; - Result Initialize(Core::DeviceMemory& device_memory_, KProcess* owner_process_, + Result Initialize(KernelCore& kernel, Core::DeviceMemory& device_memory_, KProcess* owner_process_, Svc::MemoryPermission owner_permission_, Svc::MemoryPermission user_permission_, std::size_t size_); @@ -66,12 +69,12 @@ public: return m_device_memory->GetPointer(m_physical_address + offset); } - void Finalize() override; + void Finalize(KernelCore& kernel) override; bool IsInitialized() const override { return m_is_initialized; } - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} private: Core::DeviceMemory* m_device_memory{}; diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index 3e5b735b1e..221cab655f 100644 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,12 +21,10 @@ namespace { class ThreadQueueImplForKSynchronizationObjectWait final : public KThreadQueueWithoutEndWait { public: - ThreadQueueImplForKSynchronizationObjectWait(KernelCore& kernel, KSynchronizationObject** o, - KSynchronizationObject::ThreadListNode* n, s32 c) + ThreadQueueImplForKSynchronizationObjectWait(KernelCore& kernel, KSynchronizationObject** o, KSynchronizationObject::ThreadListNode* n, s32 c) : KThreadQueueWithoutEndWait(kernel), m_objects(o), m_nodes(n), m_count(c) {} - void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, - Result wait_result) override { + void NotifyAvailable(KernelCore& kernel, KThread* waiting_thread, KSynchronizationObject* signaled_object, Result wait_result) override { // Determine the sync index, and unlink all nodes. s32 sync_index = -1; for (auto i = 0; i < m_count; ++i) { @@ -43,10 +44,10 @@ public: waiting_thread->ClearCancellable(); // Invoke the base end wait handler. - KThreadQueue::EndWait(waiting_thread, wait_result); + KThreadQueue::EndWait(kernel, waiting_thread, wait_result); } - 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 all nodes from our list. for (auto i = 0; i < m_count; ++i) { m_objects[i]->UnlinkNode(std::addressof(m_nodes[i])); @@ -56,7 +57,7 @@ public: waiting_thread->ClearCancellable(); // 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); } private: @@ -67,9 +68,9 @@ private: } // namespace -void KSynchronizationObject::Finalize() { +void KSynchronizationObject::Finalize(KernelCore& kernel) { this->OnFinalizeSynchronizationObject(); - KAutoObject::Finalize(); + KAutoObject::Finalize(kernel); } Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, @@ -98,7 +99,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, for (auto i = 0; i < num_objects; ++i) { ASSERT(objects[i] != nullptr); - if (objects[i]->IsSignaled()) { + if (objects[i]->IsSignaled(kernel)) { *out_index = i; slp.CancelSleep(); R_THROW(ResultSuccess); @@ -134,7 +135,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, // Wait for an object to be signaled. wait_queue.SetHardwareTimer(timer); - thread->BeginWait(std::addressof(wait_queue)); + thread->BeginWait(kernel, std::addressof(wait_queue)); thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Synchronization); } @@ -149,26 +150,26 @@ KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : KAutoObject KSynchronizationObject::~KSynchronizationObject() = default; -void KSynchronizationObject::NotifyAvailable(Result result) { - KScopedSchedulerLock sl(m_kernel); +void KSynchronizationObject::NotifyAvailable(KernelCore& kernel, Result result) { + KScopedSchedulerLock sl(kernel); // If we're not signaled, we've nothing to notify. - if (!this->IsSignaled()) { + if (!this->IsSignaled(kernel)) { return; } // Iterate over each thread. for (auto* cur_node = m_thread_list_head; cur_node != nullptr; cur_node = cur_node->next) { - cur_node->thread->NotifyAvailable(this, result); + cur_node->thread->NotifyAvailable(kernel, this, result); } } -std::vector KSynchronizationObject::GetWaitingThreadsForDebugging() const { +std::vector KSynchronizationObject::GetWaitingThreadsForDebugging(KernelCore& kernel) const { std::vector threads; // If debugging, dump the list of waiters. { - KScopedSchedulerLock lock(m_kernel); + KScopedSchedulerLock lock(kernel); for (auto* cur_node = m_thread_list_head; cur_node != nullptr; cur_node = cur_node->next) { threads.emplace_back(cur_node->thread); } diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index d55a2673df..4c54a4d2cb 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -24,14 +27,13 @@ public: KThread* thread{}; }; - static Result Wait(KernelCore& kernel, s32* out_index, KSynchronizationObject** objects, - const s32 num_objects, s64 timeout); + static Result Wait(KernelCore& kernel, s32* out_index, KSynchronizationObject** objects, const s32 num_objects, s64 timeout); - void Finalize() override; + void Finalize(KernelCore& kernel) override; - virtual bool IsSignaled() const = 0; + virtual bool IsSignaled(KernelCore& kernel) const = 0; - std::vector GetWaitingThreadsForDebugging() const; + std::vector GetWaitingThreadsForDebugging(KernelCore& kernel) const; void LinkNode(ThreadListNode* node_) { // Link the node to the list. @@ -71,9 +73,9 @@ protected: virtual void OnFinalizeSynchronizationObject() {} - void NotifyAvailable(Result result); - void NotifyAvailable() { - return this->NotifyAvailable(ResultSuccess); + void NotifyAvailable(KernelCore& kernel, Result result); + void NotifyAvailable(KernelCore& kernel) { + return this->NotifyAvailable(kernel, ResultSuccess); } private: diff --git a/src/core/hle/kernel/k_system_resource.cpp b/src/core/hle/kernel/k_system_resource.cpp index b51941faf4..fb664eb57a 100644 --- a/src/core/hle/kernel/k_system_resource.cpp +++ b/src/core/hle/kernel/k_system_resource.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,8 +10,7 @@ namespace Kernel { -Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_limit, - KMemoryManager::Pool pool) { +Result KSecureSystemResource::Initialize(KernelCore& kernel, size_t size, KResourceLimit* resource_limit, KMemoryManager::Pool pool) { // Set members. m_resource_limit = resource_limit; m_resource_size = size; @@ -18,18 +20,17 @@ Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_l const size_t secure_size = this->CalculateRequiredSecureMemorySize(); // Reserve memory for our secure resource. - KScopedResourceReservation memory_reservation( - m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, secure_size); + KScopedResourceReservation memory_reservation(kernel, m_resource_limit, Svc::LimitableResource::PhysicalMemoryMax, secure_size); R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); // Allocate secure memory. - R_TRY(KSystemControl::AllocateSecureMemory(m_kernel, std::addressof(m_resource_address), + R_TRY(KSystemControl::AllocateSecureMemory(kernel, std::addressof(m_resource_address), m_resource_size, static_cast(m_resource_pool))); ASSERT(m_resource_address != 0); // Ensure we clean up the secure memory, if we fail past this point. ON_RESULT_FAILURE { - KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size, + KSystemControl::FreeSecureMemory(kernel, m_resource_address, m_resource_size, static_cast(m_resource_pool)); }; @@ -40,9 +41,9 @@ Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_l // Get resource pointer. KPhysicalAddress resource_paddr = - KPageTable::GetHeapPhysicalAddress(m_kernel, m_resource_address); + KPageTable::GetHeapPhysicalAddress(kernel, m_resource_address); auto* resource = - m_kernel.System().DeviceMemory().GetPointer(resource_paddr); + kernel.System().DeviceMemory().GetPointer(resource_paddr); // Initialize slab heaps. m_dynamic_page_manager.Initialize(m_resource_address + rc_size, m_resource_size - rc_size, @@ -66,7 +67,7 @@ Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_l memory_reservation.Commit(); // Open reference to our resource limit. - m_resource_limit->Open(); + m_resource_limit->Open(kernel); // Set ourselves as initialized. m_is_initialized = true; @@ -74,26 +75,25 @@ Result KSecureSystemResource::Initialize(size_t size, KResourceLimit* resource_l R_SUCCEED(); } -void KSecureSystemResource::Finalize() { +void KSecureSystemResource::Finalize(KernelCore& kernel) { // Check that we have no outstanding allocations. ASSERT(m_memory_block_slab_manager.GetUsed() == 0); ASSERT(m_block_info_manager.GetUsed() == 0); ASSERT(m_page_table_manager.GetUsed() == 0); // Free our secure memory. - KSystemControl::FreeSecureMemory(m_kernel, m_resource_address, m_resource_size, + KSystemControl::FreeSecureMemory(kernel, m_resource_address, m_resource_size, static_cast(m_resource_pool)); // Release the memory reservation. - m_resource_limit->Release(Svc::LimitableResource::PhysicalMemoryMax, + m_resource_limit->Release(kernel, Svc::LimitableResource::PhysicalMemoryMax, this->CalculateRequiredSecureMemorySize()); // Close reference to our resource limit. - m_resource_limit->Close(); + m_resource_limit->Close(kernel); } -size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, - KMemoryManager::Pool pool) { +size_t KSecureSystemResource::CalculateRequiredSecureMemorySize(size_t size, KMemoryManager::Pool pool) { return KSystemControl::CalculateRequiredSecureMemorySize(size, static_cast(pool)); } diff --git a/src/core/hle/kernel/k_system_resource.h b/src/core/hle/kernel/k_system_resource.h index 6ea4821858..c0362497f9 100644 --- a/src/core/hle/kernel/k_system_resource.h +++ b/src/core/hle/kernel/k_system_resource.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -29,7 +32,7 @@ protected: } public: - virtual void Destroy() override { + virtual void Destroy(KernelCore& kernel) override { UNREACHABLE_MSG("KSystemResource::Destroy() was called"); } @@ -93,13 +96,13 @@ public: this->SetSecureResource(); } - Result Initialize(size_t size, KResourceLimit* resource_limit, KMemoryManager::Pool pool); - void Finalize(); + Result Initialize(KernelCore& kernel, size_t size, KResourceLimit* resource_limit, KMemoryManager::Pool pool); + void Finalize(KernelCore& kernel); bool IsInitialized() const { return m_is_initialized; } - static void PostDestroy(uintptr_t arg) {} + static void PostDestroy(KernelCore& kernel, uintptr_t arg) {} size_t CalculateRequiredSecureMemorySize() const { return CalculateRequiredSecureMemorySize(m_resource_size, m_resource_pool); diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 0af315d726..94ad214af1 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -95,12 +95,12 @@ namespace Kernel { explicit ThreadQueueImplForKThreadSetProperty(KernelCore& kernel, KThread::WaiterList* wl) : KThreadQueue(kernel), m_wait_list(wl) {} - 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 from the wait list. m_wait_list->erase(m_wait_list->iterator_to(*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); } private: @@ -113,7 +113,7 @@ namespace Kernel { : KAutoObjectWithSlabHeapAndContainer{kernel}, m_activity_pause_lock{kernel} {} KThread::~KThread() = default; - Result KThread::Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, + Result KThread::Initialize(KernelCore& kernel, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner, ThreadType type) { // Assert parameters are valid. ASSERT((type == ThreadType::Main) || (type == ThreadType::Dummy) || @@ -225,12 +225,12 @@ namespace Kernel { if (owner != nullptr) { // Setup the TLS, if needed. if (type == ThreadType::User) { - R_TRY(owner->CreateThreadLocalRegion(std::addressof(m_tls_address))); + R_TRY(owner->CreateThreadLocalRegion(kernel, std::addressof(m_tls_address))); owner->GetMemory().ZeroBlock(m_tls_address, Svc::ThreadLocalRegionSize); } m_parent = owner; - m_parent->Open(); + m_parent->Open(kernel); } // Initialize thread context. @@ -247,28 +247,28 @@ namespace Kernel { this->SetInExceptionHandler(); // Set thread ID. - m_thread_id = m_kernel.CreateNewThreadID(); + m_thread_id = kernel.CreateNewThreadID(); // We initialized! m_initialized = true; // Register ourselves with our parent process. if (m_parent != nullptr) { - m_parent->RegisterThread(this); + m_parent->RegisterThread(kernel, this); if (m_parent->IsSuspended()) { - RequestSuspend(SuspendType::Process); + RequestSuspend(kernel, SuspendType::Process); } } R_SUCCEED(); } - Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, + Result KThread::InitializeThread(KernelCore& kernel, KThread* thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess* owner, ThreadType type, std::function&& init_func) { // Initialize the thread. - R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); + R_TRY(thread->Initialize(kernel, func, arg, user_stack_top, prio, core, owner, type)); // Initialize emulation parameters. thread->m_host_context = std::make_shared(std::move(init_func)); @@ -276,9 +276,9 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) { + Result KThread::InitializeDummyThread(Core::System& system, KThread* thread, KProcess* owner) { // Initialize the thread. - R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); + R_TRY(thread->Initialize(system.Kernel(), {}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); // Initialize emulation parameters. thread->m_stack_parameters.disable_count = 0; @@ -287,18 +287,18 @@ namespace Kernel { } Result KThread::InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core) { - R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, system.GetCpuManager().GetGuestActivateFunc())); } Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { - R_RETURN(InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, system.GetCpuManager().GetIdleThreadStartFunc())); } Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, KThreadFunction func, uintptr_t arg, s32 virt_core) { - R_RETURN(InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, + R_RETURN(InitializeThread(system.Kernel(), thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, system.GetCpuManager().GetShutdownThreadStartFunc())); } @@ -307,7 +307,7 @@ namespace Kernel { uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner) { system.Kernel().GlobalSchedulerContext().AddThread(thread); - R_RETURN(InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, + R_RETURN(InitializeThread(system.Kernel(), thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType::User, system.GetCpuManager().GetGuestThreadFunc())); } @@ -326,35 +326,35 @@ namespace Kernel { Svc::ExitThread(system); }}; - R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority, + R_RETURN(InitializeThread(system.Kernel(), thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority, std::move(func2))); } - void KThread::PostDestroy(uintptr_t arg) { + void KThread::PostDestroy(KernelCore& kernel, uintptr_t arg) { KProcess* owner = reinterpret_cast(arg & ~1ULL); const bool resource_limit_release_hint = (arg & 1); const s64 hint_value = (resource_limit_release_hint ? 0 : 1); if (owner != nullptr) { - owner->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1, hint_value); - owner->Close(); + owner->GetResourceLimit()->Release(kernel, LimitableResource::ThreadCountMax, 1, hint_value); + owner->Close(kernel); } } - void KThread::Finalize() { + void KThread::Finalize(KernelCore& kernel) { // If the thread has an owner process, unregister it. if (m_parent != nullptr) { - m_parent->UnregisterThread(this); + m_parent->UnregisterThread(kernel, this); } // If the thread has a local region, delete it. if (m_tls_address != 0) { - ASSERT(m_parent->DeleteThreadLocalRegion(m_tls_address).IsSuccess()); + ASSERT(m_parent->DeleteThreadLocalRegion(kernel, m_tls_address).IsSuccess()); } // Release any waiters. { ASSERT(m_waiting_lock_info == nullptr); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Check that we have no kernel waiters. ASSERT(m_num_kernel_waiters == 0); @@ -378,14 +378,14 @@ namespace Kernel { } // Cancel the thread's wait. - waiter->CancelWait(ResultInvalidState, true); + waiter->CancelWait(kernel, ResultInvalidState, true); } // Remove the held lock from our list. it = m_held_lock_info_list.erase(it); // Free the lock info. - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } } @@ -393,35 +393,35 @@ namespace Kernel { m_host_context.reset(); // Perform inherited finalization. - KSynchronizationObject::Finalize(); + KSynchronizationObject::Finalize(kernel); } - bool KThread::IsSignaled() const { + bool KThread::IsSignaled(KernelCore& kernel) const { return m_signaled; } - void KThread::OnTimer() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::OnTimer(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // If we're waiting, cancel the wait. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, ResultTimedOut, false); + m_wait_queue->CancelWait(kernel, this, ResultTimedOut, false); } } - void KThread::StartTermination() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::StartTermination(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Release user exception and unpin, if relevant. if (m_parent != nullptr) { - m_parent->ReleaseUserException(this); - if (m_parent->GetPinnedThread(GetCurrentCoreId(m_kernel)) == this) { - m_parent->UnpinCurrentThread(); + m_parent->ReleaseUserException(kernel, this); + if (m_parent->GetPinnedThread(GetCurrentCoreId(kernel)) == this) { + m_parent->UnpinCurrentThread(kernel); } } // Set state to terminated. - this->SetState(ThreadState::Terminated); + this->SetState(kernel, ThreadState::Terminated); // Clear the thread's status as running in parent. if (m_parent != nullptr) { @@ -429,41 +429,41 @@ namespace Kernel { } // Clear previous thread in KScheduler. - KScheduler::ClearPreviousThread(m_kernel, this); + KScheduler::ClearPreviousThread(kernel, this); // Register terminated dpc flag. this->RegisterDpc(DpcFlag::Terminated); } - void KThread::FinishTermination() { + void KThread::FinishTermination(KernelCore& kernel) { // Ensure that the thread is not executing on any core. if (m_parent != nullptr) { - for (std::size_t i = 0; i < static_cast(Core::Hardware::NUM_CPU_CORES); ++i) { + for (std::size_t i = 0; i < std::size_t(Core::Hardware::NUM_CPU_CORES); ++i) { KThread* core_thread{}; do { - core_thread = m_kernel.Scheduler(i).GetSchedulerCurrentThread(); + core_thread = kernel.Scheduler(i).GetSchedulerCurrentThread(); } while (core_thread == this); } } // Acquire the scheduler lock. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Signal. m_signaled = true; - KSynchronizationObject::NotifyAvailable(); + KSynchronizationObject::NotifyAvailable(kernel); // Close the thread. - this->Close(); + this->Close(kernel); } - void KThread::DoWorkerTaskImpl() { + void KThread::DoWorkerTaskImpl(KernelCore& kernel) { // Finish the termination that was begun by Exit(). - this->FinishTermination(); + this->FinishTermination(kernel); } - void KThread::Pin(s32 current_core) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Pin(KernelCore& kernel, s32 current_core) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as pinned. GetStackParameters().is_pinned = true; @@ -487,7 +487,7 @@ namespace Kernel { if (active_core != current_core || m_physical_affinity_mask.GetAffinityMask() != m_original_physical_affinity_mask.GetAffinityMask()) { - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, + KScheduler::OnThreadAffinityMaskChanged(kernel, this, m_original_physical_affinity_mask, active_core); } } @@ -499,15 +499,15 @@ namespace Kernel { static_cast(ThreadState::SuspendShift))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } // TODO(bunnei): Update our SVC access permissions. ASSERT(m_parent != nullptr); } - void KThread::Unpin() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Unpin(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as unpinned. this->GetStackParameters().is_pinned = false; @@ -535,7 +535,7 @@ namespace Kernel { std::countl_zero(m_physical_affinity_mask.GetAffinityMask()))); } } - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core); + KScheduler::OnThreadAffinityMaskChanged(kernel, this, old_mask, active_core); } } @@ -546,20 +546,19 @@ namespace Kernel { static_cast(ThreadState::SuspendShift))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } // TODO(bunnei): Update our SVC access permissions. ASSERT(m_parent != nullptr); // Resume any threads that began waiting on us while we were pinned. - for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); - it = m_pinned_waiter_list.erase(it)) { - it->EndWait(ResultSuccess); - } + for (auto it = m_pinned_waiter_list.begin(); it != m_pinned_waiter_list.end(); it = m_pinned_waiter_list.erase(it)) { + it->EndWait(kernel, ResultSuccess); + } } - u16 KThread::GetUserDisableCount() const { + u16 KThread::GetUserDisableCount(KernelCore& kernel) const { if (!this->IsUserThread()) { // We only emulate TLS for user threads return {}; @@ -569,7 +568,7 @@ namespace Kernel { return memory.Read16(m_tls_address + offsetof(ThreadLocalRegion, disable_count)); } - void KThread::SetInterruptFlag() { + void KThread::SetInterruptFlag(KernelCore& kernel) { if (!this->IsUserThread()) { // We only emulate TLS for user threads return; @@ -579,7 +578,7 @@ namespace Kernel { memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 1); } - void KThread::ClearInterruptFlag() { + void KThread::ClearInterruptFlag(KernelCore& kernel) { if (!this->IsUserThread()) { // We only emulate TLS for user threads return; @@ -589,7 +588,7 @@ namespace Kernel { memory.Write16(m_tls_address + offsetof(ThreadLocalRegion, interrupt_flag), 0); } - void KThread::UpdateTlsThreadCpuTime(s64 switch_tick) { + void KThread::UpdateTlsThreadCpuTime(KernelCore& kernel, s64 switch_tick) { if (!this->IsUserThread()) { return; } @@ -602,8 +601,8 @@ namespace Kernel { memory.Write64(m_tls_address + offsetof(ThreadLocalRegion, thread_cpu_time), static_cast(value)); } - Result KThread::GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { - KScopedSchedulerLock sl{m_kernel}; + Result KThread::GetCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask) { + KScopedSchedulerLock sl{kernel}; // Get the virtual mask. *out_ideal_core = m_virtual_ideal_core_id; @@ -612,8 +611,8 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask) { - KScopedSchedulerLock sl{m_kernel}; + Result KThread::GetPhysicalCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask) { + KScopedSchedulerLock sl{kernel}; ASSERT(m_num_core_migration_disables >= 0); // Select between core mask and original core mask. @@ -628,7 +627,7 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::SetCoreMask(s32 core_id, u64 v_affinity_mask) { + Result KThread::SetCoreMask(KernelCore& kernel, s32 core_id, u64 v_affinity_mask) { ASSERT(m_parent != nullptr); ASSERT(v_affinity_mask != 0); KScopedLightLock lk(m_activity_pause_lock); @@ -636,7 +635,7 @@ namespace Kernel { // Set the core mask. u64 p_affinity_mask = 0; { - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); ASSERT(m_num_core_migration_disables >= 0); // If we're updating, set our ideal virtual core. @@ -682,7 +681,7 @@ namespace Kernel { std::countl_zero(m_physical_affinity_mask.GetAffinityMask())); SetActiveCore(new_core); } - KScheduler::OnThreadAffinityMaskChanged(m_kernel, this, old_mask, active_core); + KScheduler::OnThreadAffinityMaskChanged(kernel, this, old_mask, active_core); } } else { // Otherwise, we edit the original affinity for restoration later. @@ -692,12 +691,12 @@ namespace Kernel { } // Update the pinned waiter list. - ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel, std::addressof(m_pinned_waiter_list)); + ThreadQueueImplForKThreadSetProperty wait_queue(kernel, std::addressof(m_pinned_waiter_list)); { bool retry_update{}; do { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Don't do any further management if our termination has been requested. R_SUCCEED_IF(this->IsTerminationRequested()); @@ -710,7 +709,7 @@ namespace Kernel { s32 thread_core; for (thread_core = 0; thread_core < static_cast(Core::Hardware::NUM_CPU_CORES); ++thread_core) { - if (m_kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) { + if (kernel.Scheduler(thread_core).GetSchedulerCurrentThread() == this) { thread_is_current = true; break; } @@ -722,12 +721,12 @@ namespace Kernel { // If the thread is pinned, we want to wait until it's not pinned. if (this->GetStackParameters().is_pinned) { // Verify that the current thread isn't terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Wait until the thread isn't pinned any more. - m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel)); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + m_pinned_waiter_list.push_back(GetCurrentThread(kernel)); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } else { // If the thread isn't pinned, release the scheduler lock and retry until it's // not current. @@ -740,25 +739,25 @@ namespace Kernel { R_SUCCEED(); } - void KThread::SetBasePriority(s32 value) { + void KThread::SetBasePriority(KernelCore& kernel, s32 value) { ASSERT(Svc::HighestThreadPriority <= value && value <= Svc::LowestThreadPriority); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Change our base priority. m_base_priority = value; // Perform a priority restoration. - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } - KThread* KThread::GetLockOwner() const { + KThread* KThread::GetLockOwner(KernelCore& kernel) const { return m_waiting_lock_info != nullptr ? m_waiting_lock_info->GetOwner() : nullptr; } - void KThread::IncreaseBasePriority(s32 priority) { + void KThread::IncreaseBasePriority(KernelCore& kernel, s32 priority) { ASSERT(Svc::HighestThreadPriority <= priority && priority <= Svc::LowestThreadPriority); - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(!this->GetStackParameters().is_pinned); // Set our base priority. @@ -766,47 +765,47 @@ namespace Kernel { m_base_priority = priority; // Perform a priority restoration. - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } } - void KThread::RequestSuspend(SuspendType type) { - KScopedSchedulerLock sl{m_kernel}; + void KThread::RequestSuspend(KernelCore& kernel, SuspendType type) { + KScopedSchedulerLock sl{kernel}; // Note the request in our flags. m_suspend_request_flags |= (1U << (static_cast(ThreadState::SuspendShift) + static_cast(type))); // Try to perform the suspend. - this->TrySuspend(); + this->TrySuspend(kernel); } - void KThread::Resume(SuspendType type) { - KScopedSchedulerLock sl{m_kernel}; + void KThread::Resume(KernelCore& kernel, SuspendType type) { + KScopedSchedulerLock sl{kernel}; // Clear the request in our flags. m_suspend_request_flags &= ~(1U << (static_cast(ThreadState::SuspendShift) + static_cast(type))); // Update our state. - this->UpdateState(); + this->UpdateState(kernel); } - void KThread::WaitCancel() { - KScopedSchedulerLock sl{m_kernel}; + void KThread::WaitCancel(KernelCore& kernel) { + KScopedSchedulerLock sl{kernel}; // Check if we're waiting and cancellable. if (this->GetState() == ThreadState::Waiting && m_cancellable) { m_wait_cancelled = false; - m_wait_queue->CancelWait(this, ResultCancelled, true); + m_wait_queue->CancelWait(kernel, this, ResultCancelled, true); } else { // Otherwise, note that we cancelled a wait. m_wait_cancelled = true; } } - void KThread::TrySuspend() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::TrySuspend(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsSuspendRequested()); // Ensure that we have no waiters. @@ -816,11 +815,11 @@ namespace Kernel { ASSERT(this->GetNumKernelWaiters() == 0); // Perform the suspend. - this->UpdateState(); + this->UpdateState(kernel); } - void KThread::UpdateState() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::UpdateState(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set our suspend flags in state. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); @@ -830,37 +829,37 @@ namespace Kernel { // Note the state change in scheduler. if (new_state != old_state) { - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } } - void KThread::Continue() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::Continue(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Clear our suspend flags in state. const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); m_thread_state.store(old_state & ThreadState::Mask, std::memory_order_relaxed); // Note the state change in scheduler. - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } - void KThread::CloneFpuStatus() { + void KThread::CloneFpuStatus(KernelCore& kernel) { // We shouldn't reach here when starting kernel threads. ASSERT(this->GetOwnerProcess() != nullptr); - ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(m_kernel)); + ASSERT(this->GetOwnerProcess() == GetCurrentProcessPointer(kernel)); - m_kernel.CurrentPhysicalCore().CloneFpuStatus(this); + kernel.CurrentPhysicalCore().CloneFpuStatus(this); } - Result KThread::SetActivity(Svc::ThreadActivity activity) { + Result KThread::SetActivity(KernelCore& kernel, Svc::ThreadActivity activity) { // Lock ourselves. KScopedLightLock lk(m_activity_pause_lock); // Set the activity. { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Verify our state. const auto cur_state = this->GetState(); @@ -873,7 +872,7 @@ namespace Kernel { R_UNLESS(!this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); // Suspend. - this->RequestSuspend(SuspendType::Thread); + this->RequestSuspend(kernel, SuspendType::Thread); } else { ASSERT(activity == Svc::ThreadActivity::Runnable); @@ -881,19 +880,19 @@ namespace Kernel { R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); // Resume. - this->Resume(SuspendType::Thread); + this->Resume(kernel, SuspendType::Thread); } } // If the thread is now paused, update the pinned waiter list. if (activity == Svc::ThreadActivity::Paused) { - ThreadQueueImplForKThreadSetProperty wait_queue(m_kernel, + ThreadQueueImplForKThreadSetProperty wait_queue(kernel, std::addressof(m_pinned_waiter_list)); bool thread_is_current{}; do { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); + KScopedSchedulerLock sl(kernel); // Don't do any further management if our termination has been requested. R_SUCCEED_IF(this->IsTerminationRequested()); @@ -904,17 +903,17 @@ namespace Kernel { // Check whether the thread is pinned. if (this->GetStackParameters().is_pinned) { // Verify that the current thread isn't terminating. - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Wait until the thread isn't pinned any more. - m_pinned_waiter_list.push_back(GetCurrentThread(m_kernel)); - GetCurrentThread(m_kernel).BeginWait(std::addressof(wait_queue)); + m_pinned_waiter_list.push_back(GetCurrentThread(kernel)); + GetCurrentThread(kernel).BeginWait(kernel, std::addressof(wait_queue)); } else { // Check if the thread is currently running. // If it is, we'll need to retry. for (auto i = 0; i < static_cast(Core::Hardware::NUM_CPU_CORES); ++i) { - if (m_kernel.Scheduler(i).GetSchedulerCurrentThread() == this) { + if (kernel.Scheduler(i).GetSchedulerCurrentThread() == this) { thread_is_current = true; break; } @@ -926,14 +925,14 @@ namespace Kernel { R_SUCCEED(); } - Result KThread::GetThreadContext3(Svc::ThreadContext* out) { + Result KThread::GetThreadContext3(KernelCore& kernel, Svc::ThreadContext* out) { // Lock ourselves. KScopedLightLock lk{m_activity_pause_lock}; // Get the context. { // Lock the scheduler. - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Verify that we're suspended. R_UNLESS(this->IsSuspendRequested(SuspendType::Thread), ResultInvalidState); @@ -957,8 +956,8 @@ namespace Kernel { R_SUCCEED(); } - void KThread::AddHeldLock(LockWithPriorityInheritanceInfo* lock_info) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::AddHeldLock(KernelCore& kernel, LockWithPriorityInheritanceInfo* lock_info) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Set ourselves as the lock's owner. lock_info->SetOwner(this); @@ -967,23 +966,21 @@ namespace Kernel { m_held_lock_info_list.push_front(*lock_info); } - KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KProcessAddress address_key, - bool is_kernel_address_key) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + KThread::LockWithPriorityInheritanceInfo* KThread::FindHeldLock(KernelCore& kernel, KProcessAddress address_key, bool is_kernel_address_key) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Try to find an existing held lock. for (auto& held_lock : m_held_lock_info_list) { - if (held_lock.GetAddressKey() == address_key && - held_lock.GetIsKernelAddressKey() == is_kernel_address_key) { + if (held_lock.GetAddressKey() == address_key && held_lock.GetIsKernelAddressKey() == is_kernel_address_key) { return std::addressof(held_lock); - } + } } return nullptr; } - void KThread::AddWaiterImpl(KThread* thread) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::AddWaiterImpl(KernelCore& kernel, KThread* thread) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(thread->GetConditionVariableTree() == nullptr); // Get the thread's address key. @@ -993,31 +990,31 @@ namespace Kernel { // Keep track of how many kernel waiters we have. if (is_kernel_address_key) { ASSERT((m_num_kernel_waiters++) >= 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } // Get the relevant lock info. - auto* lock_info = this->FindHeldLock(address_key, is_kernel_address_key); + auto* lock_info = this->FindHeldLock(kernel, address_key, is_kernel_address_key); if (lock_info == nullptr) { // Create a new lock for the address key. lock_info = - LockWithPriorityInheritanceInfo::Create(m_kernel, address_key, is_kernel_address_key); + LockWithPriorityInheritanceInfo::Create(kernel, address_key, is_kernel_address_key); // Add the new lock to our list. - this->AddHeldLock(lock_info); + this->AddHeldLock(kernel, lock_info); } // Add the thread as waiter to the lock info. lock_info->AddWaiter(thread); } - void KThread::RemoveWaiterImpl(KThread* thread) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::RemoveWaiterImpl(KernelCore& kernel, KThread* thread) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Keep track of how many kernel waiters we have. if (thread->GetIsKernelAddressKey()) { ASSERT((m_num_kernel_waiters--) > 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } // Get the info for the lock the thread is waiting on. @@ -1027,7 +1024,7 @@ namespace Kernel { // Remove the waiter. if (lock_info->RemoveWaiter(thread)) { m_held_lock_info_list.erase(m_held_lock_info_list.iterator_to(*lock_info)); - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } } @@ -1048,12 +1045,12 @@ namespace Kernel { } // Get the owner of whatever lock this thread is waiting on. - KThread* const lock_owner = thread->GetLockOwner(); + KThread* const lock_owner = thread->GetLockOwner(kernel); // If the thread is waiting on some lock, remove it as a waiter to prevent violating red // black tree invariants. if (lock_owner != nullptr) { - lock_owner->RemoveWaiterImpl(thread); + lock_owner->RemoveWaiterImpl(kernel, thread); } // Ensure we don't violate condition variable red black tree invariants. @@ -1072,7 +1069,7 @@ namespace Kernel { // If we removed the thread from some lock's waiting list, add it back. if (lock_owner != nullptr) { - lock_owner->AddWaiterImpl(thread); + lock_owner->AddWaiterImpl(kernel, thread); } // Update the scheduler. @@ -1083,32 +1080,30 @@ namespace Kernel { } } - void KThread::AddWaiter(KThread* thread) { - this->AddWaiterImpl(thread); + void KThread::AddWaiter(KernelCore& kernel, KThread* thread) { + this->AddWaiterImpl(kernel, thread); // If the thread has a higher priority than us, we should inherit. if (thread->GetPriority() < this->GetPriority()) { - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); } } - void KThread::RemoveWaiter(KThread* thread) { - this->RemoveWaiterImpl(thread); + void KThread::RemoveWaiter(KernelCore& kernel, KThread* thread) { + this->RemoveWaiterImpl(kernel, thread); // If our priority is the same as the thread's (and we've inherited), we may need to restore to // lower priority. - if (this->GetPriority() == thread->GetPriority() && - this->GetPriority() < this->GetBasePriority()) { - RestorePriority(m_kernel, this); - } + if (this->GetPriority() == thread->GetPriority() && this->GetPriority() < this->GetBasePriority()) { + RestorePriority(kernel, this); + } } - KThread* KThread::RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, - bool is_kernel_address_key_) { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + KThread* KThread::RemoveWaiterByKey(KernelCore& kernel, bool* out_has_waiters, KProcessAddress key, bool is_kernel_address_key_) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); // Get the relevant lock info. - auto* lock_info = this->FindHeldLock(key, is_kernel_address_key_); + auto* lock_info = this->FindHeldLock(kernel, key, is_kernel_address_key_); if (lock_info == nullptr) { *out_has_waiters = false; return nullptr; @@ -1121,7 +1116,7 @@ namespace Kernel { if (lock_info->GetIsKernelAddressKey()) { m_num_kernel_waiters -= lock_info->GetWaiterCount(); ASSERT(m_num_kernel_waiters >= 0); - KScheduler::SetSchedulerUpdateNeeded(m_kernel); + KScheduler::SetSchedulerUpdateNeeded(kernel); } ASSERT(lock_info->GetWaiterCount() > 0); @@ -1133,13 +1128,13 @@ namespace Kernel { *out_has_waiters = false; // Free the lock info, since it has no waiters. - LockWithPriorityInheritanceInfo::Free(m_kernel, lock_info); + LockWithPriorityInheritanceInfo::Free(kernel, lock_info); } else { // There are additional waiters on the lock. *out_has_waiters = true; // Add the lock to the new owner's held list. - next_lock_owner->AddHeldLock(lock_info); + next_lock_owner->AddHeldLock(kernel, lock_info); // Keep track of any kernel waiters for the new owner. if (lock_info->GetIsKernelAddressKey()) { @@ -1155,7 +1150,7 @@ namespace Kernel { // to lower priority. if (this->GetPriority() == next_lock_owner->GetPriority() && this->GetPriority() < this->GetBasePriority()) { - RestorePriority(m_kernel, this); + RestorePriority(kernel, this); // NOTE: No need to restore priority on the next lock owner, because it was already the // highest priority waiter on the lock. } @@ -1164,91 +1159,91 @@ namespace Kernel { return next_lock_owner; } - Result KThread::Run() { + Result KThread::Run(KernelCore& kernel) { while (true) { - KScopedSchedulerLock lk{m_kernel}; + KScopedSchedulerLock lk{kernel}; // If either this thread or the current thread are requesting termination, note it. R_UNLESS(!this->IsTerminationRequested(), ResultTerminationRequested); - R_UNLESS(!GetCurrentThread(m_kernel).IsTerminationRequested(), ResultTerminationRequested); + R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested); // Ensure our thread state is correct. R_UNLESS(this->GetState() == ThreadState::Initialized, ResultInvalidState); // If the current thread has been asked to suspend, suspend it and retry. - if (GetCurrentThread(m_kernel).IsSuspended()) { - GetCurrentThread(m_kernel).UpdateState(); + if (GetCurrentThread(kernel).IsSuspended()) { + GetCurrentThread(kernel).UpdateState(kernel); continue; } // If we're not a kernel thread and we've been asked to suspend, suspend ourselves. if (KProcess* owner = this->GetOwnerProcess(); owner != nullptr) { if (this->IsUserThread() && this->IsSuspended()) { - this->UpdateState(); + this->UpdateState(kernel); } - owner->IncrementRunningThreadCount(); + owner->IncrementRunningThreadCount(kernel); } // Open a reference, now that we're running. - this->Open(); + this->Open(kernel); // Set our state and finish. - this->SetState(ThreadState::Runnable); + this->SetState(kernel, ThreadState::Runnable); R_SUCCEED(); } } - void KThread::Exit() { - ASSERT(this == GetCurrentThreadPointer(m_kernel)); + void KThread::Exit(KernelCore& kernel) { + ASSERT(this == GetCurrentThreadPointer(kernel)); // Release the thread resource hint, running thread count from parent. if (m_parent != nullptr) { - m_parent->GetResourceLimit()->Release(Kernel::LimitableResource::ThreadCountMax, 0, 1); + m_parent->GetResourceLimit()->Release(kernel, Kernel::LimitableResource::ThreadCountMax, 0, 1); m_resource_limit_release_hint = true; - m_parent->DecrementRunningThreadCount(); + m_parent->DecrementRunningThreadCount(kernel); } // Perform termination. { - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Disallow all suspension. m_suspend_allowed_flags = 0; - this->UpdateState(); + this->UpdateState(kernel); // Disallow all suspension. m_suspend_allowed_flags = 0; // Start termination. - this->StartTermination(); + this->StartTermination(kernel); // Register the thread as a work task. - KWorkerTaskManager::AddTask(m_kernel, KWorkerTaskManager::WorkerType::Exit, this); + KWorkerTaskManager::AddTask(kernel, KWorkerTaskManager::WorkerType::Exit, this); } UNREACHABLE_MSG("KThread::Exit() would return"); } - Result KThread::Terminate() { - ASSERT(this != GetCurrentThreadPointer(m_kernel)); + Result KThread::Terminate(KernelCore& kernel) { + ASSERT(this != GetCurrentThreadPointer(kernel)); // Request the thread terminate if it hasn't already. - if (const auto new_state = this->RequestTerminate(); new_state != ThreadState::Terminated) { + if (const auto new_state = this->RequestTerminate(kernel); new_state != ThreadState::Terminated) { // If the thread isn't terminated, wait for it to terminate. s32 index; KSynchronizationObject* objects[] = {this}; - R_TRY(KSynchronizationObject::Wait(m_kernel, std::addressof(index), objects, 1, + R_TRY(KSynchronizationObject::Wait(kernel, std::addressof(index), objects, 1, Svc::WaitInfinite)); } R_SUCCEED(); } - ThreadState KThread::RequestTerminate() { - ASSERT(this != GetCurrentThreadPointer(m_kernel)); + ThreadState KThread::RequestTerminate(KernelCore& kernel) { + ASSERT(this != GetCurrentThreadPointer(kernel)); - KScopedSchedulerLock sl{m_kernel}; + KScopedSchedulerLock sl{kernel}; // Determine if this is the first termination request. const bool first_request = [&]() -> bool { @@ -1270,46 +1265,46 @@ namespace Kernel { // If the thread is pinned, unpin it. if (this->GetStackParameters().is_pinned) { - this->GetOwnerProcess()->UnpinThread(this); + this->GetOwnerProcess()->UnpinThread(kernel, this); } // If the thread is suspended, continue it. if (this->IsSuspended()) { m_suspend_allowed_flags = 0; - this->UpdateState(); + this->UpdateState(kernel); } // Change the thread's priority to be higher than any system thread's. - this->IncreaseBasePriority(TerminatingThreadPriority); + this->IncreaseBasePriority(kernel, TerminatingThreadPriority); // If the thread is runnable, send a termination interrupt to cores it may be running on. if (this->GetState() == ThreadState::Runnable) { // NOTE: We do not mask the "current core", because this code may not actually be // executing from the thread representing the "current core". if (const u64 core_mask = m_physical_affinity_mask.GetAffinityMask(); core_mask != 0) { - Kernel::KInterruptManager::SendInterProcessorInterrupt(m_kernel, core_mask); + Kernel::KInterruptManager::SendInterProcessorInterrupt(kernel, core_mask); } } // Wake up the thread. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, ResultTerminationRequested, true); + m_wait_queue->CancelWait(kernel, this, ResultTerminationRequested, true); } } return this->GetState(); } - Result KThread::Sleep(s64 timeout) { - ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); - ASSERT(this == GetCurrentThreadPointer(m_kernel)); + Result KThread::Sleep(KernelCore& kernel, s64 timeout) { + ASSERT(!KScheduler::IsSchedulerLockedByCurrentThread(kernel)); + ASSERT(this == GetCurrentThreadPointer(kernel)); ASSERT(timeout > 0); - ThreadQueueImplForKThreadSleep wait_queue(m_kernel); + ThreadQueueImplForKThreadSleep wait_queue(kernel); KHardwareTimer* timer{}; { // Setup the scheduling lock and sleep. - KScopedSchedulerLockAndSleep slp(m_kernel, std::addressof(timer), this, timeout); + KScopedSchedulerLockAndSleep slp(kernel, std::addressof(timer), this, timeout); // Check if the thread should terminate. if (this->IsTerminationRequested()) { @@ -1319,15 +1314,15 @@ namespace Kernel { // Wait for the sleep to end. wait_queue.SetHardwareTimer(timer); - this->BeginWait(std::addressof(wait_queue)); + this->BeginWait(kernel, std::addressof(wait_queue)); this->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::Sleep); } R_SUCCEED(); } - void KThread::RequestDummyThreadWait() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::RequestDummyThreadWait(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsDummyThread()); // We will block when the scheduler lock is released. @@ -1335,8 +1330,8 @@ namespace Kernel { m_dummy_thread_runnable = false; } - void KThread::DummyThreadBeginWait() { - if (!this->IsDummyThread() || m_kernel.IsPhantomModeForSingleCore()) { + void KThread::DummyThreadBeginWait(KernelCore& kernel) { + if (!this->IsDummyThread() || kernel.IsPhantomModeForSingleCore()) { // Occurs in single core mode. return; } @@ -1346,8 +1341,8 @@ namespace Kernel { m_dummy_thread_cv.wait(lock, [this] { return m_dummy_thread_runnable; }); } - void KThread::DummyThreadEndWait() { - ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(m_kernel)); + void KThread::DummyThreadEndWait(KernelCore& kernel) { + ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel)); ASSERT(this->IsDummyThread()); // Wake up the waiting thread. @@ -1358,28 +1353,26 @@ namespace Kernel { m_dummy_thread_cv.notify_one(); } - void KThread::BeginWait(KThreadQueue* queue) { + void KThread::BeginWait(KernelCore& kernel, KThreadQueue* queue) { // Set our state as waiting. - this->SetState(ThreadState::Waiting); + this->SetState(kernel, ThreadState::Waiting); // Set our wait queue. m_wait_queue = queue; } - void KThread::NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result) { + void KThread::NotifyAvailable(KernelCore& kernel, KSynchronizationObject* signaled_object, Result wait_result) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->NotifyAvailable(this, signaled_object, wait_result); + m_wait_queue->NotifyAvailable(kernel, this, signaled_object, wait_result); } } - void KThread::EndWait(Result wait_result) { + void KThread::EndWait(KernelCore& kernel, Result wait_result) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { if (m_wait_queue == nullptr) { @@ -1388,32 +1381,29 @@ namespace Kernel { return; } - m_wait_queue->EndWait(this, wait_result); + m_wait_queue->EndWait(kernel, this, wait_result); } } - void KThread::CancelWait(Result wait_result, bool cancel_timer_task) { + void KThread::CancelWait(KernelCore& kernel, Result wait_result, bool cancel_timer_task) { // Lock the scheduler. - KScopedSchedulerLock sl(m_kernel); - + KScopedSchedulerLock sl(kernel); // If we're waiting, notify our queue that we're available. if (this->GetState() == ThreadState::Waiting) { - m_wait_queue->CancelWait(this, wait_result, cancel_timer_task); + m_wait_queue->CancelWait(kernel, this, wait_result, cancel_timer_task); } } - void KThread::SetState(ThreadState state) { - KScopedSchedulerLock sl{m_kernel}; - + void KThread::SetState(KernelCore& kernel, ThreadState state) { + KScopedSchedulerLock sl{kernel}; // Clear debugging state this->SetWaitReasonForDebugging({}); - const ThreadState old_state = m_thread_state.load(std::memory_order_relaxed); m_thread_state.store( static_cast((old_state & ~ThreadState::Mask) | (state & ThreadState::Mask)), std::memory_order_relaxed); if (m_thread_state.load(std::memory_order_relaxed) != old_state) { - KScheduler::OnThreadStateChanged(m_kernel, this, old_state); + KScheduler::OnThreadStateChanged(kernel, this, old_state); } } @@ -1464,7 +1454,7 @@ namespace Kernel { KScheduler::RescheduleCurrentHLEThread(m_kernel); } } else { - GetCurrentThread(m_kernel).EnableDispatch(); + GetCurrentThread(m_kernel).EnableDispatch(m_kernel); } } } \ No newline at end of file diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index e79704ce4b..95ba1b4d76 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -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 @@ -181,21 +181,17 @@ public: return m_thread_id; } - void ContinueIfHasKernelWaiters() { + void ContinueIfHasKernelWaiters(KernelCore& kernel) { if (GetNumKernelWaiters() > 0) { - Continue(); + Continue(kernel); } } - void SetBasePriority(s32 value); - - Result Run(); - - void Exit(); - - Result Terminate(); - - ThreadState RequestTerminate(); + void SetBasePriority(KernelCore& kernel, s32 value); + Result Run(KernelCore& kernel); + void Exit(KernelCore& kernel); + Result Terminate(KernelCore& kernel); + ThreadState RequestTerminate(KernelCore& kernel); u32 GetSuspendFlags() const { return m_suspend_allowed_flags & m_suspend_request_flags; @@ -215,15 +211,11 @@ public: return m_suspend_request_flags != 0; } - void RequestSuspend(SuspendType type); - - void Resume(SuspendType type); - - void TrySuspend(); - - void UpdateState(); - - void Continue(); + void RequestSuspend(KernelCore& kernel, SuspendType type); + void Resume(KernelCore& kernel, SuspendType type); + void TrySuspend(KernelCore& kernel); + void UpdateState(KernelCore& kernel); + void Continue(KernelCore& kernel); constexpr void SetSyncedIndex(s32 index) { m_synced_index = index; @@ -262,7 +254,7 @@ public: m_thread_context.tpidr = value; } - void CloneFpuStatus(); + void CloneFpuStatus(KernelCore& kernel); Svc::ThreadContext& GetContext() { return m_thread_context; @@ -282,7 +274,7 @@ public: return m_thread_state.load(std::memory_order_relaxed); } - void SetState(ThreadState state); + void SetState(KernelCore& kernel, ThreadState state); StepState GetStepState() const { return m_step_state; @@ -342,27 +334,27 @@ public: Svc::ArgumentHandleCountMax}; } - u16 GetUserDisableCount() const; - void SetInterruptFlag(); - void ClearInterruptFlag(); + u16 GetUserDisableCount(KernelCore& kernel) const; + void SetInterruptFlag(KernelCore& kernel); + void ClearInterruptFlag(KernelCore& kernel); - void UpdateTlsThreadCpuTime(s64 switch_tick); + void UpdateTlsThreadCpuTime(KernelCore& kernel, s64 switch_tick); - KThread* GetLockOwner() const; + KThread* GetLockOwner(KernelCore& kernel) const; const KAffinityMask& GetAffinityMask() const { return m_physical_affinity_mask; } - Result GetCoreMask(s32* out_ideal_core, u64* out_affinity_mask); + Result GetCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask); - Result GetPhysicalCoreMask(s32* out_ideal_core, u64* out_affinity_mask); + Result GetPhysicalCoreMask(KernelCore& kernel, s32* out_ideal_core, u64* out_affinity_mask); - Result SetCoreMask(s32 cpu_core_id, u64 v_affinity_mask); + Result SetCoreMask(KernelCore& kernel, s32 cpu_core_id, u64 v_affinity_mask); - Result SetActivity(Svc::ThreadActivity activity); + Result SetActivity(KernelCore& kernel, Svc::ThreadActivity activity); - Result Sleep(s64 timeout); + Result Sleep(KernelCore& kernel, s64 timeout); s64 GetYieldScheduleCount() const { return m_schedule_count; @@ -372,7 +364,7 @@ public: m_schedule_count = count; } - void WaitCancel(); + void WaitCancel(KernelCore& kernel); bool IsWaitCancelled() const { return m_wait_cancelled; @@ -417,17 +409,17 @@ public: return reinterpret_cast(m_parent) | (m_resource_limit_release_hint ? 1 : 0); } - void Finalize() override; + void Finalize(KernelCore& kernel) override; - bool IsSignaled() const override; + bool IsSignaled(KernelCore& kernel) const override; - void OnTimer(); + void OnTimer(KernelCore& kernel); - void DoWorkerTaskImpl(); + void DoWorkerTaskImpl(KernelCore& kernel); - static void PostDestroy(uintptr_t arg); + static void PostDestroy(KernelCore& kernel, uintptr_t arg); - static Result InitializeDummyThread(KThread* thread, KProcess* owner); + static Result InitializeDummyThread(Core::System& system, KThread* thread, KProcess* owner); static Result InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core); @@ -514,19 +506,18 @@ public: return this->GetStackParameters().disable_count; } - void DisableDispatch() { - ASSERT(GetCurrentThread(m_kernel).GetDisableDispatchCount() >= 0); + void DisableDispatch(KernelCore& kernel) { + ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() >= 0); this->GetStackParameters().disable_count++; } - void EnableDispatch() { - ASSERT(GetCurrentThread(m_kernel).GetDisableDispatchCount() > 0); + void EnableDispatch(KernelCore& kernel) { + ASSERT(GetCurrentThread(kernel).GetDisableDispatchCount() > 0); this->GetStackParameters().disable_count--; } - void Pin(s32 current_core); - - void Unpin(); + void Pin(KernelCore& kernel, s32 current_core); + void Unpin(KernelCore& kernel); void SetInExceptionHandler() { this->GetStackParameters().is_in_exception_handler = true; @@ -592,18 +583,18 @@ public: return this->GetThreadType() == ThreadType::Dummy; } - void AddWaiter(KThread* thread); + void AddWaiter(KernelCore& kernel, KThread* thread); - void RemoveWaiter(KThread* thread); + void RemoveWaiter(KernelCore& kernel, KThread* thread); - Result GetThreadContext3(Svc::ThreadContext* out); + Result GetThreadContext3(KernelCore& kernel, Svc::ThreadContext* out); - KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { - return this->RemoveWaiterByKey(out_has_waiters, key, false); + KThread* RemoveUserWaiterByKey(KernelCore& kernel, bool* out_has_waiters, KProcessAddress key) { + return this->RemoveWaiterByKey(kernel, out_has_waiters, key, false); } - KThread* RemoveKernelWaiterByKey(bool* out_has_waiters, KProcessAddress key) { - return this->RemoveWaiterByKey(out_has_waiters, key, true); + KThread* RemoveKernelWaiterByKey(KernelCore& kernel, bool* out_has_waiters, KProcessAddress key) { + return this->RemoveWaiterByKey(kernel, out_has_waiters, key, true); } KProcessAddress GetAddressKey() const { @@ -641,10 +632,10 @@ public: m_wait_queue = nullptr; } - void BeginWait(KThreadQueue* queue); - void NotifyAvailable(KSynchronizationObject* signaled_object, Result wait_result); - void EndWait(Result wait_result); - void CancelWait(Result wait_result, bool cancel_timer_task); + void BeginWait(KernelCore& kernel, KThreadQueue* queue); + void NotifyAvailable(KernelCore& kernel, KSynchronizationObject* signaled_object, Result wait_result); + void EndWait(KernelCore& kernel, Result wait_result); + void CancelWait(KernelCore& kernel, Result wait_result, bool cancel_timer_task); s32 GetNumKernelWaiters() const { return m_num_kernel_waiters; @@ -662,9 +653,9 @@ public: // therefore will not block on guest kernel synchronization primitives. These methods handle // blocking as needed. - void RequestDummyThreadWait(); - void DummyThreadBeginWait(); - void DummyThreadEndWait(); + void RequestDummyThreadWait(KernelCore& kernel); + void DummyThreadBeginWait(KernelCore& kernel); + void DummyThreadEndWait(KernelCore& kernel); uintptr_t GetArgument() const { return m_argument; @@ -690,8 +681,7 @@ public: } private: - KThread* RemoveWaiterByKey(bool* out_has_waiters, KProcessAddress key, - bool is_kernel_address_key); + KThread* RemoveWaiterByKey(KernelCore& kernel, bool* out_has_waiters, KProcessAddress key, bool is_kernel_address_key); static constexpr size_t PriorityInheritanceCountMax = 10; union SyncObjectBuffer { @@ -735,19 +725,19 @@ private: } }; - void AddWaiterImpl(KThread* thread); - void RemoveWaiterImpl(KThread* thread); + void AddWaiterImpl(KernelCore& kernel, KThread* thread); + void RemoveWaiterImpl(KernelCore& kernel, KThread* thread); static void RestorePriority(KernelCore& kernel, KThread* thread); - void StartTermination(); - void FinishTermination(); + void StartTermination(KernelCore& kernel); + void FinishTermination(KernelCore& kernel); - void IncreaseBasePriority(s32 priority); + void IncreaseBasePriority(KernelCore& kernel, s32 priority); - Result Initialize(KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, + Result Initialize(KernelCore& kernel, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 virt_core, KProcess* owner, ThreadType type); - static Result InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, + static Result InitializeThread(KernelCore& kernel, KThread* thread, KThreadFunction func, uintptr_t arg, KProcessAddress user_stack_top, s32 prio, s32 core, KProcess* owner, ThreadType type, std::function&& init_func); @@ -878,9 +868,8 @@ public: return m_waiting_lock_info; } - void AddHeldLock(LockWithPriorityInheritanceInfo* lock_info); - LockWithPriorityInheritanceInfo* FindHeldLock(KProcessAddress address_key, - bool is_kernel_address_key); + void AddHeldLock(KernelCore& kernel, LockWithPriorityInheritanceInfo* lock_info); + LockWithPriorityInheritanceInfo* FindHeldLock(KernelCore& kernel, KProcessAddress address_key, bool is_kernel_address_key); private: using LockWithPriorityInheritanceInfoList = @@ -996,7 +985,7 @@ public: if (m_kernel.IsShuttingDown()) { return; } - GetCurrentThread(kernel).DisableDispatch(); + GetCurrentThread(kernel).DisableDispatch(kernel); } ~KScopedDisableDispatch(); @@ -1005,8 +994,8 @@ private: KernelCore& m_kernel; }; -inline void KTimerTask::OnTimer() { - static_cast(this)->OnTimer(); +inline void KTimerTask::OnTimer(KernelCore& kernel) { + static_cast(this)->OnTimer(kernel); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_thread_queue.cpp b/src/core/hle/kernel/k_thread_queue.cpp index 61488f4ce6..7c4bfe5a49 100644 --- a/src/core/hle/kernel/k_thread_queue.cpp +++ b/src/core/hle/kernel/k_thread_queue.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,17 +10,16 @@ namespace Kernel { -void KThreadQueue::NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, - Result wait_result) { +void KThreadQueue::NotifyAvailable(KernelCore& kernel, KThread* waiting_thread, KSynchronizationObject* signaled_object, Result wait_result) { UNREACHABLE(); } -void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) { +void KThreadQueue::EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) { // Set the thread's wait result. waiting_thread->SetWaitResult(wait_result); // Set the thread as runnable. - waiting_thread->SetState(ThreadState::Runnable); + waiting_thread->SetState(kernel, ThreadState::Runnable); // Clear the thread's wait queue. waiting_thread->ClearWaitQueue(); @@ -28,12 +30,12 @@ void KThreadQueue::EndWait(KThread* waiting_thread, Result wait_result) { } } -void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task) { +void KThreadQueue::CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task) { // Set the thread's wait result. waiting_thread->SetWaitResult(wait_result); // Set the thread as runnable. - waiting_thread->SetState(ThreadState::Runnable); + waiting_thread->SetState(kernel, ThreadState::Runnable); // Clear the thread's wait queue. waiting_thread->ClearWaitQueue(); @@ -44,7 +46,7 @@ void KThreadQueue::CancelWait(KThread* waiting_thread, Result wait_result, bool } } -void KThreadQueueWithoutEndWait::EndWait(KThread* waiting_thread, Result wait_result) { +void KThreadQueueWithoutEndWait::EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) { UNREACHABLE(); } diff --git a/src/core/hle/kernel/k_thread_queue.h b/src/core/hle/kernel/k_thread_queue.h index 117af0919a..371efc9d95 100644 --- a/src/core/hle/kernel/k_thread_queue.h +++ b/src/core/hle/kernel/k_thread_queue.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -19,10 +22,9 @@ public: m_hardware_timer = timer; } - virtual void NotifyAvailable(KThread* waiting_thread, KSynchronizationObject* signaled_object, - Result wait_result); - virtual void EndWait(KThread* waiting_thread, Result wait_result); - virtual void CancelWait(KThread* waiting_thread, Result wait_result, bool cancel_timer_task); + virtual void NotifyAvailable(KernelCore& kernel, KThread* waiting_thread, KSynchronizationObject* signaled_object, Result wait_result); + virtual void EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result); + virtual void CancelWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result, bool cancel_timer_task); private: KernelCore& m_kernel; @@ -32,8 +34,7 @@ private: class KThreadQueueWithoutEndWait : public KThreadQueue { public: explicit KThreadQueueWithoutEndWait(KernelCore& kernel) : KThreadQueue(kernel) {} - - void EndWait(KThread* waiting_thread, Result wait_result) override final; + void EndWait(KernelCore& kernel, KThread* waiting_thread, Result wait_result) override final; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_timer_task.h b/src/core/hle/kernel/k_timer_task.h index 66f0a5a908..7625c1fee1 100644 --- a/src/core/hle/kernel/k_timer_task.h +++ b/src/core/hle/kernel/k_timer_task.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,6 +10,7 @@ namespace Kernel { +class KernelCore; class KTimerTask : public Common::IntrusiveRedBlackTreeBaseNode { public: static constexpr int Compare(const KTimerTask& lhs, const KTimerTask& rhs) { @@ -30,7 +34,7 @@ public: // NOTE: This is virtual in Nintendo's kernel. Prior to 13.0.0, KWaitObject was also a // TimerTask; this is no longer the case. Since this is now KThread exclusive, we have // devirtualized (see inline declaration for this inside k_thread.h). - void OnTimer(); + void OnTimer(KernelCore& kernel); private: // Absolute time in nanoseconds diff --git a/src/core/hle/kernel/k_trace.h b/src/core/hle/kernel/k_trace.h index d61af48303..84dd4134e1 100644 --- a/src/core/hle/kernel/k_trace.h +++ b/src/core/hle/kernel/k_trace.h @@ -1,8 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once +#include "common/literals.h" + namespace Kernel { using namespace Common::Literals; diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp index 64547e488a..a4ef530b5b 100644 --- a/src/core/hle/kernel/k_transfer_memory.cpp +++ b/src/core/hle/kernel/k_transfer_memory.cpp @@ -17,16 +17,15 @@ KTransferMemory::KTransferMemory(KernelCore& kernel) KTransferMemory::~KTransferMemory() = default; -Result KTransferMemory::Initialize(KProcessAddress addr, std::size_t size, - Svc::MemoryPermission own_perm) { +Result KTransferMemory::Initialize(KernelCore& kernel, KProcessAddress addr, std::size_t size, Svc::MemoryPermission own_perm) { // Set members. - m_owner = GetCurrentProcessPointer(m_kernel); + m_owner = GetCurrentProcessPointer(kernel); // Get the owner page table. auto& page_table = m_owner->GetPageTable(); // Construct the page group, guarding to make sure our state is valid on exit. - m_page_group.emplace(m_kernel, page_table.GetBlockInfoManager()); + m_page_group.emplace(kernel, page_table.GetBlockInfoManager()); auto pg_guard = SCOPE_GUARD { m_page_group.reset(); }; @@ -36,7 +35,7 @@ Result KTransferMemory::Initialize(KProcessAddress addr, std::size_t size, ConvertToKMemoryPermission(own_perm))); // Set remaining tracking members. - m_owner->Open(); + m_owner->Open(kernel); m_owner_perm = own_perm; m_address = addr; m_is_initialized = true; @@ -47,7 +46,7 @@ Result KTransferMemory::Initialize(KProcessAddress addr, std::size_t size, R_SUCCEED(); } -void KTransferMemory::Finalize() { +void KTransferMemory::Finalize(KernelCore& kernel) { // Unlock. if (!m_is_mapped) { const size_t size = m_page_group->GetNumPages() * PageSize; @@ -56,17 +55,17 @@ void KTransferMemory::Finalize() { } // Close the page group. - m_page_group->Close(m_kernel); + m_page_group->Close(kernel); m_page_group->Finalize(); } -void KTransferMemory::PostDestroy(uintptr_t arg) { +void KTransferMemory::PostDestroy(KernelCore& kernel, uintptr_t arg) { KProcess* owner = reinterpret_cast(arg); - owner->GetResourceLimit()->Release(LimitableResource::TransferMemoryCountMax, 1); - owner->Close(); + owner->GetResourceLimit()->Release(kernel, LimitableResource::TransferMemoryCountMax, 1); + owner->Close(kernel); } -Result KTransferMemory::Map(KProcessAddress address, size_t size, Svc::MemoryPermission map_perm) { +Result KTransferMemory::Map(KernelCore& kernel, KProcessAddress address, size_t size, Svc::MemoryPermission map_perm) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -83,7 +82,7 @@ Result KTransferMemory::Map(KProcessAddress address, size_t size, Svc::MemoryPer const KMemoryState state = (m_owner_perm == Svc::MemoryPermission::None) ? KMemoryState::Transferred : KMemoryState::SharedTransferred; - R_TRY(GetCurrentProcess(m_kernel).GetPageTable().MapPageGroup( + R_TRY(GetCurrentProcess(kernel).GetPageTable().MapPageGroup( address, *m_page_group, state, KMemoryPermission::UserReadWrite)); // Mark ourselves as mapped. @@ -92,7 +91,7 @@ Result KTransferMemory::Map(KProcessAddress address, size_t size, Svc::MemoryPer R_SUCCEED(); } -Result KTransferMemory::Unmap(KProcessAddress address, size_t size) { +Result KTransferMemory::Unmap(KernelCore& kernel, KProcessAddress address, size_t size) { // Validate the size. R_UNLESS(m_page_group->GetNumPages() == Common::DivideUp(size, PageSize), ResultInvalidSize); @@ -103,7 +102,7 @@ Result KTransferMemory::Unmap(KProcessAddress address, size_t size) { const KMemoryState state = (m_owner_perm == Svc::MemoryPermission::None) ? KMemoryState::Transferred : KMemoryState::SharedTransferred; - R_TRY(GetCurrentProcess(m_kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, state)); + R_TRY(GetCurrentProcess(kernel).GetPageTable().UnmapPageGroup(address, *m_page_group, state)); // Mark ourselves as unmapped. ASSERT(m_is_mapped); diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index 530b452182..0753b4fd6d 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -30,9 +33,9 @@ public: explicit KTransferMemory(KernelCore& kernel); ~KTransferMemory() override; - Result Initialize(KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm); + Result Initialize(KernelCore& kernel, KProcessAddress address, std::size_t size, Svc::MemoryPermission owner_perm); - void Finalize() override; + void Finalize(KernelCore& kernel) override; bool IsInitialized() const override { return m_is_initialized; @@ -42,7 +45,7 @@ public: return reinterpret_cast(m_owner); } - static void PostDestroy(uintptr_t arg); + static void PostDestroy(KernelCore& kernel, uintptr_t arg); KProcess* GetOwner() const override { return m_owner; @@ -54,8 +57,8 @@ public: size_t GetSize() const; - Result Map(KProcessAddress address, size_t size, Svc::MemoryPermission map_perm); - Result Unmap(KProcessAddress address, size_t size); + Result Map(KernelCore& kernel, KProcessAddress address, size_t size, Svc::MemoryPermission map_perm); + Result Unmap(KernelCore& kernel, KProcessAddress address, size_t size); private: std::optional m_page_group{}; diff --git a/src/core/hle/kernel/k_worker_task.h b/src/core/hle/kernel/k_worker_task.h index 9a230c03c4..a4820bc412 100644 --- a/src/core/hle/kernel/k_worker_task.h +++ b/src/core/hle/kernel/k_worker_task.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,8 +13,7 @@ namespace Kernel { class KWorkerTask : public KSynchronizationObject { public: explicit KWorkerTask(KernelCore& kernel); - - void DoWorkerTask(); + void DoWorkerTask(KernelCore& kernel); }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_worker_task_manager.cpp b/src/core/hle/kernel/k_worker_task_manager.cpp index 8ead395911..4427f9859a 100644 --- a/src/core/hle/kernel/k_worker_task_manager.cpp +++ b/src/core/hle/kernel/k_worker_task_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -12,14 +15,14 @@ namespace Kernel { KWorkerTask::KWorkerTask(KernelCore& kernel) : KSynchronizationObject{kernel} {} -void KWorkerTask::DoWorkerTask() { +void KWorkerTask::DoWorkerTask(KernelCore& kernel) { if (auto* const thread = this->DynamicCast(); thread != nullptr) { - return thread->DoWorkerTaskImpl(); + return thread->DoWorkerTaskImpl(kernel); } else { auto* const process = this->DynamicCast(); ASSERT(process != nullptr); - return process->DoWorkerTaskImpl(); + return process->DoWorkerTaskImpl(kernel); } } @@ -32,9 +35,9 @@ void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTas void KWorkerTaskManager::AddTask(KernelCore& kernel, KWorkerTask* task) { KScopedSchedulerLock sl(kernel); - m_waiting_thread.QueueWork([task]() { + m_waiting_thread.QueueWork([&kernel, task]() { // Do the task. - task->DoWorkerTask(); + task->DoWorkerTask(kernel); }); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 01feac52a9..b5d6489ea7 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -121,14 +121,14 @@ struct KernelCore::Impl { void TerminateAllProcesses() { std::scoped_lock lk{process_list_lock}; for (auto& process : process_list) { - process->Terminate(); - process->Close(); + process->Terminate(system.Kernel()); + process->Close(system.Kernel()); process = nullptr; } process_list.clear(); } - void Shutdown() { + void Shutdown(KernelCore& kernel) { is_shutting_down.store(true, std::memory_order_relaxed); SCOPE_EXIT { is_shutting_down.store(false, std::memory_order_relaxed); @@ -137,7 +137,7 @@ struct KernelCore::Impl { CloseServices(); if (application_process) { - application_process->Close(); + application_process->Close(system.Kernel()); application_process = nullptr; } @@ -149,9 +149,9 @@ struct KernelCore::Impl { preemption_event = nullptr; // Cleanup persistent kernel objects - auto CleanupObject = [](KAutoObject* obj) { + auto CleanupObject = [&kernel](KAutoObject* obj) { if (obj) { - obj->Close(); + obj->Close(kernel); obj = nullptr; } }; @@ -163,7 +163,7 @@ struct KernelCore::Impl { for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { if (shutdown_threads[core_id]) { - shutdown_threads[core_id]->Close(); + shutdown_threads[core_id]->Close(kernel); shutdown_threads[core_id] = nullptr; } @@ -178,7 +178,7 @@ struct KernelCore::Impl { std::scoped_lock lk{registered_in_use_objects_lock}; if (registered_in_use_objects.size()) { for (auto& object : registered_in_use_objects) { - object->Close(); + object->Close(kernel); } registered_in_use_objects.clear(); } @@ -247,12 +247,11 @@ struct KernelCore::Impl { ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 900).IsSuccess()); ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200).IsSuccess()); ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 1133).IsSuccess()); - system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, kernel_size); + system_resource_limit->Reserve(kernel, LimitableResource::PhysicalMemoryMax, kernel_size); // Reserve secure applet memory, introduced in firmware 5.0.0 constexpr u64 secure_applet_memory_size{4_MiB}; - ASSERT(system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, - secure_applet_memory_size)); + ASSERT(system_resource_limit->Reserve(kernel, LimitableResource::PhysicalMemoryMax, secure_applet_memory_size)); } void InitializePreemption(KernelCore& kernel) { @@ -350,9 +349,9 @@ struct KernelCore::Impl { object_name_global_data.emplace(kernel); } - void MakeApplicationProcess(KProcess* process) { + void MakeApplicationProcess(KernelCore& kernel, KProcess* process) { application_process = process; - application_process->Open(); + application_process->Open(kernel); } /// Sets the host thread ID for the caller. @@ -374,10 +373,10 @@ struct KernelCore::Impl { // Gets the dummy KThread for the caller, allocating a new one if this is the first time KThread* GetHostDummyThread(ThreadLocalData& t, KThread* existing_thread) { if (t.thread == nullptr) { - auto const initialize{[](KThread* thread) { - ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); + auto const initialize = [this](KThread* thread) { + ASSERT(KThread::InitializeDummyThread(system, thread, nullptr).IsSuccess()); return thread; - }}; + }; t.raw_thread.emplace(system.Kernel()); t.thread = existing_thread ? existing_thread : initialize(&*t.raw_thread); ASSERT(t.thread != nullptr); @@ -742,19 +741,19 @@ struct KernelCore::Impl { time_shared_mem = KSharedMemory::Create(system.Kernel()); hidbus_shared_mem = KSharedMemory::Create(system.Kernel()); - font_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, + font_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, Svc::MemoryPermission::Read, font_size); KSharedMemory::Register(kernel, font_shared_mem); - irs_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, + irs_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, Svc::MemoryPermission::Read, irs_size); KSharedMemory::Register(kernel, irs_shared_mem); - time_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, + time_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, Svc::MemoryPermission::Read, time_size); KSharedMemory::Register(kernel, time_shared_mem); - hidbus_shared_mem->Initialize(system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, + hidbus_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, Svc::MemoryPermission::None, Svc::MemoryPermission::Read, hidbus_size); KSharedMemory::Register(kernel, hidbus_shared_mem); } @@ -852,7 +851,7 @@ void KernelCore::Initialize() { } void KernelCore::Shutdown() { - impl->Shutdown(); + impl->Shutdown(*this); } void KernelCore::CloseServices() { @@ -868,7 +867,7 @@ KResourceLimit* KernelCore::GetSystemResourceLimit() { } void KernelCore::AppendNewProcess(KProcess* process) { - process->Open(); + process->Open(*this); std::scoped_lock lk{impl->process_list_lock}; impl->process_list.push_back(process); @@ -877,12 +876,12 @@ void KernelCore::AppendNewProcess(KProcess* process) { void KernelCore::RemoveProcess(KProcess* process) { std::scoped_lock lk{impl->process_list_lock}; if (std::erase(impl->process_list, process)) { - process->Close(); + process->Close(*this); } } void KernelCore::MakeApplicationProcess(KProcess* process) { - impl->MakeApplicationProcess(process); + impl->MakeApplicationProcess(*this, process); } KProcess* KernelCore::ApplicationProcess() { @@ -896,11 +895,8 @@ const KProcess* KernelCore::ApplicationProcess() const { std::list> KernelCore::GetProcessList() { std::list> processes; std::scoped_lock lk{impl->process_list_lock}; - - for (auto* const process : impl->process_list) { - processes.emplace_back(process); - } - + for (auto* const process : impl->process_list) + processes.emplace_back(*this, process); return processes; } @@ -1029,15 +1025,14 @@ void KernelCore::RegisterHostThread(KThread* existing_thread) { } } -static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process, - std::string&& thread_name, std::function&& func) { +static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process, std::string&& thread_name, std::function&& func) { // Reserve a new thread from the process resource limit. - KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax); + KScopedResourceReservation thread_reservation(kernel, process, LimitableResource::ThreadCountMax); ASSERT(thread_reservation.Succeeded()); // Initialize the thread. KThread* thread = KThread::Create(kernel); - ASSERT(R_SUCCEEDED(KThread::InitializeDummyThread(thread, process))); + ASSERT(R_SUCCEEDED(KThread::InitializeDummyThread(kernel.System(), thread, process))); // Commit the thread reservation. thread_reservation.Commit(); @@ -1057,7 +1052,7 @@ static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process, // Close the thread. // This will free the process if it is the last reference. - thread->Close(); + thread->Close(kernel); }); } @@ -1066,11 +1061,11 @@ std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name, // Make a new process. KProcess* process = KProcess::Create(*this); ASSERT(R_SUCCEEDED( - process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); + process->Initialize(*this, Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); // Ensure that we don't hold onto any extra references. SCOPE_EXIT { - process->Close(); + process->Close(*this); }; // Register the new process. @@ -1096,18 +1091,18 @@ void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function // Make a new process. KProcess* process = KProcess::Create(*this); ASSERT(R_SUCCEEDED( - process->Initialize(Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); + process->Initialize(*this, Svc::CreateProcessParameter{}, GetSystemResourceLimit(), false))); // Ensure that we don't hold onto any extra references. SCOPE_EXIT { - process->Close(); + process->Close(*this); }; // Register the new process. KProcess::Register(*this, process); // Reserve a new thread from the process resource limit. - KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax); + KScopedResourceReservation thread_reservation(*this, process, LimitableResource::ThreadCountMax); ASSERT(thread_reservation.Succeeded()); // Initialize the thread. @@ -1122,7 +1117,7 @@ void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function KThread::Register(*this, thread); // Begin running the thread. - ASSERT(R_SUCCEEDED(thread->Run())); + ASSERT(R_SUCCEEDED(thread->Run(*this))); } u32 KernelCore::GetCurrentHostThreadID() const { @@ -1206,9 +1201,9 @@ void KernelCore::SuspendEmulation(bool suspended) { for (auto& thread : process->GetThreadList()) { if (should_suspend) { - thread.RequestSuspend(SuspendType::System); + thread.RequestSuspend(*this, SuspendType::System); } else { - thread.Resume(SuspendType::System); + thread.Resume(*this, SuspendType::System); } } } @@ -1244,12 +1239,9 @@ void KernelCore::SuspendEmulation(bool suspended) { void KernelCore::ShutdownCores() { impl->TerminateAllProcesses(); - KScopedSchedulerLock lk{*this}; - - for (auto* thread : impl->shutdown_threads) { - void(thread->Run()); - } + for (auto* thread : impl->shutdown_threads) + void(thread->Run(*this)); } bool KernelCore::IsMulticore() const { diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index 1e380a183c..a81c14f643 100644 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -73,14 +73,14 @@ void PhysicalCore::RunThread(KernelCore& kernel, Kernel::KThread* thread) { while (true) { // If the thread is scheduled for termination, exit. if (thread->HasDpc() && thread->IsTerminationRequested()) { - thread->Exit(); + thread->Exit(kernel); } // Notify the debugger and go to sleep if a step was performed // and this thread has been scheduled again. if (thread->GetStepState() == StepState::StepPerformed) { system.GetDebugger().NotifyThreadStopped(thread); - thread->RequestSuspend(SuspendType::Debug); + thread->RequestSuspend(kernel, SuspendType::Debug); return; } @@ -136,7 +136,7 @@ void PhysicalCore::RunThread(KernelCore& kernel, Kernel::KThread* thread) { } else { interface->LogBacktrace(process); } - thread->RequestSuspend(SuspendType::Debug); + thread->RequestSuspend(kernel, SuspendType::Debug); return; } @@ -145,7 +145,7 @@ void PhysicalCore::RunThread(KernelCore& kernel, Kernel::KThread* thread) { if (system.DebuggerEnabled()) { system.GetDebugger().NotifyThreadWatchpoint(thread, *interface->HaltedWatchpoint()); } - thread->RequestSuspend(SuspendType::Debug); + thread->RequestSuspend(kernel, SuspendType::Debug); return; } diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h index d1bbc76709..95e6b9f6e6 100644 --- a/src/core/hle/kernel/slab_helpers.h +++ b/src/core/hle/kernel/slab_helpers.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -69,16 +72,16 @@ public: explicit KAutoObjectWithSlabHeap(KernelCore& kernel) : Base(kernel) {} virtual ~KAutoObjectWithSlabHeap() = default; - virtual void Destroy() override { + virtual void Destroy(KernelCore& kernel) override { const bool is_initialized = this->IsInitialized(); uintptr_t arg = 0; if (is_initialized) { arg = this->GetPostDestroyArgument(); - this->Finalize(); + this->Finalize(kernel); } - Free(Base::m_kernel, static_cast(this)); + Free(kernel, static_cast(this)); if (is_initialized) { - Derived::PostDestroy(arg); + Derived::PostDestroy(kernel, arg); } } @@ -89,8 +92,8 @@ public: return 0; } - size_t GetSlabIndex() const { - return SlabHeap(Base::m_kernel).GetObjectIndex(static_cast(this)); + size_t GetSlabIndex(KernelCore& kernel) const { + return SlabHeap(kernel).GetObjectIndex(static_cast(this)); } public: @@ -144,17 +147,17 @@ public: KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel) : Base(kernel) {} virtual ~KAutoObjectWithSlabHeapAndContainer() {} - virtual void Destroy() override { + virtual void Destroy(KernelCore& kernel) override { const bool is_initialized = this->IsInitialized(); uintptr_t arg = 0; if (is_initialized) { - Base::m_kernel.ObjectListContainer().Unregister(this); + kernel.ObjectListContainer().Unregister(this); arg = this->GetPostDestroyArgument(); - this->Finalize(); + this->Finalize(kernel); } - Free(Base::m_kernel, static_cast(this)); + Free(kernel, static_cast(this)); if (is_initialized) { - Derived::PostDestroy(arg); + Derived::PostDestroy(kernel, arg); } } @@ -165,8 +168,8 @@ public: return 0; } - size_t GetSlabIndex() const { - return SlabHeap(Base::m_kernel).GetObjectIndex(static_cast(this)); + size_t GetSlabIndex(KernelCore& kernel) const { + return SlabHeap(kernel).GetObjectIndex(static_cast(this)); } public: @@ -177,9 +180,8 @@ public: static Derived* Create(KernelCore& kernel) { Derived* obj = Allocate(kernel); - if (obj != nullptr) { + if (obj != nullptr) KAutoObject::Create(obj); - } return obj; } diff --git a/src/core/hle/kernel/svc/svc_activity.cpp b/src/core/hle/kernel/svc/svc_activity.cpp index c8f988dd8e..c1ab3daab3 100644 --- a/src/core/hle/kernel/svc/svc_activity.cpp +++ b/src/core/hle/kernel/svc/svc_activity.cpp @@ -33,7 +33,7 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle, R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy); // Set the activity. - R_TRY(thread->SetActivity(thread_activity)); + R_TRY(thread->SetActivity(system.Kernel(), thread_activity)); return ResultSuccess; } diff --git a/src/core/hle/kernel/svc/svc_code_memory.cpp b/src/core/hle/kernel/svc/svc_code_memory.cpp index 31349859d0..4133586d11 100644 --- a/src/core/hle/kernel/svc/svc_code_memory.cpp +++ b/src/core/hle/kernel/svc/svc_code_memory.cpp @@ -35,9 +35,6 @@ constexpr bool IsValidUnmapFromOwnerCodeMemoryPermission(MemoryPermission perm) Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t size) { LOG_TRACE(Kernel_SVC, "called, address={:#X}, size=0x{:X}", address, size); - // Get kernel instance. - auto& kernel = system.Kernel(); - // Validate address / size. R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); @@ -46,21 +43,20 @@ Result CreateCodeMemory(Core::System& system, Handle* out, u64 address, uint64_t // Create the code memory. - KCodeMemory* code_mem = KCodeMemory::Create(kernel); + KCodeMemory* code_mem = KCodeMemory::Create(system.Kernel()); R_UNLESS(code_mem != nullptr, ResultOutOfResource); SCOPE_EXIT { - code_mem->Close(); + code_mem->Close(system.Kernel()); }; // Verify that the region is in range. - R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), - ResultInvalidCurrentMemory); + R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); // Initialize the code memory. - R_TRY(code_mem->Initialize(system.DeviceMemory(), address, size)); + R_TRY(code_mem->Initialize(system.Kernel(), system.DeviceMemory(), address, size)); // Register the code memory. - KCodeMemory::Register(kernel, code_mem); + KCodeMemory::Register(system.Kernel(), code_mem); // Add the code memory to the handle table. R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(system.Kernel(), out, code_mem)); @@ -96,29 +92,23 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, switch (operation) { case CodeMemoryOperation::Map: { // Check that the region is in range. - R_UNLESS(GetCurrentProcess(system.Kernel()) - .GetPageTable() - .CanContain(address, size, KMemoryState::CodeOut), - ResultInvalidMemoryRegion); + R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion); // Check the memory permission. R_UNLESS(IsValidMapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); // Map the memory. - R_TRY(code_mem->Map(address, size)); + R_TRY(code_mem->Map(system.Kernel(), address, size)); } break; case CodeMemoryOperation::Unmap: { // Check that the region is in range. - R_UNLESS(GetCurrentProcess(system.Kernel()) - .GetPageTable() - .CanContain(address, size, KMemoryState::CodeOut), - ResultInvalidMemoryRegion); + R_UNLESS(GetCurrentProcess(system.Kernel()).GetPageTable().CanContain(address, size, KMemoryState::CodeOut), ResultInvalidMemoryRegion); // Check the memory permission. R_UNLESS(IsValidUnmapCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); // Unmap the memory. - R_TRY(code_mem->Unmap(address, size)); + R_TRY(code_mem->Unmap(system.Kernel(), address, size)); } break; case CodeMemoryOperation::MapToOwner: { // Check that the region is in range. @@ -130,7 +120,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, R_UNLESS(IsValidMapToOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); // Map the memory to its owner. - R_TRY(code_mem->MapToOwner(address, size, perm)); + R_TRY(code_mem->MapToOwner(system.Kernel(), address, size, perm)); } break; case CodeMemoryOperation::UnmapFromOwner: { // Check that the region is in range. @@ -142,7 +132,7 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle, R_UNLESS(IsValidUnmapFromOwnerCodeMemoryPermission(perm), ResultInvalidNewMemoryPermission); // Unmap the memory from its owner. - R_TRY(code_mem->UnmapFromOwner(address, size)); + R_TRY(code_mem->UnmapFromOwner(system.Kernel(), address, size)); } break; default: R_THROW(ResultInvalidEnumValue); diff --git a/src/core/hle/kernel/svc/svc_device_address_space.cpp b/src/core/hle/kernel/svc/svc_device_address_space.cpp index e5154d6bc8..2deb683d4b 100644 --- a/src/core/hle/kernel/svc/svc_device_address_space.cpp +++ b/src/core/hle/kernel/svc/svc_device_address_space.cpp @@ -32,11 +32,11 @@ Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_ KDeviceAddressSpace* das = KDeviceAddressSpace::Create(system.Kernel()); R_UNLESS(das != nullptr, ResultOutOfResource); SCOPE_EXIT { - das->Close(); + das->Close(system.Kernel()); }; // Initialize the device address space. - R_TRY(das->Initialize(das_address, das_size)); + R_TRY(das->Initialize(system.Kernel(), das_address, das_size)); // Register the device address space. KDeviceAddressSpace::Register(system.Kernel(), das); diff --git a/src/core/hle/kernel/svc/svc_event.cpp b/src/core/hle/kernel/svc/svc_event.cpp index c66e8e5862..36de3b9096 100644 --- a/src/core/hle/kernel/svc/svc_event.cpp +++ b/src/core/hle/kernel/svc/svc_event.cpp @@ -24,7 +24,7 @@ Result SignalEvent(Core::System& system, Handle event_handle) { if ((program_id & 0xFFFFFFFFFFFFFF00ull) == 0x0100000000001000ull) { KScopedAutoObject event = handle_table.GetObject(system.Kernel(), event_handle); if (event.IsNotNull()) { - event->Signal(); + event->Signal(system.Kernel()); } else { LOG_WARNING(Kernel_SVC, "SignalEvent best-effort unknown handle=0x{:08X} (ignored)", event_handle); @@ -37,7 +37,7 @@ Result SignalEvent(Core::System& system, Handle event_handle) { KScopedAutoObject event = handle_table.GetObject(system.Kernel(), event_handle); R_UNLESS(event.IsNotNull(), ResultInvalidHandle); - R_RETURN(event->Signal()); + R_RETURN(event->Signal(system.Kernel())); } Result ClearEvent(Core::System& system, Handle event_handle) { @@ -50,7 +50,7 @@ Result ClearEvent(Core::System& system, Handle event_handle) { { KScopedAutoObject event = handle_table.GetObject(system.Kernel(), event_handle); if (event.IsNotNull()) { - event->Clear(); + event->Clear(system.Kernel()); R_SUCCEED(); } } @@ -59,7 +59,7 @@ Result ClearEvent(Core::System& system, Handle event_handle) { { KScopedAutoObject readable_event = handle_table.GetObject(system.Kernel(), event_handle); if (readable_event.IsNotNull()) { - readable_event->Clear(); + readable_event->Clear(system.Kernel()); R_SUCCEED(); } } @@ -71,32 +71,31 @@ Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { LOG_DEBUG(Kernel_SVC, "called"); // Get the kernel reference and handle table. - auto& kernel = system.Kernel(); - auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); + auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable(); // Reserve a new event from the process resource limit - KScopedResourceReservation event_reservation(GetCurrentProcessPointer(kernel), + KScopedResourceReservation event_reservation(system.Kernel(), GetCurrentProcessPointer(system.Kernel()), LimitableResource::EventCountMax); R_UNLESS(event_reservation.Succeeded(), ResultLimitReached); // Create a new event. - KEvent* event = KEvent::Create(kernel); + KEvent* event = KEvent::Create(system.Kernel()); R_UNLESS(event != nullptr, ResultOutOfResource); // Initialize the event. - event->Initialize(GetCurrentProcessPointer(kernel)); + event->Initialize(system.Kernel(), GetCurrentProcessPointer(system.Kernel())); // Commit the thread reservation. event_reservation.Commit(); // Ensure that we clean up the event (and its only references are handle table) on function end. SCOPE_EXIT { - event->GetReadableEvent().Close(); - event->Close(); + event->GetReadableEvent().Close(system.Kernel()); + event->Close(system.Kernel()); }; // Register the event. - KEvent::Register(kernel, event); + KEvent::Register(system.Kernel(), event); // Add the event to the handle table. R_TRY(handle_table.Add(system.Kernel(), out_write, event)); diff --git a/src/core/hle/kernel/svc/svc_exception.cpp b/src/core/hle/kernel/svc/svc_exception.cpp index 0a1d4244ab..2b6e1a6e2d 100644 --- a/src/core/hle/kernel/svc/svc_exception.cpp +++ b/src/core/hle/kernel/svc/svc_exception.cpp @@ -115,7 +115,7 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) { if (system.DebuggerEnabled() && should_break) { auto* thread = system.Kernel().GetCurrentEmuThread(); system.GetDebugger().NotifyThreadStopped(thread); - thread->RequestSuspend(Kernel::SuspendType::Debug); + thread->RequestSuspend(system.Kernel(), Kernel::SuspendType::Debug); } } diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index f97ec62b73..62f203476e 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -90,11 +90,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::TotalMemorySize: - *result = process->GetTotalUserPhysicalMemorySize(); + *result = process->GetTotalUserPhysicalMemorySize(system.Kernel()); R_SUCCEED(); case InfoType::UsedMemorySize: - *result = process->GetUsedUserPhysicalMemorySize(); + *result = process->GetUsedUserPhysicalMemorySize(system.Kernel()); R_SUCCEED(); case InfoType::SystemResourceSizeTotal: @@ -114,11 +114,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle R_SUCCEED(); case InfoType::TotalNonSystemMemorySize: - *result = process->GetTotalNonSystemUserPhysicalMemorySize(); + *result = process->GetTotalNonSystemUserPhysicalMemorySize(system.Kernel()); R_SUCCEED(); case InfoType::UsedNonSystemMemorySize: - *result = process->GetUsedNonSystemUserPhysicalMemorySize(); + *result = process->GetUsedNonSystemUserPhysicalMemorySize(system.Kernel()); R_SUCCEED(); case InfoType::IsApplication: diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 9131727e8e..875590d6f7 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -26,11 +26,11 @@ Result SendSyncRequestImpl(KernelCore& kernel, uintptr_t message, size_t buffer_ R_UNLESS(session.IsNotNull(), ResultInvalidHandle); // Get the parent, and persist a reference to it until we're done. - KScopedAutoObject parent = session->GetParent(); + KScopedAutoObject parent = {kernel, session->GetParent()}; ASSERT(parent.IsNotNull()); // Send the request. - R_RETURN(session->SendSyncRequest(message, buffer_size)); + R_RETURN(session->SendSyncRequest(kernel, message, buffer_size)); } Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t message, @@ -48,7 +48,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes }; // Send the reply. - R_TRY(session->SendReply(message, buffer_size, message_paddr)); + R_TRY(session->SendReply(kernel, message, buffer_size, message_paddr)); } // Receive a message. @@ -74,8 +74,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes while (true) { // Wait for an object. s32 index; - Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs, - num_objects, timeout); + Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs, num_objects, timeout); if (ResultTimedOut == result) { R_THROW(result); } @@ -84,7 +83,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes if (R_SUCCEEDED(result)) { KServerSession* session = objs[index]->DynamicCast(); if (session != nullptr) { - result = session->ReceiveRequest(message, buffer_size, message_paddr); + result = session->ReceiveRequest(kernel, message, buffer_size, message_paddr); if (ResultNotFound == result) { continue; } @@ -131,7 +130,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes // Ensure handles are closed when we're done. SCOPE_EXIT { for (auto i = 0; i < num_handles; ++i) { - objs[i]->Close(); + objs[i]->Close(kernel); } }; @@ -185,8 +184,7 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha auto& handle_table = process.GetHandleTable(); // Reserve a new event from the process resource limit. - KScopedResourceReservation event_reservation(std::addressof(process), - Svc::LimitableResource::EventCountMax); + KScopedResourceReservation event_reservation(system.Kernel(), std::addressof(process), Svc::LimitableResource::EventCountMax); R_UNLESS(event_reservation.Succeeded(), ResultLimitReached); // Get the client session. @@ -194,7 +192,7 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha R_UNLESS(session.IsNotNull(), ResultInvalidHandle); // Get the parent, and persist a reference to it until we're done. - KScopedAutoObject parent = session->GetParent(); + KScopedAutoObject parent = {system.Kernel(), session->GetParent()}; ASSERT(parent.IsNotNull()); // Create a new event. @@ -202,15 +200,15 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha R_UNLESS(event != nullptr, ResultOutOfResource); // Initialize the event. - event->Initialize(std::addressof(process)); + event->Initialize(system.Kernel(), std::addressof(process)); // Commit our reservation. event_reservation.Commit(); // At end of scope, kill the standing references to the sub events. SCOPE_EXIT { - event->GetReadableEvent().Close(); - event->Close(); + event->GetReadableEvent().Close(system.Kernel()); + event->Close(system.Kernel()); }; // Register the event. @@ -225,7 +223,7 @@ Result SendAsyncRequestWithUserBuffer(Core::System& system, Handle* out_event_ha }; // Send the async request. - R_RETURN(session->SendAsyncRequest(event, message, buffer_size)); + R_RETURN(session->SendAsyncRequest(system.Kernel(), event, message, buffer_size)); } Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles, s32 num_handles, diff --git a/src/core/hle/kernel/svc/svc_light_ipc.cpp b/src/core/hle/kernel/svc/svc_light_ipc.cpp index 732b84baa1..ae3ff85a88 100644 --- a/src/core/hle/kernel/svc/svc_light_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_light_ipc.cpp @@ -22,7 +22,7 @@ Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* ar R_UNLESS(session.IsNotNull(), ResultInvalidHandle); // Send the request. - R_TRY(session->SendSyncRequest(args)); + R_TRY(session->SendSyncRequest(system.Kernel(), args)); R_SUCCEED(); } @@ -35,7 +35,7 @@ Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* ar R_UNLESS(session.IsNotNull(), ResultInvalidHandle); // Handle the request. - R_TRY(session->ReplyAndReceive(args)); + R_TRY(session->ReplyAndReceive(system.Kernel(), args)); R_SUCCEED(); } diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index 6244877e5d..bddd57e8f9 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp @@ -43,11 +43,11 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) { // Create a session. KClientSession* session; - R_TRY(port->CreateSession(std::addressof(session))); + R_TRY(port->CreateSession(system.Kernel(), std::addressof(session))); // Register the session in the table, close the extra reference. handle_table.Register(system.Kernel(), *out, session); - session->Close(); + session->Close(system.Kernel()); // We succeeded. R_SUCCEED(); @@ -68,12 +68,12 @@ Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, R_UNLESS(port != nullptr, ResultOutOfResource); // Initialize the port. - port->Initialize(max_sessions, is_light, name); + port->Initialize(system.Kernel(), max_sessions, is_light, name); // Ensure that we clean up the port (and its only references are handle table) on function end. SCOPE_EXIT { - port->GetServerPort().Close(); - port->GetClientPort().Close(); + port->GetServerPort().Close(system.Kernel()); + port->GetClientPort().Close(system.Kernel()); }; // Register the port. @@ -108,17 +108,15 @@ Result ConnectToPort(Core::System& system, Handle* out, Handle port) { // Create the session. KAutoObject* session; - if (client_port->IsLight()) { - R_TRY(client_port->CreateLightSession( - reinterpret_cast(std::addressof(session)))); + if (client_port->IsLight(system.Kernel())) { + R_TRY(client_port->CreateLightSession(system.Kernel(), reinterpret_cast(std::addressof(session)))); } else { - R_TRY(client_port->CreateSession( - reinterpret_cast(std::addressof(session)))); + R_TRY(client_port->CreateSession(system.Kernel(), reinterpret_cast(std::addressof(session)))); } // Register the session. handle_table.Register(system.Kernel(), *out, session); - session->Close(); + session->Close(system.Kernel()); // We succeeded. R_SUCCEED(); @@ -146,15 +144,15 @@ Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t R_UNLESS(port != nullptr, ResultOutOfResource); // Initialize the new port. - port->Initialize(max_sessions, false, 0); + port->Initialize(system.Kernel(), max_sessions, false, 0); // Register the port. KPort::Register(system.Kernel(), port); // Ensure that our only reference to the port is in the handle table when we're done. SCOPE_EXIT { - port->GetClientPort().Close(); - port->GetServerPort().Close(); + port->GetClientPort().Close(system.Kernel()); + port->GetServerPort().Close(system.Kernel()); }; // Register the handle in the table. diff --git a/src/core/hle/kernel/svc/svc_resource_limit.cpp b/src/core/hle/kernel/svc/svc_resource_limit.cpp index c9a30fb21d..7f78aa8b10 100644 --- a/src/core/hle/kernel/svc/svc_resource_limit.cpp +++ b/src/core/hle/kernel/svc/svc_resource_limit.cpp @@ -22,7 +22,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) { // Ensure we don't leak a reference to the limit. SCOPE_EXIT { - resource_limit->Close(); + resource_limit->Close(system.Kernel()); }; // Initialize the resource limit. diff --git a/src/core/hle/kernel/svc/svc_session.cpp b/src/core/hle/kernel/svc/svc_session.cpp index 0c6a1baf05..4d04f0c5a3 100644 --- a/src/core/hle/kernel/svc/svc_session.cpp +++ b/src/core/hle/kernel/svc/svc_session.cpp @@ -26,7 +26,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien // Reserve a new session from the process resource limit. // TODO: Dynamic resource limits - KScopedResourceReservation session_reservation(std::addressof(process), + KScopedResourceReservation session_reservation(system.Kernel(), std::addressof(process), LimitableResource::SessionCountMax); if (session_reservation.Succeeded()) { session = T::Create(system.Kernel()); @@ -65,7 +65,7 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien R_UNLESS(session != nullptr, ResultOutOfResource); // Initialize the session. - session->Initialize(nullptr, name); + session->Initialize(system.Kernel(), nullptr, name); // Commit the session reservation. session_reservation.Commit(); @@ -73,8 +73,8 @@ Result CreateSession(Core::System& system, Handle* out_server, Handle* out_clien // Ensure that we clean up the session (and its only references are handle table) on function // end. SCOPE_EXIT { - session->GetClientSession().Close(); - session->GetServerSession().Close(); + session->GetClientSession().Close(system.Kernel()); + session->GetServerSession().Close(system.Kernel()); }; // Register the session. @@ -119,10 +119,10 @@ Result AcceptSession(Core::System& system, Handle* out, Handle port_handle) { // Accept the session. KAutoObject* session; - if (port->IsLight()) { - session = port->AcceptLightSession(); + if (port->IsLight(system.Kernel())) { + session = port->AcceptLightSession(system.Kernel()); } else { - session = port->AcceptSession(); + session = port->AcceptSession(system.Kernel()); } // Ensure we accepted successfully. @@ -130,7 +130,7 @@ Result AcceptSession(Core::System& system, Handle* out, Handle port_handle) { // Register the session. handle_table.Register(system.Kernel(), *out, session); - session->Close(); + session->Close(system.Kernel()); R_SUCCEED(); } diff --git a/src/core/hle/kernel/svc/svc_shared_memory.cpp b/src/core/hle/kernel/svc/svc_shared_memory.cpp index 1f426fd232..66cf5902ec 100644 --- a/src/core/hle/kernel/svc/svc_shared_memory.cpp +++ b/src/core/hle/kernel/svc/svc_shared_memory.cpp @@ -56,11 +56,11 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u R_UNLESS(page_table.CanContain(address, size, KMemoryState::Shared), ResultInvalidMemoryRegion); // Add the shared memory to the process. - R_TRY(process.AddSharedMemory(shmem.GetPointerUnsafe(), address, size)); + R_TRY(process.AddSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size)); // Ensure that we clean up the shared memory if we fail to map it. ON_RESULT_FAILURE { - process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size); + process.RemoveSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size); }; // Map the shared memory. @@ -89,7 +89,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, R_TRY(shmem->Unmap(process, address, size)); // Remove the shared memory from the process. - process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size); + process.RemoveSharedMemory(system.Kernel(), shmem.GetPointerUnsafe(), address, size); R_SUCCEED(); } diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index f9a4e5f992..1b29fd5865 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp @@ -37,7 +37,7 @@ Result ResetSignal(Core::System& system, Handle handle) { { KScopedAutoObject readable_event = handle_table.GetObject(system.Kernel(), handle); if (readable_event.IsNotNull()) { - R_RETURN(readable_event->Reset()); + R_RETURN(readable_event->Reset(system.Kernel())); } } @@ -45,7 +45,7 @@ Result ResetSignal(Core::System& system, Handle handle) { { KScopedAutoObject process = handle_table.GetObject(system.Kernel(), handle); if (process.IsNotNull()) { - R_RETURN(process->Reset()); + R_RETURN(process->Reset(system.Kernel())); } } @@ -62,17 +62,14 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); // Get the synchronization context. - auto& kernel = system.Kernel(); - auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); - auto objs = GetCurrentThread(kernel).GetSynchronizationObjectBuffer(); - auto handles = GetCurrentThread(kernel).GetHandleBuffer(); + auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable(); + auto objs = GetCurrentThread(system.Kernel()).GetSynchronizationObjectBuffer(); + auto handles = GetCurrentThread(system.Kernel()).GetHandleBuffer(); // Copy user handles. if (num_handles > 0) { // Get the handles. - R_UNLESS(GetCurrentMemory(kernel).ReadBlock(user_handles, handles.data(), - sizeof(Handle) * num_handles), - ResultInvalidPointer); + R_UNLESS(GetCurrentMemory(system.Kernel()).ReadBlock(user_handles, handles.data(), sizeof(Handle) * num_handles), ResultInvalidPointer); // Convert the handles to objects. R_UNLESS(handle_table.GetMultipleObjects(system.Kernel(), objs.data(), handles.data(), num_handles), ResultInvalidHandle); @@ -81,14 +78,14 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha // Ensure handles are closed when we're done. SCOPE_EXIT { for (auto i = 0; i < num_handles; ++i) { - objs[i]->Close(); + objs[i]->Close(system.Kernel()); } }; // Convert the timeout from nanoseconds to ticks. s64 timeout; if (timeout_ns > 0) { - u64 ticks = kernel.HardwareTimer().GetTick(); + u64 ticks = system.Kernel().HardwareTimer().GetTick(); ticks += timeout_ns; ticks += 2; @@ -98,7 +95,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha } // Wait on the objects. - Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout); + Result res = KSynchronizationObject::Wait(system.Kernel(), out_index, objs.data(), num_handles, timeout); R_SUCCEED_IF(res == ResultSessionClosed); R_RETURN(res); @@ -109,31 +106,28 @@ Result CancelSynchronization(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "called handle={:#X}", handle); // Get the thread from its handle. - KScopedAutoObject thread = - GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject(system.Kernel(), handle); + KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject(system.Kernel(), handle); R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Cancel the thread's wait. - thread->WaitCancel(); + thread->WaitCancel(system.Kernel()); R_SUCCEED(); } void SynchronizePreemptionState(Core::System& system) { - auto& kernel = system.Kernel(); - // Lock the scheduler. - KScopedSchedulerLock sl{kernel}; + KScopedSchedulerLock sl{system.Kernel()}; // If the current thread is pinned, unpin it. - KProcess* cur_process = GetCurrentProcessPointer(kernel); - const auto core_id = GetCurrentCoreId(kernel); + KProcess* cur_process = GetCurrentProcessPointer(system.Kernel()); + const auto core_id = GetCurrentCoreId(system.Kernel()); - if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(kernel)) { + if (cur_process->GetPinnedThread(core_id) == GetCurrentThreadPointer(system.Kernel())) { // Clear the current thread's interrupt flag. - GetCurrentThread(kernel).ClearInterruptFlag(); + GetCurrentThread(system.Kernel()).ClearInterruptFlag(system.Kernel()); // Unpin the current thread. - cur_process->UnpinCurrentThread(); + cur_process->UnpinCurrentThread(system.Kernel()); } } diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index c4d3dfa18f..b1159020d3 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -46,7 +46,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); // Reserve a new thread from the process resource limit (waiting up to 100ms). - KScopedResourceReservation thread_reservation(std::addressof(process), + KScopedResourceReservation thread_reservation(system.Kernel(), std::addressof(process), LimitableResource::ThreadCountMax, 1, kernel.HardwareTimer().GetTick() + 100000000); R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); @@ -55,7 +55,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u KThread* thread = KThread::Create(kernel); R_UNLESS(thread != nullptr, ResultOutOfResource) SCOPE_EXIT { - thread->Close(); + thread->Close(system.Kernel()); }; // Initialize the thread. @@ -69,7 +69,7 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u thread_reservation.Commit(); // Clone the current fpu status to the new thread. - thread->CloneFpuStatus(); + thread->CloneFpuStatus(system.Kernel()); // Register the new thread. KThread::Register(kernel, thread); @@ -92,7 +92,7 @@ Result StartThread(Core::System& system, Handle thread_handle) { R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Try to start the thread. - R_TRY(thread->Run()); + R_TRY(thread->Run(system.Kernel())); R_SUCCEED(); } @@ -101,7 +101,7 @@ Result StartThread(Core::System& system, Handle thread_handle) { void ExitThread(Core::System& system) { auto* const current_thread = GetCurrentThreadPointer(system.Kernel()); system.GlobalSchedulerContext().RemoveThread(current_thread); - current_thread->Exit(); + current_thread->Exit(system.Kernel()); } /// Sleep the current thread @@ -129,7 +129,7 @@ void SleepThread(Core::System& system, s64 ns) { // Sleep. // NOTE: Nintendo does not check the result of this sleep. - static_cast(GetCurrentThread(kernel).Sleep(timeout)); + static_cast(GetCurrentThread(kernel).Sleep(kernel, timeout)); } else if (yield_type == Svc::YieldType::WithoutCoreMigration) { KScheduler::YieldWithoutCoreMigration(kernel); } else if (yield_type == Svc::YieldType::WithCoreMigration) { @@ -143,26 +143,23 @@ void SleepThread(Core::System& system, s64 ns) { /// Gets the thread context Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_handle) { - LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle={:#X}", out_context, - thread_handle); - - auto& kernel = system.Kernel(); + LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle={:#X}", out_context, thread_handle); // Get the thread from its handle. - KScopedAutoObject thread = GetCurrentProcess(kernel).GetHandleTable().GetObject(system.Kernel(), thread_handle); + KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject(system.Kernel(), thread_handle); R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Require the handle be to a non-current thread in the current process. - R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(kernel), ResultInvalidHandle); - R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultBusy); + R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()), ResultInvalidHandle); + R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy); // Get the thread context. Svc::ThreadContext context{}; - R_TRY(thread->GetThreadContext3(std::addressof(context))); + R_TRY(thread->GetThreadContext3(system.Kernel(), std::addressof(context))); // Copy the thread context to user space. R_UNLESS( - GetCurrentMemory(kernel).WriteBlock(out_context, std::addressof(context), sizeof(context)), + GetCurrentMemory(system.Kernel()).WriteBlock(out_context, std::addressof(context), sizeof(context)), ResultInvalidPointer); R_SUCCEED(); @@ -196,7 +193,7 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Set the thread priority. - thread->SetBasePriority(priority); + thread->SetBasePriority(system.Kernel(), priority); R_SUCCEED(); } @@ -249,7 +246,7 @@ Result GetThreadCoreMask(Core::System& system, s32* out_core_id, u64* out_affini R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Get the core mask. - R_RETURN(thread->GetCoreMask(out_core_id, out_affinity_mask)); + R_RETURN(thread->GetCoreMask(system.Kernel(), out_core_id, out_affinity_mask)); } Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, @@ -279,7 +276,7 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); // Set the core mask. - R_RETURN(thread->SetCoreMask(core_id, affinity_mask)); + R_RETURN(thread->SetCoreMask(system.Kernel(), core_id, affinity_mask)); } /// Get the ID for the specified thread. diff --git a/src/core/hle/kernel/svc/svc_transfer_memory.cpp b/src/core/hle/kernel/svc/svc_transfer_memory.cpp index 5d12bd2830..e539eee911 100644 --- a/src/core/hle/kernel/svc/svc_transfer_memory.cpp +++ b/src/core/hle/kernel/svc/svc_transfer_memory.cpp @@ -46,8 +46,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 auto& handle_table = process.GetHandleTable(); // Reserve a new transfer memory from the process resource limit. - KScopedResourceReservation trmem_reservation(std::addressof(process), - LimitableResource::TransferMemoryCountMax); + KScopedResourceReservation trmem_reservation(system.Kernel(), std::addressof(process), LimitableResource::TransferMemoryCountMax); R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached); // Create the transfer memory. @@ -56,14 +55,14 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64 // Ensure the only reference is in the handle table when we're done. SCOPE_EXIT { - trmem->Close(); + trmem->Close(system.Kernel()); }; // Ensure that the region is in range. R_UNLESS(process.GetPageTable().Contains(address, size), ResultInvalidCurrentMemory); // Initialize the transfer memory. - R_TRY(trmem->Initialize(address, size, map_perm)); + R_TRY(trmem->Initialize(system.Kernel(), address, size, map_perm)); // Commit the reservation. trmem_reservation.Commit(); @@ -99,7 +98,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add ResultInvalidMemoryRegion); // Map the transfer memory. - R_TRY(trmem->Map(address, size, map_perm)); + R_TRY(trmem->Map(system.Kernel(), address, size, map_perm)); // We succeeded. R_SUCCEED(); @@ -126,7 +125,7 @@ Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t a ResultInvalidMemoryRegion); // Unmap the transfer memory. - R_TRY(trmem->Unmap(address, size)); + R_TRY(trmem->Unmap(system.Kernel(), address, size)); R_SUCCEED(); } diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp index c9e0af90ce..c767e46e8f 100644 --- a/src/core/hle/service/acc/async_context.cpp +++ b/src/core/hle/service/acc/async_context.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -64,7 +67,7 @@ void IAsyncContext::GetResult(HLERequestContext& ctx) { void IAsyncContext::MarkComplete() { is_complete.store(true); - completion_event->Signal(); + completion_event->Signal(system.Kernel()); } } // namespace Service::Account diff --git a/src/core/hle/service/am/applet.cpp b/src/core/hle/service/am/applet.cpp index 2ae3102aff..c080afe099 100644 --- a/src/core/hle/service/am/applet.cpp +++ b/src/core/hle/service/am/applet.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 2024 yuzu Emulator @@ -76,7 +76,7 @@ void Applet::SetInteractibleLocked(bool interactible) { void Applet::OnProcessTerminatedLocked() { is_completed = true; - state_changed_event.Signal(); + state_changed_event.Signal(context.kernel); } } // namespace Service::AM diff --git a/src/core/hle/service/am/applet_data_broker.cpp b/src/core/hle/service/am/applet_data_broker.cpp index fff78c5afb..f75baac282 100644 --- a/src/core/hle/service/am/applet_data_broker.cpp +++ b/src/core/hle/service/am/applet_data_broker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,22 +14,23 @@ namespace Service::AM { AppletStorageChannel::AppletStorageChannel(KernelHelpers::ServiceContext& context) - : m_event(context) {} + : m_event(context) +{} AppletStorageChannel::~AppletStorageChannel() = default; -void AppletStorageChannel::Push(std::shared_ptr storage) { +void AppletStorageChannel::Push(Kernel::KernelCore& kernel, std::shared_ptr storage) { std::scoped_lock lk{m_lock}; m_data.emplace_back(std::move(storage)); - m_event.Signal(); + m_event.Signal(kernel); } -Result AppletStorageChannel::Pop(std::shared_ptr* out_storage) { +Result AppletStorageChannel::Pop(Kernel::KernelCore& kernel, std::shared_ptr* out_storage) { std::scoped_lock lk{m_lock}; SCOPE_EXIT { if (m_data.empty()) { - m_event.Clear(); + m_event.Clear(kernel); } }; diff --git a/src/core/hle/service/am/applet_data_broker.h b/src/core/hle/service/am/applet_data_broker.h index 2718f608ad..36ce8a24d4 100644 --- a/src/core/hle/service/am/applet_data_broker.h +++ b/src/core/hle/service/am/applet_data_broker.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -22,8 +25,8 @@ public: explicit AppletStorageChannel(KernelHelpers::ServiceContext& ctx); ~AppletStorageChannel(); - void Push(std::shared_ptr storage); - Result Pop(std::shared_ptr* out_storage); + void Push(Kernel::KernelCore& kernel, std::shared_ptr storage); + Result Pop(Kernel::KernelCore& kernel, std::shared_ptr* out_storage); Kernel::KReadableEvent* GetEvent(); private: diff --git a/src/core/hle/service/am/applet_manager.cpp b/src/core/hle/service/am/applet_manager.cpp index 2bedce03cb..2388faa541 100644 --- a/src/core/hle/service/am/applet_manager.cpp +++ b/src/core/hle/service/am/applet_manager.cpp @@ -34,8 +34,7 @@ struct LaunchParameterAccountPreselectedUser { }; static_assert(sizeof(LaunchParameterAccountPreselectedUser) == 0x88); -AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system, - std::shared_ptr& applet) { +AppletStorageChannel& InitializeFakeCallerApplet(Core::System& system, std::shared_ptr& applet) { applet->caller_applet_broker = std::make_shared(system); return applet->caller_applet_broker->GetInData(); } @@ -52,7 +51,7 @@ void PushInShowQlaunch(Core::System& system, AppletStorageChannel& channel) { std::vector argument_data(sizeof(arguments)); std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); - channel.Push(std::make_shared(system, std::move(argument_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(argument_data))); } void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { @@ -68,8 +67,8 @@ void PushInShowAlbum(Core::System& system, AppletStorageChannel& channel) { std::vector argument_data(sizeof(arguments)); std::vector settings_data{2}; std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); - channel.Push(std::make_shared(system, std::move(argument_data))); - channel.Push(std::make_shared(system, std::move(settings_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(argument_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(settings_data))); } void PushInShowController(Core::System& system, AppletStorageChannel& channel) { @@ -116,9 +115,9 @@ void PushInShowController(Core::System& system, AppletStorageChannel& channel) { std::memcpy(private_args_data.data(), &private_args, sizeof(private_args)); std::memcpy(user_args_data.data(), &user_args, sizeof(user_args)); - channel.Push(std::make_shared(system, std::move(common_args_data))); - channel.Push(std::make_shared(system, std::move(private_args_data))); - channel.Push(std::make_shared(system, std::move(user_args_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(common_args_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(private_args_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(user_args_data))); } void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) { @@ -146,8 +145,8 @@ void PushInShowCabinetData(Core::System& system, AppletStorageChannel& channel) std::vector settings_data(sizeof(amiibo_settings)); std::memcpy(argument_data.data(), &arguments, sizeof(arguments)); std::memcpy(settings_data.data(), &amiibo_settings, sizeof(amiibo_settings)); - channel.Push(std::make_shared(system, std::move(argument_data))); - channel.Push(std::make_shared(system, std::move(settings_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(argument_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(settings_data))); } void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) { @@ -169,7 +168,7 @@ void PushInShowMiiEditData(Core::System& system, AppletStorageChannel& channel) std::vector argument_data(sizeof(mii_arguments)); std::memcpy(argument_data.data(), &mii_arguments, sizeof(mii_arguments)); - channel.Push(std::make_shared(system, std::move(argument_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(argument_data))); } void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& channel) { @@ -222,9 +221,9 @@ void PushInShowSoftwareKeyboard(Core::System& system, AppletStorageChannel& chan std::memcpy(work_buffer.data(), initial_string.data(), swkbd_config.initial_string_length * sizeof(char16_t)); - channel.Push(std::make_shared(system, std::move(argument_data))); - channel.Push(std::make_shared(system, std::move(swkbd_data))); - channel.Push(std::make_shared(system, std::move(work_buffer))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(argument_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(swkbd_data))); + channel.Push(system.Kernel(), std::make_shared(system, std::move(work_buffer))); } } // namespace @@ -340,7 +339,7 @@ void AppletManager::SetWindowSystem(WindowSystem* window_system) { } // Applet was started by frontend, so it is foreground. - applet->lifecycle_manager.SetFocusState(FocusState::InFocus); + applet->lifecycle_manager.SetFocusState(m_system.Kernel(), FocusState::InFocus); if (applet->applet_id == AppletId::QLaunch) { applet->lifecycle_manager.SetFocusHandlingMode(false); diff --git a/src/core/hle/service/am/event_observer.cpp b/src/core/hle/service/am/event_observer.cpp index ef944c1993..32cb35ee30 100644 --- a/src/core/hle/service/am/event_observer.cpp +++ b/src/core/hle/service/am/event_observer.cpp @@ -41,7 +41,7 @@ EventObserver::EventObserver(Core::System& system, WindowSystem& window_system) EventObserver::~EventObserver() { // Signal thread and wait for processing to finish. m_stop_source.request_stop(); - m_wakeup_event.Signal(); + m_wakeup_event.Signal(m_system.Kernel()); m_thread.join(); // Free remaining owned sessions. @@ -76,11 +76,11 @@ void EventObserver::TrackAppletProcess(Applet& applet) { } // Signal wakeup. - m_wakeup_event.Signal(); + m_wakeup_event.Signal(m_system.Kernel()); } void EventObserver::RequestUpdate() { - m_wakeup_event.Signal(); + m_wakeup_event.Signal(m_system.Kernel()); } void EventObserver::LinkDeferred() { @@ -121,7 +121,7 @@ void EventObserver::Process(MultiWaitHolder* holder) { } void EventObserver::OnWakeupEvent(MultiWaitHolder* holder) { - m_wakeup_event.Clear(); + m_wakeup_event.Clear(m_system.Kernel()); // Perform recalculation. m_window_system.Update(); diff --git a/src/core/hle/service/am/frontend/applet_general.cpp b/src/core/hle/service/am/frontend/applet_general.cpp index 5345fdec33..22cad54b66 100644 --- a/src/core/hle/service/am/frontend/applet_general.cpp +++ b/src/core/hle/service/am/frontend/applet_general.cpp @@ -20,16 +20,16 @@ namespace Service::AM::Frontend { constexpr Result ERROR_INVALID_PIN{ErrorModule::PCTL, 221}; -static void LogCurrentStorage(std::shared_ptr applet, std::string_view prefix) { +static void LogCurrentStorage(Kernel::KernelCore& kernel, std::shared_ptr applet, std::string_view prefix) { std::shared_ptr storage; - while (R_SUCCEEDED(applet->caller_applet_broker->GetInData().Pop(&storage))) { + while (R_SUCCEEDED(applet->caller_applet_broker->GetInData().Pop(kernel, &storage))) { const auto data = storage->GetData(); LOG_INFO(Service_AM, "called (STUBBED), during {} received normal data with size={:08X}, data={}", prefix, data.size(), Common::HexToString(data)); } - while (R_SUCCEEDED(applet->caller_applet_broker->GetInteractiveInData().Pop(&storage))) { + while (R_SUCCEEDED(applet->caller_applet_broker->GetInteractiveInData().Pop(kernel, &storage))) { const auto data = storage->GetData(); LOG_INFO(Service_AM, "called (STUBBED), during {} received interactive data with size={:08X}, data={}", @@ -219,7 +219,7 @@ void StubApplet::Initialize() { LOG_WARNING(Service_AM, "called (STUBBED)"); FrontendApplet::Initialize(); - LogCurrentStorage(applet.lock(), "Initialize"); + LogCurrentStorage(system.Kernel(), applet.lock(), "Initialize"); } Result StubApplet::GetStatus() const { @@ -229,7 +229,7 @@ Result StubApplet::GetStatus() const { void StubApplet::ExecuteInteractive() { LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(applet.lock(), "ExecuteInteractive"); + LogCurrentStorage(system.Kernel(), applet.lock(), "ExecuteInteractive"); PushOutData(std::make_shared(system, std::vector(0x1000))); PushInteractiveOutData(std::make_shared(system, std::vector(0x1000))); @@ -238,7 +238,7 @@ void StubApplet::ExecuteInteractive() { void StubApplet::Execute() { LOG_WARNING(Service_AM, "called (STUBBED)"); - LogCurrentStorage(applet.lock(), "Execute"); + LogCurrentStorage(system.Kernel(), applet.lock(), "Execute"); PushOutData(std::make_shared(system, std::vector(0x1000))); PushInteractiveOutData(std::make_shared(system, std::vector(0x1000))); diff --git a/src/core/hle/service/am/frontend/applets.cpp b/src/core/hle/service/am/frontend/applets.cpp index 2ff2bcdbb6..407ca10602 100644 --- a/src/core/hle/service/am/frontend/applets.cpp +++ b/src/core/hle/service/am/frontend/applets.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 #include @@ -52,22 +52,22 @@ void FrontendApplet::Initialize() { std::shared_ptr FrontendApplet::PopInData() { std::shared_ptr ret; - applet.lock()->caller_applet_broker->GetInData().Pop(&ret); + applet.lock()->caller_applet_broker->GetInData().Pop(system.Kernel(), &ret); return ret; } std::shared_ptr FrontendApplet::PopInteractiveInData() { std::shared_ptr ret; - applet.lock()->caller_applet_broker->GetInteractiveInData().Pop(&ret); + applet.lock()->caller_applet_broker->GetInteractiveInData().Pop(system.Kernel(), &ret); return ret; } void FrontendApplet::PushOutData(std::shared_ptr storage) { - applet.lock()->caller_applet_broker->GetOutData().Push(storage); + applet.lock()->caller_applet_broker->GetOutData().Push(system.Kernel(), storage); } void FrontendApplet::PushInteractiveOutData(std::shared_ptr storage) { - applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(storage); + applet.lock()->caller_applet_broker->GetInteractiveOutData().Push(system.Kernel(), storage); } void FrontendApplet::Exit() { @@ -75,7 +75,7 @@ void FrontendApplet::Exit() { std::scoped_lock lk{applet_->lock}; applet_->is_completed = true; - applet_->state_changed_event.Signal(); + applet_->state_changed_event.Signal(system.Kernel()); } FrontendAppletSet::FrontendAppletSet() = default; diff --git a/src/core/hle/service/am/library_applet_storage.cpp b/src/core/hle/service/am/library_applet_storage.cpp index 0412c215d5..8b14511c72 100644 --- a/src/core/hle/service/am/library_applet_storage.cpp +++ b/src/core/hle/service/am/library_applet_storage.cpp @@ -1,7 +1,11 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "core/hle/kernel/k_transfer_memory.h" +#include "core/hle/kernel/kernel.h" #include "core/hle/service/am/am_results.h" #include "core/hle/service/am/library_applet_storage.h" #include "core/memory.h" @@ -55,15 +59,18 @@ private: class TransferMemoryLibraryAppletStorage : public LibraryAppletStorage { public: - explicit TransferMemoryLibraryAppletStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, bool is_writable, - s64 size) - : m_memory(memory), m_trmem(trmem), m_is_writable(is_writable), m_size(size) { - m_trmem->Open(); + explicit TransferMemoryLibraryAppletStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, bool is_writable, s64 size) + : m_kernel{kernel} + , m_memory(memory) + , m_trmem(trmem) + , m_is_writable(is_writable) + , m_size(size) + { + m_trmem->Open(m_kernel); } ~TransferMemoryLibraryAppletStorage() { - m_trmem->Close(); + m_trmem->Close(m_kernel); m_trmem = nullptr; } @@ -93,6 +100,7 @@ public: } protected: + Kernel::KernelCore& m_kernel; Core::Memory::Memory& m_memory; Kernel::KTransferMemory* m_trmem; bool m_is_writable; @@ -101,9 +109,9 @@ protected: class HandleLibraryAppletStorage : public TransferMemoryLibraryAppletStorage { public: - explicit HandleLibraryAppletStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, s64 size) - : TransferMemoryLibraryAppletStorage(memory, trmem, true, size) {} + explicit HandleLibraryAppletStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, s64 size) + : TransferMemoryLibraryAppletStorage(kernel, memory, trmem, true, size) + {} ~HandleLibraryAppletStorage() = default; Kernel::KTransferMemory* GetHandle() override { @@ -125,16 +133,12 @@ std::shared_ptr CreateStorage(std::vector&& data) { return std::make_shared(std::move(data)); } -std::shared_ptr CreateTransferMemoryStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, - bool is_writable, s64 size) { - return std::make_shared(memory, trmem, is_writable, size); +std::shared_ptr CreateTransferMemoryStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, bool is_writable, s64 size) { + return std::make_shared(kernel, memory, trmem, is_writable, size); } -std::shared_ptr CreateHandleStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, - s64 size) { - return std::make_shared(memory, trmem, size); +std::shared_ptr CreateHandleStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, s64 size) { + return std::make_shared(kernel, memory, trmem, size); } } // namespace Service::AM diff --git a/src/core/hle/service/am/library_applet_storage.h b/src/core/hle/service/am/library_applet_storage.h index 7f53f3a9cd..cfdbef96d0 100644 --- a/src/core/hle/service/am/library_applet_storage.h +++ b/src/core/hle/service/am/library_applet_storage.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,6 +13,7 @@ class Memory; } namespace Kernel { +class KernelCore; class KTransferMemory; } @@ -27,10 +31,7 @@ public: }; std::shared_ptr CreateStorage(std::vector&& data); -std::shared_ptr CreateTransferMemoryStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, - bool is_writable, s64 size); -std::shared_ptr CreateHandleStorage(Core::Memory::Memory& memory, - Kernel::KTransferMemory* trmem, s64 size); +std::shared_ptr CreateTransferMemoryStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, bool is_writable, s64 size); +std::shared_ptr CreateHandleStorage(Kernel::KernelCore& kernel, Core::Memory::Memory& memory, Kernel::KTransferMemory* trmem, s64 size); } // namespace Service::AM diff --git a/src/core/hle/service/am/lifecycle_manager.cpp b/src/core/hle/service/am/lifecycle_manager.cpp index a79ef6f5f5..8d6965a06c 100644 --- a/src/core/hle/service/am/lifecycle_manager.cpp +++ b/src/core/hle/service/am/lifecycle_manager.cpp @@ -28,9 +28,9 @@ Event& LifecycleManager::GetHDCPStateChangedEvent() { return m_hdcp_state_changed_event; } -void LifecycleManager::PushUnorderedMessage(AppletMessage message) { +void LifecycleManager::PushUnorderedMessage(Kernel::KernelCore& kernel, AppletMessage message) { m_unordered_messages.push_back(message); - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } AppletMessage LifecycleManager::PopMessageInOrderOfPriority() { @@ -144,36 +144,36 @@ bool LifecycleManager::ShouldSignalSystemEvent() { m_has_album_screen_shot_taken || m_has_album_recording_saved; } -void LifecycleManager::OnOperationAndPerformanceModeChanged() { +void LifecycleManager::OnOperationAndPerformanceModeChanged(Kernel::KernelCore& kernel) { if (m_operation_mode_changed_notification_enabled) { m_has_operation_mode_changed = true; } if (m_performance_mode_changed_notification_enabled) { m_has_performance_mode_changed = true; } - m_operation_mode_changed_system_event.Signal(); - this->SignalSystemEventIfNeeded(); + m_operation_mode_changed_system_event.Signal(kernel); + this->SignalSystemEventIfNeeded(kernel); } -void LifecycleManager::SignalSystemEventIfNeeded() { +void LifecycleManager::SignalSystemEventIfNeeded(Kernel::KernelCore& kernel) { // Check our cached value for the system event. const bool applet_message_available = m_applet_message_available; // If it's not current, we need to do an update, either clearing or signaling. if (applet_message_available != this->ShouldSignalSystemEvent()) { if (!applet_message_available) { - m_system_event.Signal(); + m_system_event.Signal(kernel); m_applet_message_available = true; } else { - m_system_event.Clear(); + m_system_event.Clear(kernel); m_applet_message_available = false; } } } -bool LifecycleManager::PopMessage(AppletMessage* out_message) { +bool LifecycleManager::PopMessage(Kernel::KernelCore& kernel, AppletMessage* out_message) { const auto message = this->PopMessageInOrderOfPriority(); - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); *out_message = message; return message != AppletMessage::None; diff --git a/src/core/hle/service/am/lifecycle_manager.h b/src/core/hle/service/am/lifecycle_manager.h index a1ddb9e2df..615aeed591 100644 --- a/src/core/hle/service/am/lifecycle_manager.h +++ b/src/core/hle/service/am/lifecycle_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -66,17 +69,17 @@ public: return m_acknowledged_focus_state; } - void SetFocusState(FocusState state) { + void SetFocusState(Kernel::KernelCore& kernel, FocusState state) { if (m_requested_focus_state != state) { m_has_focus_state_changed = true; } m_requested_focus_state = state; - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } - void RequestExit() { + void RequestExit(Kernel::KernelCore& kernel) { m_has_requested_exit = true; - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } void RequestResumeNotification() { @@ -89,22 +92,22 @@ public: } } - void OnOperationAndPerformanceModeChanged(); + void OnOperationAndPerformanceModeChanged(Kernel::KernelCore& kernel); public: - void SetFocusStateChangedNotificationEnabled(bool enabled) { + void SetFocusStateChangedNotificationEnabled(Kernel::KernelCore& kernel, bool enabled) { m_focus_state_changed_notification_enabled = enabled; - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } - void SetOperationModeChangedNotificationEnabled(bool enabled) { + void SetOperationModeChangedNotificationEnabled(Kernel::KernelCore& kernel, bool enabled) { m_operation_mode_changed_notification_enabled = enabled; - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } - void SetPerformanceModeChangedNotificationEnabled(bool enabled) { + void SetPerformanceModeChangedNotificationEnabled(Kernel::KernelCore& kernel, bool enabled) { m_performance_mode_changed_notification_enabled = enabled; - this->SignalSystemEventIfNeeded(); + this->SignalSystemEventIfNeeded(kernel); } void SetResumeNotificationEnabled(bool enabled) { @@ -129,11 +132,11 @@ public: void RemoveForceResumeIfPossible(); bool IsRunnable() const; bool UpdateRequestedFocusState(); - void SignalSystemEventIfNeeded(); + void SignalSystemEventIfNeeded(Kernel::KernelCore& kernel); public: - void PushUnorderedMessage(AppletMessage message); - bool PopMessage(AppletMessage* out_message); + void PushUnorderedMessage(Kernel::KernelCore& kernel, AppletMessage message); + bool PopMessage(Kernel::KernelCore& kernel, AppletMessage* out_message); private: FocusState GetFocusStateWhileForegroundObscured() const; diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index 5b5e21b8e0..0645e735ff 100644 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp @@ -123,21 +123,21 @@ Result ICommonStateGetter::RequestToAcquireSleepLock() { LOG_WARNING(Service_AM, "(STUBBED) called"); // Sleep lock is acquired immediately. - m_applet->sleep_lock_event.Signal(); + m_applet->sleep_lock_event.Signal(system.Kernel()); R_SUCCEED(); } Result ICommonStateGetter::ReleaseSleepLock() { LOG_WARNING(Service_AM, "(STUBBED) called"); - m_applet->sleep_lock_event.Clear(); + m_applet->sleep_lock_event.Clear(system.Kernel()); R_SUCCEED(); } Result ICommonStateGetter::ReleaseSleepLockTransiently() { LOG_WARNING(Service_AM, "(STUBBED) called"); - m_applet->sleep_lock_event.Clear(); + m_applet->sleep_lock_event.Clear(system.Kernel()); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/library_applet_accessor.cpp b/src/core/hle/service/am/service/library_applet_accessor.cpp index ef91f69c23..366a26de0a 100644 --- a/src/core/hle/service/am/service/library_applet_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_accessor.cpp @@ -123,7 +123,7 @@ Result ILibraryAppletAccessor::RequestExit() { LOG_DEBUG(Service_AM, "called"); { std::scoped_lock lk{m_applet->lock}; - m_applet->lifecycle_manager.RequestExit(); + m_applet->lifecycle_manager.RequestExit(system.Kernel()); } FrontendRequestExit(); R_SUCCEED(); @@ -157,7 +157,7 @@ Result ILibraryAppletAccessor::PushInData(SharedPointer storage) { } } - m_broker->GetInData().Push(storage); + m_broker->GetInData().Push(system.Kernel(), storage); R_SUCCEED(); } @@ -165,13 +165,13 @@ Result ILibraryAppletAccessor::PopOutData(Out> out_stora LOG_DEBUG(Service_AM, "called"); if (auto caller_applet = m_applet->caller_applet.lock(); caller_applet) { - caller_applet->lifecycle_manager.GetSystemEvent().Signal(); + caller_applet->lifecycle_manager.GetSystemEvent().Signal(system.Kernel()); caller_applet->lifecycle_manager.RequestResumeNotification(); - caller_applet->lifecycle_manager.GetSystemEvent().Clear(); + caller_applet->lifecycle_manager.GetSystemEvent().Clear(system.Kernel()); caller_applet->lifecycle_manager.UpdateRequestedFocusState(); } - R_TRY(m_broker->GetOutData().Pop(out_storage.Get())); + R_TRY(m_broker->GetOutData().Pop(system.Kernel(), out_storage.Get())); if (m_applet->applet_id == AppletId::ProfileSelect && *out_storage) { auto impl = (*out_storage)->GetImpl(); @@ -186,14 +186,14 @@ Result ILibraryAppletAccessor::PopOutData(Out> out_stora Result ILibraryAppletAccessor::PushInteractiveInData(SharedPointer storage) { LOG_DEBUG(Service_AM, "called"); - m_broker->GetInteractiveInData().Push(storage); + m_broker->GetInteractiveInData().Push(system.Kernel(), storage); FrontendExecuteInteractive(); R_SUCCEED(); } Result ILibraryAppletAccessor::PopInteractiveOutData(Out> out_storage) { LOG_DEBUG(Service_AM, "called"); - R_RETURN(m_broker->GetInteractiveOutData().Pop(out_storage.Get())); + R_RETURN(m_broker->GetInteractiveOutData().Pop(system.Kernel(), out_storage.Get())); } Result ILibraryAppletAccessor::GetPopOutDataEvent(OutCopyHandle out_event) { diff --git a/src/core/hle/service/am/service/library_applet_creator.cpp b/src/core/hle/service/am/service/library_applet_creator.cpp index 1dfb1d6e52..92c9fd4ad9 100644 --- a/src/core/hle/service/am/service/library_applet_creator.cpp +++ b/src/core/hle/service/am/service/library_applet_creator.cpp @@ -207,7 +207,7 @@ Result ILibraryAppletCreator::CreateLibraryApplet( } // Applet is created, can now be launched. - m_applet->library_applet_launchable_event.Signal(); + m_applet->library_applet_launchable_event.Signal(system.Kernel()); *out_library_applet_accessor = library_applet; R_SUCCEED(); } @@ -233,7 +233,7 @@ Result ILibraryAppletCreator::CreateLibraryAppletEx( } // Applet is created, can now be launched. - m_applet->library_applet_launchable_event.Signal(); + m_applet->library_applet_launchable_event.Signal(system.Kernel()); *out_library_applet_accessor = library_applet; R_SUCCEED(); } @@ -266,7 +266,7 @@ Result ILibraryAppletCreator::CreateTransferMemoryStorage( } *out_storage = std::make_shared( - system, AM::CreateTransferMemoryStorage(transfer_memory_handle->GetOwner()->GetMemory(), + system, AM::CreateTransferMemoryStorage(system.Kernel(), transfer_memory_handle->GetOwner()->GetMemory(), transfer_memory_handle.Get(), is_writable, size)); R_SUCCEED(); } @@ -287,7 +287,7 @@ Result ILibraryAppletCreator::CreateHandleStorage( } *out_storage = std::make_shared( - system, AM::CreateHandleStorage(transfer_memory_handle->GetOwner()->GetMemory(), + system, AM::CreateHandleStorage(system.Kernel(), transfer_memory_handle->GetOwner()->GetMemory(), transfer_memory_handle.Get(), size)); R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/library_applet_self_accessor.cpp b/src/core/hle/service/am/service/library_applet_self_accessor.cpp index 4a1d1f97d3..473a4bc955 100644 --- a/src/core/hle/service/am/service/library_applet_self_accessor.cpp +++ b/src/core/hle/service/am/service/library_applet_self_accessor.cpp @@ -93,23 +93,23 @@ ILibraryAppletSelfAccessor::~ILibraryAppletSelfAccessor() = default; Result ILibraryAppletSelfAccessor::PopInData(Out> out_storage) { LOG_INFO(Service_AM, "called"); - R_RETURN(m_broker->GetInData().Pop(out_storage)); + R_RETURN(m_broker->GetInData().Pop(system.Kernel(), out_storage)); } Result ILibraryAppletSelfAccessor::PushOutData(SharedPointer storage) { LOG_INFO(Service_AM, "called"); - m_broker->GetOutData().Push(storage); + m_broker->GetOutData().Push(system.Kernel(), storage); R_SUCCEED(); } Result ILibraryAppletSelfAccessor::PopInteractiveInData(Out> out_storage) { LOG_INFO(Service_AM, "called"); - R_RETURN(m_broker->GetInteractiveInData().Pop(out_storage)); + R_RETURN(m_broker->GetInteractiveInData().Pop(system.Kernel(), out_storage)); } Result ILibraryAppletSelfAccessor::PushInteractiveOutData(SharedPointer storage) { LOG_INFO(Service_AM, "called"); - m_broker->GetInteractiveOutData().Push(storage); + m_broker->GetInteractiveOutData().Push(system.Kernel(), storage); R_SUCCEED(); } diff --git a/src/core/hle/service/am/window_system.cpp b/src/core/hle/service/am/window_system.cpp index 5f20a98322..90115d73be 100644 --- a/src/core/hle/service/am/window_system.cpp +++ b/src/core/hle/service/am/window_system.cpp @@ -154,7 +154,7 @@ void WindowSystem::OnOperationModeChanged() { for (const auto& [aruid, applet] : m_applets) { std::scoped_lock lk2{applet->lock}; - applet->lifecycle_manager.OnOperationAndPerformanceModeChanged(); + applet->lifecycle_manager.OnOperationAndPerformanceModeChanged(m_system.Kernel()); } } @@ -163,22 +163,22 @@ void WindowSystem::OnExitRequested() { for (const auto& [aruid, applet] : m_applets) { std::scoped_lock lk2{applet->lock}; - applet->lifecycle_manager.RequestExit(); + applet->lifecycle_manager.RequestExit(m_system.Kernel()); } } void WindowSystem::SendButtonAppletMessageLocked(AppletMessage message) { if (m_home_menu) { std::scoped_lock lk_home{m_home_menu->lock}; - m_home_menu->lifecycle_manager.PushUnorderedMessage(message); + m_home_menu->lifecycle_manager.PushUnorderedMessage(m_system.Kernel(), message); } if (m_overlay_display) { std::scoped_lock lk_overlay{m_overlay_display->lock}; - m_overlay_display->lifecycle_manager.PushUnorderedMessage(message); + m_overlay_display->lifecycle_manager.PushUnorderedMessage(m_system.Kernel(), message); } if (m_application) { std::scoped_lock lk_application{m_application->lock}; - m_application->lifecycle_manager.PushUnorderedMessage(message); + m_application->lifecycle_manager.PushUnorderedMessage(m_system.Kernel(), message); } if (m_event_observer) { m_event_observer->RequestUpdate(); @@ -277,8 +277,7 @@ void WindowSystem::PruneTerminatedAppletsLocked() { // If we have a home menu, send it the application exited message. if (m_home_menu) { - m_home_menu->lifecycle_manager.PushUnorderedMessage( - AppletMessage::ApplicationExited); + m_home_menu->lifecycle_manager.PushUnorderedMessage(m_system.Kernel(), AppletMessage::ApplicationExited); } } diff --git a/src/core/hle/service/audio/audio_device.cpp b/src/core/hle/service/audio/audio_device.cpp index eb64892ed8..e9f7e074a1 100644 --- a/src/core/hle/service/audio/audio_device.cpp +++ b/src/core/hle/service/audio/audio_device.cpp @@ -42,7 +42,7 @@ IAudioDevice::IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u }; RegisterHandlers(functions); - event->Signal(); + event->Signal(system.Kernel()); } IAudioDevice::~IAudioDevice() { @@ -128,7 +128,7 @@ Result IAudioDevice::GetActiveAudioDeviceNameAuto( Result IAudioDevice::QueryAudioDeviceSystemEvent(OutCopyHandle out_event) { LOG_DEBUG(Service_Audio, "(STUBBED) called"); - event->Signal(); + event->Signal(system.Kernel()); *out_event = &event->GetReadableEvent(); R_SUCCEED(); } diff --git a/src/core/hle/service/audio/audio_in.cpp b/src/core/hle/service/audio/audio_in.cpp index 416803acc3..6208c2d104 100644 --- a/src/core/hle/service/audio/audio_in.cpp +++ b/src/core/hle/service/audio/audio_in.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -37,7 +40,7 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, RegisterHandlers(functions); - process->Open(); + process->Open(system.Kernel()); if (impl->GetSystem() .Initialize(device_name, in_params, handle, applet_resource_user_id) @@ -49,7 +52,7 @@ IAudioIn::IAudioIn(Core::System& system_, Manager& manager, size_t session_id, IAudioIn::~IAudioIn() { impl->Free(); service_context.CloseEvent(event); - process->Close(); + process->Close(system.Kernel()); } Result IAudioIn::GetAudioInState(Out out_state) { diff --git a/src/core/hle/service/audio/audio_out.cpp b/src/core/hle/service/audio/audio_out.cpp index 53009d5d74..996eeede58 100644 --- a/src/core/hle/service/audio/audio_out.cpp +++ b/src/core/hle/service/audio/audio_out.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -39,13 +42,13 @@ IAudioOut::IAudioOut(Core::System& system_, Manager& manager, size_t session_id, // clang-format on RegisterHandlers(functions); - process->Open(); + process->Open(system.Kernel()); } IAudioOut::~IAudioOut() { impl->Free(); service_context.CloseEvent(event); - process->Close(); + process->Close(system.Kernel()); } Result IAudioOut::GetAudioOutState(Out out_state) { diff --git a/src/core/hle/service/audio/audio_renderer.cpp b/src/core/hle/service/audio/audio_renderer.cpp index 21cc742b69..49c6083109 100644 --- a/src/core/hle/service/audio/audio_renderer.cpp +++ b/src/core/hle/service/audio/audio_renderer.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 2024 yuzu Emulator Project @@ -39,7 +39,7 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, // clang-format on RegisterHandlers(functions); - process_handle->Open(); + process_handle->Open(system_.Kernel()); impl->Initialize(params, transfer_memory, transfer_memory_size, process_handle, applet_resource_user_id, session_id); } @@ -47,7 +47,7 @@ IAudioRenderer::IAudioRenderer(Core::System& system_, Manager& manager_, IAudioRenderer::~IAudioRenderer() { impl->Finalize(); service_context.CloseEvent(rendered_event); - process_handle->Close(); + process_handle->Close(system.Kernel()); } Result IAudioRenderer::GetSampleRate(Out out_sample_rate) { diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 491416254c..3ef70aaacc 100644 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp @@ -13,9 +13,9 @@ namespace Service::BCAT { ProgressServiceBackend::ProgressServiceBackend(Core::System& system, std::string_view event_name) - : service_context{system, "ProgressServiceBackend"} { - update_event = service_context.CreateEvent("ProgressServiceBackend:UpdateEvent:" + - std::string(event_name)); + : service_context{system, "ProgressServiceBackend"} +{ + update_event = service_context.CreateEvent("ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); } ProgressServiceBackend::~ProgressServiceBackend() { @@ -30,103 +30,90 @@ DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { return impl; } -void ProgressServiceBackend::SetTotalSize(u64 size) { +void ProgressServiceBackend::SetTotalSize(Kernel::KernelCore& kernel, u64 size) { impl.total_bytes = size; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::StartConnecting() { +void ProgressServiceBackend::StartConnecting(Kernel::KernelCore& kernel) { impl.status = DeliveryCacheProgressStatus::Connecting; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::StartProcessingDataList() { +void ProgressServiceBackend::StartProcessingDataList(Kernel::KernelCore& kernel) { impl.status = DeliveryCacheProgressStatus::ProcessingDataList; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::StartDownloadingFile(std::string_view dir_name, - std::string_view file_name, u64 file_size) { +void ProgressServiceBackend::StartDownloadingFile(Kernel::KernelCore& kernel, std::string_view dir_name, std::string_view file_name, u64 file_size) { impl.status = DeliveryCacheProgressStatus::Downloading; impl.current_downloaded_bytes = 0; impl.current_total_bytes = file_size; - std::memcpy(impl.current_directory.data(), dir_name.data(), - std::min(dir_name.size(), 0x31ull)); - std::memcpy(impl.current_file.data(), file_name.data(), - std::min(file_name.size(), 0x31ull)); - SignalUpdate(); + std::memcpy(impl.current_directory.data(), dir_name.data(), std::min(dir_name.size(), 0x31ull)); + std::memcpy(impl.current_file.data(), file_name.data(), std::min(file_name.size(), 0x31ull)); + SignalUpdate(kernel); } -void ProgressServiceBackend::UpdateFileProgress(u64 downloaded) { +void ProgressServiceBackend::UpdateFileProgress(Kernel::KernelCore& kernel, u64 downloaded) { impl.current_downloaded_bytes = downloaded; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::FinishDownloadingFile() { +void ProgressServiceBackend::FinishDownloadingFile(Kernel::KernelCore& kernel) { impl.total_downloaded_bytes += impl.current_total_bytes; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::CommitDirectory(std::string_view dir_name) { +void ProgressServiceBackend::CommitDirectory(Kernel::KernelCore& kernel, std::string_view dir_name) { impl.status = DeliveryCacheProgressStatus::Committing; impl.current_file.fill(0); impl.current_downloaded_bytes = 0; impl.current_total_bytes = 0; - std::memcpy(impl.current_directory.data(), dir_name.data(), - std::min(dir_name.size(), 0x31ull)); - SignalUpdate(); + std::memcpy(impl.current_directory.data(), dir_name.data(), std::min(dir_name.size(), 0x31ull)); + SignalUpdate(kernel); } -void ProgressServiceBackend::FinishDownload(Result result) { +void ProgressServiceBackend::FinishDownload(Kernel::KernelCore& kernel, Result result) { impl.total_downloaded_bytes = impl.total_bytes; impl.status = DeliveryCacheProgressStatus::Done; impl.result = result; - SignalUpdate(); + SignalUpdate(kernel); } -void ProgressServiceBackend::SignalUpdate() { - update_event->Signal(); +void ProgressServiceBackend::SignalUpdate(Kernel::KernelCore& kernel) { + update_event->Signal(kernel); } BcatBackend::BcatBackend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} - BcatBackend::~BcatBackend() = default; NullBcatBackend::NullBcatBackend(DirectoryGetter getter) : BcatBackend(std::move(getter)) {} - NullBcatBackend::~NullBcatBackend() = default; -bool NullBcatBackend::Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, - title.build_id); - - progress.FinishDownload(ResultSuccess); +bool NullBcatBackend::Synchronize(Kernel::KernelCore& kernel, TitleIDVersion title, ProgressServiceBackend& progress) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, title.build_id); + progress.FinishDownload(kernel, ResultSuccess); return true; } -bool NullBcatBackend::SynchronizeDirectory(TitleIDVersion title, std::string name, - ProgressServiceBackend& progress) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}, name={}", title.title_id, - title.build_id, name); - - progress.FinishDownload(ResultSuccess); +bool NullBcatBackend::SynchronizeDirectory(Kernel::KernelCore& kernel, TitleIDVersion title, std::string name, ProgressServiceBackend& progress) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}, name={}", title.title_id, title.build_id, name); + progress.FinishDownload(kernel, ResultSuccess); return true; } -bool NullBcatBackend::Clear(u64 title_id) { +bool NullBcatBackend::Clear(Kernel::KernelCore& kernel, u64 title_id) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", title_id); return true; } -void NullBcatBackend::SetPassphrase(u64 title_id, const Passphrase& passphrase) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, - Common::HexToString(passphrase)); +void NullBcatBackend::SetPassphrase(Kernel::KernelCore& kernel, u64 title_id, const Passphrase& passphrase) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, passphrase={}", title_id, Common::HexToString(passphrase)); } -std::optional> NullBcatBackend::GetLaunchParameter(TitleIDVersion title) { - LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, - title.build_id); +std::optional> NullBcatBackend::GetLaunchParameter(Kernel::KernelCore& kernel, TitleIDVersion title) { + LOG_DEBUG(Service_BCAT, "called, title_id={:016X}, build_id={:016X}", title.title_id, title.build_id); return std::nullopt; } diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index 3680f6c9c8..8419399a62 100644 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -34,26 +37,26 @@ public: ~ProgressServiceBackend(); // Sets the number of bytes total in the entire download. - void SetTotalSize(u64 size); + void SetTotalSize(Kernel::KernelCore& kernel, u64 size); // Notifies the application that the backend has started connecting to the server. - void StartConnecting(); + void StartConnecting(Kernel::KernelCore& kernel); // Notifies the application that the backend has begun accumulating and processing metadata. - void StartProcessingDataList(); + void StartProcessingDataList(Kernel::KernelCore& kernel); // Notifies the application that a file is starting to be downloaded. - void StartDownloadingFile(std::string_view dir_name, std::string_view file_name, u64 file_size); + void StartDownloadingFile(Kernel::KernelCore& kernel, std::string_view dir_name, std::string_view file_name, u64 file_size); // Updates the progress of the current file to the size passed. - void UpdateFileProgress(u64 downloaded); + void UpdateFileProgress(Kernel::KernelCore& kernel, u64 downloaded); // Notifies the application that the current file has completed download. - void FinishDownloadingFile(); + void FinishDownloadingFile(Kernel::KernelCore& kernel); // Notifies the application that all files in this directory have completed and are being // finalized. - void CommitDirectory(std::string_view dir_name); + void CommitDirectory(Kernel::KernelCore& kernel, std::string_view dir_name); // Notifies the application that the operation completed with result code result. - void FinishDownload(Result result); + void FinishDownload(Kernel::KernelCore& kernel, Result result); private: explicit ProgressServiceBackend(Core::System& system, std::string_view event_name); @@ -61,7 +64,7 @@ private: Kernel::KReadableEvent& GetEvent(); DeliveryCacheProgressImpl& GetImpl(); - void SignalUpdate(); + void SignalUpdate(Kernel::KernelCore& kernel); KernelHelpers::ServiceContext service_context; @@ -74,25 +77,19 @@ class BcatBackend { public: explicit BcatBackend(DirectoryGetter getter); virtual ~BcatBackend(); - // Called when the backend is needed to synchronize the data for the game with title ID and // version in title. A ProgressServiceBackend object is provided to alert the application of // status. - virtual bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) = 0; + virtual bool Synchronize(Kernel::KernelCore& kernel, TitleIDVersion title, ProgressServiceBackend& progress) = 0; // Very similar to Synchronize, but only for the directory provided. Backends should not alter // the data for any other directories. - virtual bool SynchronizeDirectory(TitleIDVersion title, std::string name, - ProgressServiceBackend& progress) = 0; - + virtual bool SynchronizeDirectory(Kernel::KernelCore& kernel, TitleIDVersion title, std::string name, ProgressServiceBackend& progress) = 0; // Removes all cached data associated with title id provided. - virtual bool Clear(u64 title_id) = 0; - + virtual bool Clear(Kernel::KernelCore& kernel, u64 title_id) = 0; // Sets the BCAT Passphrase to be used with the associated title ID. - virtual void SetPassphrase(u64 title_id, const Passphrase& passphrase) = 0; - + virtual void SetPassphrase(Kernel::KernelCore& kernel, u64 title_id, const Passphrase& passphrase) = 0; // Gets the launch parameter used by AM associated with the title ID and version provided. - virtual std::optional> GetLaunchParameter(TitleIDVersion title) = 0; - + virtual std::optional> GetLaunchParameter(Kernel::KernelCore& kernel, TitleIDVersion title) = 0; protected: DirectoryGetter dir_getter; }; @@ -103,18 +100,13 @@ public: explicit NullBcatBackend(DirectoryGetter getter); ~NullBcatBackend() override; - bool Synchronize(TitleIDVersion title, ProgressServiceBackend& progress) override; - bool SynchronizeDirectory(TitleIDVersion title, std::string name, - ProgressServiceBackend& progress) override; - - bool Clear(u64 title_id) override; - - void SetPassphrase(u64 title_id, const Passphrase& passphrase) override; - - std::optional> GetLaunchParameter(TitleIDVersion title) override; + bool Synchronize(Kernel::KernelCore& kernel, TitleIDVersion title, ProgressServiceBackend& progress) override; + bool SynchronizeDirectory(Kernel::KernelCore& kernel, TitleIDVersion title, std::string name, ProgressServiceBackend& progress) override; + bool Clear(Kernel::KernelCore& kernel, u64 title_id) override; + void SetPassphrase(Kernel::KernelCore& kernel, u64 title_id, const Passphrase& passphrase) override; + std::optional> GetLaunchParameter(Kernel::KernelCore& kernel, TitleIDVersion title) override; }; -std::unique_ptr CreateBackendFromSettings(Core::System& system, - DirectoryGetter getter); +std::unique_ptr CreateBackendFromSettings(Core::System& system, DirectoryGetter getter); } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_service.cpp b/src/core/hle/service/bcat/bcat_service.cpp index 849bf8d0d9..210fd77094 100644 --- a/src/core/hle/service/bcat/bcat_service.cpp +++ b/src/core/hle/service/bcat/bcat_service.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 2018 yuzu Emulator Project @@ -70,7 +70,7 @@ Result IBcatService::RequestSyncDeliveryCache( LOG_DEBUG(Service_BCAT, "called"); auto& progress_backend{GetProgressBackend(SyncType::Normal)}; - backend.Synchronize({system.GetApplicationProcessProgramID(), + backend.Synchronize(system.Kernel(), {system.GetApplicationProcessProgramID(), GetCurrentBuildID(system.GetApplicationProcessBuildID())}, GetProgressBackend(SyncType::Normal)); @@ -86,7 +86,7 @@ Result IBcatService::RequestSyncDeliveryCacheWithDirectoryName( LOG_DEBUG(Service_BCAT, "called, name={}", name); auto& progress_backend{GetProgressBackend(SyncType::Directory)}; - backend.SynchronizeDirectory({system.GetApplicationProcessProgramID(), + backend.SynchronizeDirectory(system.Kernel(), {system.GetApplicationProcessProgramID(), GetCurrentBuildID(system.GetApplicationProcessBuildID())}, name, progress_backend); @@ -107,7 +107,7 @@ Result IBcatService::SetPassphrase(u64 application_id, std::memcpy(passphrase.data(), passphrase_buffer.data(), (std::min)(passphrase.size(), passphrase_buffer.size())); - backend.SetPassphrase(application_id, passphrase); + backend.SetPassphrase(system.Kernel(), application_id, passphrase); R_SUCCEED(); } @@ -120,7 +120,7 @@ Result IBcatService::ClearDeliveryCacheStorage(u64 application_id) { LOG_DEBUG(Service_BCAT, "called, title_id={:016X}", application_id); R_UNLESS(application_id != 0, ResultInvalidArgument); - R_UNLESS(backend.Clear(application_id), FileSys::ResultPermissionDenied); + R_UNLESS(backend.Clear(system.Kernel(), application_id), FileSys::ResultPermissionDenied); R_SUCCEED(); } diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 79578956b1..6885a7be7d 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -183,7 +183,7 @@ private: auto& readable_event = completion_event->GetReadableEvent(); IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(readable_event.Signal()); + rb.Push(readable_event.Signal(system.Kernel())); rb.PushCopyObjects(readable_event); } diff --git a/src/core/hle/service/glue/time/alarm_worker.cpp b/src/core/hle/service/glue/time/alarm_worker.cpp index 3ff071f4a0..770dc62f5c 100644 --- a/src/core/hle/service/glue/time/alarm_worker.cpp +++ b/src/core/hle/service/glue/time/alarm_worker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -28,7 +31,7 @@ void AlarmWorker::Initialize(std::shared_ptr "Glue:AlarmWorker::AlarmTimer", [this](s64 time, std::chrono::nanoseconds ns_late) -> std::optional { - m_timer_event->Signal(); + m_timer_event->Signal(m_system.Kernel()); return std::nullopt; }); @@ -57,7 +60,7 @@ void AlarmWorker::OnPowerStateChanged() { s64 closest_time{}; if (!GetClosestAlarmInfo(closest_alarm_info, closest_time)) { m_system.CoreTiming().UnscheduleEvent(m_timer_timing_event); - m_timer_event->Clear(); + m_timer_event->Clear(m_system.Kernel()); return; } @@ -67,7 +70,7 @@ void AlarmWorker::OnPowerStateChanged() { auto next_time{closest_alarm_info.alert_time - closest_time}; m_system.CoreTiming().UnscheduleEvent(m_timer_timing_event); - m_timer_event->Clear(); + m_timer_event->Clear(m_system.Kernel()); m_system.CoreTiming().ScheduleEvent(std::chrono::nanoseconds(next_time), m_timer_timing_event); diff --git a/src/core/hle/service/glue/time/time_zone.cpp b/src/core/hle/service/glue/time/time_zone.cpp index c358cfbf28..3543e1938b 100644 --- a/src/core/hle/service/glue/time/time_zone.cpp +++ b/src/core/hle/service/glue/time/time_zone.cpp @@ -89,7 +89,7 @@ Result TimeZoneService::SetDeviceLocationName( std::scoped_lock m{m_list_mutex}; for (auto& operation_event : m_list_nodes) { - operation_event.m_event->Signal(); + operation_event.m_event->Signal(m_system.Kernel()); } R_SUCCEED(); } diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index 1dab3e9dcb..5025efc717 100644 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -30,7 +33,7 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady "Time::SteadyClockEvent", [this](s64 time, std::chrono::nanoseconds ns_late) -> std::optional { - m_timer_steady_clock->Signal(); + m_timer_steady_clock->Signal(m_system.Kernel()); return std::nullopt; }); @@ -38,19 +41,19 @@ TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady "Time::SteadyClockEvent", [this](s64 time, std::chrono::nanoseconds ns_late) -> std::optional { - m_timer_file_system->Signal(); + m_timer_file_system->Signal(m_system.Kernel()); return std::nullopt; }); } TimeWorker::~TimeWorker() { - m_local_clock_event->Signal(); - m_network_clock_event->Signal(); - m_ephemeral_clock_event->Signal(); + m_local_clock_event->Signal(m_system.Kernel()); + m_network_clock_event->Signal(m_system.Kernel()); + m_ephemeral_clock_event->Signal(m_system.Kernel()); std::this_thread::sleep_for(std::chrono::milliseconds(16)); m_thread.request_stop(); - m_event->Signal(); + m_event->Signal(m_system.Kernel()); m_thread.join(); m_ctx.CloseEvent(m_event); @@ -167,19 +170,19 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { return; case EventType::PowerStateChange: - m_alarm_worker.GetEvent().Clear(); + m_alarm_worker.GetEvent().Clear(m_system.Kernel()); if (m_pm_state_change_handler.m_priority <= 1) { m_alarm_worker.OnPowerStateChanged(); } break; case EventType::SignalAlarms: - m_alarm_worker.GetTimerEvent().Clear(); + m_alarm_worker.GetTimerEvent().Clear(m_system.Kernel()); m_time_m->CheckAndSignalAlarms(); break; case EventType::UpdateLocalSystemClock: { - m_local_clock_event->Clear(); + m_local_clock_event->Clear(m_system.Kernel()); Service::PSC::Time::SystemClockContext context{}; R_ASSERT(m_local_clock->GetSystemClockContext(&context)); @@ -190,7 +193,7 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { } case EventType::UpdateNetworkSystemClock: { - m_network_clock_event->Clear(); + m_network_clock_event->Clear(m_system.Kernel()); Service::PSC::Time::SystemClockContext context{}; R_ASSERT(m_network_clock->GetSystemClockContext(&context)); @@ -218,7 +221,7 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { } case EventType::UpdateEphemeralSystemClock: { - m_ephemeral_clock_event->Clear(); + m_ephemeral_clock_event->Clear(m_system.Kernel()); Service::PSC::Time::SystemClockContext context{}; auto res = m_ephemeral_clock->GetSystemClockContext(&context); @@ -247,20 +250,20 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) { } case EventType::UpdateSteadyClock: - m_timer_steady_clock->Clear(); + m_timer_steady_clock->Clear(m_system.Kernel()); m_steady_clock_resource.UpdateTime(); m_time_m->SetStandardSteadyClockBaseTime(m_steady_clock_resource.GetTime()); break; case EventType::UpdateFileTimestamp: - m_timer_file_system->Clear(); + m_timer_file_system->Clear(m_system.Kernel()); m_file_timestamp_worker.SetFilesystemPosixTime(); break; case EventType::AutoCorrect: { - m_standard_user_auto_correct_clock_event->Clear(); + m_standard_user_auto_correct_clock_event->Clear(m_system.Kernel()); bool automatic_correction{}; R_ASSERT(m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled( diff --git a/src/core/hle/service/hle_ipc.cpp b/src/core/hle/service/hle_ipc.cpp index 64ef19d8ef..ce7591656a 100644 --- a/src/core/hle/service/hle_ipc.cpp +++ b/src/core/hle/service/hle_ipc.cpp @@ -285,7 +285,7 @@ Result HLERequestContext::WriteToOutgoingCommandBuffer() { R_TRY(handle_table.Add(kernel, &handle, object)); // Close our reference to the object, as it is being moved to the caller. - object->Close(); + object->Close(kernel); } cmd_buf[current_offset++] = handle; } @@ -503,11 +503,10 @@ bool HLERequestContext::CanWriteBuffer(std::size_t buffer_index) const { } void HLERequestContext::AddMoveInterface(SessionRequestHandlerPtr s) { - ASSERT(Kernel::GetCurrentProcess(kernel).GetResourceLimit()->Reserve( - Kernel::LimitableResource::SessionCountMax, 1)); + ASSERT(Kernel::GetCurrentProcess(kernel).GetResourceLimit()->Reserve(kernel, Kernel::LimitableResource::SessionCountMax, 1)); auto* session = Kernel::KSession::Create(kernel); - session->Initialize(nullptr, 0); + session->Initialize(kernel, nullptr, 0); Kernel::KSession::Register(kernel, session); auto& server = manager.lock()->GetServerManager(); diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index 4cf89d38fe..eeb5bf3547 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h @@ -374,10 +374,9 @@ public: template Kernel::KScopedAutoObject GetObjectFromHandle(u32 handle) { auto obj = client_handle_table->GetObjectForIpc(kernel, handle, thread); - if (obj.IsNotNull()) { - return obj->DynamicCast(); - } - return nullptr; + if (obj.IsNotNull()) + return {kernel, obj->DynamicCast()}; + return {kernel, nullptr}; } [[nodiscard]] std::shared_ptr GetManager() const { diff --git a/src/core/hle/service/ipc_helpers.h b/src/core/hle/service/ipc_helpers.h index 8aee17db8d..c37b0c2e05 100644 --- a/src/core/hle/service/ipc_helpers.h +++ b/src/core/hle/service/ipc_helpers.h @@ -151,11 +151,10 @@ public: if (manager->IsDomain()) { context->AddDomainObject(std::move(iface)); } else { - ASSERT(Kernel::GetCurrentProcess(kernel).GetResourceLimit()->Reserve( - Kernel::LimitableResource::SessionCountMax, 1)); + ASSERT(Kernel::GetCurrentProcess(kernel).GetResourceLimit()->Reserve(kernel, Kernel::LimitableResource::SessionCountMax, 1)); auto* session = Kernel::KSession::Create(kernel); - session->Initialize(nullptr, 0); + session->Initialize(kernel, nullptr, 0); Kernel::KSession::Register(kernel, session); auto next_manager = std::make_shared( diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp index f080f7ffa2..f7a5cb7049 100644 --- a/src/core/hle/service/kernel_helpers.cpp +++ b/src/core/hle/service/kernel_helpers.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -14,15 +17,15 @@ namespace Service::KernelHelpers { ServiceContext::ServiceContext(Core::System& system_, std::string name_) - : kernel(system_.Kernel()) { + : kernel(system_.Kernel()) +{ if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) { return; } // Create the process. process = Kernel::KProcess::Create(kernel); - ASSERT(R_SUCCEEDED(process->Initialize(Kernel::Svc::CreateProcessParameter{}, - kernel.GetSystemResourceLimit(), false))); + ASSERT(R_SUCCEEDED(process->Initialize(kernel, Kernel::Svc::CreateProcessParameter{}, kernel.GetSystemResourceLimit(), false))); // Register the process. Kernel::KProcess::Register(kernel, process); @@ -31,14 +34,14 @@ ServiceContext::ServiceContext(Core::System& system_, std::string name_) ServiceContext::~ServiceContext() { if (process_created) { - process->Close(); + process->Close(kernel); process = nullptr; } } Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { // Reserve a new event from the process resource limit - Kernel::KScopedResourceReservation event_reservation(process, + Kernel::KScopedResourceReservation event_reservation(kernel, process, Kernel::LimitableResource::EventCountMax); if (!event_reservation.Succeeded()) { LOG_CRITICAL(Service, "Resource limit reached!"); @@ -53,7 +56,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { } // Initialize the event. - event->Initialize(process); + event->Initialize(kernel, process); // Commit the thread reservation. event_reservation.Commit(); @@ -65,11 +68,10 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { } void ServiceContext::CloseEvent(Kernel::KEvent* event) { - if (!event) { - return; + if (event) { + event->GetReadableEvent().Close(kernel); + event->Close(kernel); } - event->GetReadableEvent().Close(); - event->Close(); } } // namespace Service::KernelHelpers diff --git a/src/core/hle/service/kernel_helpers.h b/src/core/hle/service/kernel_helpers.h index eca9aefb52..4e21c8857f 100644 --- a/src/core/hle/service/kernel_helpers.h +++ b/src/core/hle/service/kernel_helpers.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -26,7 +29,6 @@ public: void CloseEvent(Kernel::KEvent* event); -private: Kernel::KernelCore& kernel; Kernel::KProcess* process{}; bool process_created{false}; diff --git a/src/core/hle/service/ldn/user_local_communication_service.cpp b/src/core/hle/service/ldn/user_local_communication_service.cpp index 1e984a9782..572aea6314 100644 --- a/src/core/hle/service/ldn/user_local_communication_service.cpp +++ b/src/core/hle/service/ldn/user_local_communication_service.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 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -322,7 +322,7 @@ void IUserLocalCommunicationService::OnLDNPacketReceived(const Network::LDNPacke } void IUserLocalCommunicationService::OnEventFired() { - state_change_event->Signal(); + state_change_event->Signal(system.Kernel()); } } // namespace Service::LDN diff --git a/src/core/hle/service/nfc/common/device.cpp b/src/core/hle/service/nfc/common/device.cpp index faa2b1f584..2876c6f739 100644 --- a/src/core/hle/service/nfc/common/device.cpp +++ b/src/core/hle/service/nfc/common/device.cpp @@ -71,13 +71,13 @@ NfcDevice::~NfcDevice() { void NfcDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { if (type == Core::HID::ControllerTriggerType::Connected) { Initialize(); - availability_change_event->Signal(); + availability_change_event->Signal(system.Kernel()); return; } if (type == Core::HID::ControllerTriggerType::Disconnected) { Finalize(); - availability_change_event->Signal(); + availability_change_event->Signal(system.Kernel()); return; } @@ -138,8 +138,8 @@ bool NfcDevice::LoadNfcTag(u8 protocol, u8 tag_type, u8 uuid_length, UniqueSeria }; device_state = DeviceState::TagFound; - deactivate_event->GetReadableEvent().Clear(); - activate_event->Signal(); + deactivate_event->GetReadableEvent().Clear(system.Kernel()); + activate_event->Signal(system.Kernel()); return true; } @@ -192,8 +192,8 @@ void NfcDevice::CloseNfcTag() { device_state = DeviceState::TagRemoved; encrypted_tag_data = {}; tag_data = {}; - activate_event->GetReadableEvent().Clear(); - deactivate_event->Signal(); + activate_event->GetReadableEvent().Clear(system.Kernel()); + deactivate_event->Signal(system.Kernel()); } Kernel::KReadableEvent& NfcDevice::GetActivateEvent() const { diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 7bd06e2e0f..87e806d86b 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -275,7 +275,7 @@ private: } state.store(State::Processing); - evt_processing->Signal(); + evt_processing->Signal(system.Kernel()); worker = std::thread([this]() { using namespace std::chrono_literals; @@ -321,7 +321,7 @@ private: void Finish(Result rc) { worker_result.store(rc); state.store(State::Finished); - evt_scan_complete->Signal(); + evt_scan_complete->Signal(system.Kernel()); } KernelHelpers::ServiceContext svc_ctx; @@ -486,7 +486,7 @@ private: void UpdateState(RequestState new_state) { LOG_DEBUG(Service_NIFM, "(STUBBED) called"); state = new_state; - event1->Signal(); + event1->Signal(system.Kernel()); } KernelHelpers::ServiceContext service_context; diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 4f465c5da7..5f85302713 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.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 2018 yuzu Emulator Project @@ -429,7 +429,7 @@ private: void StartTask(HLERequestContext& ctx) { // No need to connect to the internet, just finish the task straight away. LOG_DEBUG(Service_NIM, "called"); - finished_event->Signal(); + finished_event->Signal(system.Kernel()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -451,7 +451,7 @@ private: void Cancel(HLERequestContext& ctx) { LOG_DEBUG(Service_NIM, "called"); - finished_event->Clear(); + finished_event->Clear(system.Kernel()); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } diff --git a/src/core/hle/service/ns/read_only_application_control_data_interface.cpp b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp index 03f0a17865..f12d9b03d2 100644 --- a/src/core/hle/service/ns/read_only_application_control_data_interface.cpp +++ b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp @@ -87,7 +87,7 @@ public: RegisterHandlers(functions); completion_event = service_context.CreateEvent("IAsyncValue:Completion"); - completion_event->GetReadableEvent().Signal(); + completion_event->GetReadableEvent().Signal(system.Kernel()); } ~IAsyncValueForListApplicationTitle() override { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index b2580f2bb9..6ef32b890f 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -203,7 +203,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(IocCtrlEventWaitParams& params, bool is_a auto& event_ = events[slot]; if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) == EventState::Waiting) { - event_.kevent->Signal(); + event_.kevent->Signal(system.Kernel()); } event_.status.store(EventState::Signalled, std::memory_order_release); }); @@ -292,7 +292,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(IocCtrlEventClearParams& params) { } event.fails++; event.status.store(EventState::Cancelled, std::memory_order_release); - event.kevent->Clear(); + event.kevent->Clear(system.Kernel()); return NvResult::Success; } diff --git a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp index 5bd53fb99e..c3eb2796e3 100644 --- a/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp +++ b/src/core/hle/service/nvnflinger/buffer_queue_producer.cpp @@ -111,7 +111,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) { core->override_max_buffer_count = buffer_count; core->SignalDequeueCondition(); - buffer_wait_event->Signal(); + buffer_wait_event->Signal(service_context.kernel); listener = core->consumer_listener; } @@ -576,7 +576,7 @@ void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) { slots[slot].fence = fence; core->SignalDequeueCondition(); - buffer_wait_event->Signal(); + buffer_wait_event->Signal(service_context.kernel); } Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) { @@ -714,7 +714,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) { core->connected_producer_listener = nullptr; core->connected_api = NativeWindowApi::NoConnectedApi; core->SignalDequeueCondition(); - buffer_wait_event->Signal(); + buffer_wait_event->Signal(service_context.kernel); listener = core->consumer_listener; } else { LOG_ERROR(Service_Nvnflinger, @@ -764,7 +764,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot, } core->SignalDequeueCondition(); - buffer_wait_event->Signal(); + buffer_wait_event->Signal(service_context.kernel); return Status::NoError; } diff --git a/src/core/hle/service/olsc/native_handle_holder.cpp b/src/core/hle/service/olsc/native_handle_holder.cpp index d381714bc3..1e50195539 100644 --- a/src/core/hle/service/olsc/native_handle_holder.cpp +++ b/src/core/hle/service/olsc/native_handle_holder.cpp @@ -32,7 +32,7 @@ INativeHandleHolder::~INativeHandleHolder() { Result INativeHandleHolder::GetNativeHandle(OutCopyHandle out_event) { LOG_WARNING(Service_OLSC, "(STUBBED) called"); if (event) { - event->Signal(); + event->Signal(system.Kernel()); *out_event = std::addressof(event->GetReadableEvent()); } else { *out_event = nullptr; diff --git a/src/core/hle/service/os/event.cpp b/src/core/hle/service/os/event.cpp index ec52c17fd8..8808c5b4f0 100644 --- a/src/core/hle/service/os/event.cpp +++ b/src/core/hle/service/os/event.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,25 +10,27 @@ namespace Service { -Event::Event(KernelHelpers::ServiceContext& ctx) { +Event::Event(KernelHelpers::ServiceContext& ctx_) + : ctx{ctx_} +{ m_event = ctx.CreateEvent("Event"); } Event::~Event() { - m_event->GetReadableEvent().Close(); - m_event->Close(); + m_event->GetReadableEvent().Close(ctx.kernel); + m_event->Close(ctx.kernel); } -void Event::Signal() { - m_event->Signal(); +void Event::Signal(Kernel::KernelCore& kernel) noexcept { + m_event->Signal(kernel); } -void Event::Clear() { - m_event->Clear(); +void Event::Clear(Kernel::KernelCore& kernel) noexcept { + m_event->Clear(kernel); } -Kernel::KReadableEvent* Event::GetHandle() { - return &m_event->GetReadableEvent(); +Kernel::KReadableEvent* Event::GetHandle() noexcept { + return std::addressof(m_event->GetReadableEvent()); } } // namespace Service diff --git a/src/core/hle/service/os/event.h b/src/core/hle/service/os/event.h index cdbc4635a6..bc23598b58 100644 --- a/src/core/hle/service/os/event.h +++ b/src/core/hle/service/os/event.h @@ -1,9 +1,13 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once namespace Kernel { +class KernelCore; class KEvent; class KReadableEvent; } // namespace Kernel @@ -19,12 +23,12 @@ public: explicit Event(KernelHelpers::ServiceContext& ctx); ~Event(); - void Signal(); - void Clear(); - - Kernel::KReadableEvent* GetHandle(); + void Signal(Kernel::KernelCore& kernel) noexcept; + void Clear(Kernel::KernelCore& kernel) noexcept; + Kernel::KReadableEvent* GetHandle() noexcept; private: + KernelHelpers::ServiceContext& ctx; Kernel::KEvent* m_event; }; diff --git a/src/core/hle/service/os/process.cpp b/src/core/hle/service/os/process.cpp index 2d5d7def64..5e46de245d 100644 --- a/src/core/hle/service/os/process.cpp +++ b/src/core/hle/service/os/process.cpp @@ -23,7 +23,7 @@ bool Process::Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_lo // On exit, ensure we free the additional reference to the process. SCOPE_EXIT { - process->Close(); + process->Close(m_system.Kernel()); }; // Insert process modules into memory. @@ -47,7 +47,7 @@ bool Process::Initialize(Loader::AppLoader& loader, Loader::ResultStatus& out_lo // Take ownership of the process object. m_process = process; - m_process->Open(); + m_process->Open(m_system.Kernel()); // We succeeded. return true; @@ -59,8 +59,7 @@ void Process::Finalize() { // Close the process. if (m_process) { - m_process->Close(); - + m_process->Close(m_system.Kernel()); // TODO: remove this, kernel already tracks this m_system.Kernel().RemoveProcess(m_process); } @@ -80,7 +79,7 @@ bool Process::Run() { // Start. if (m_process) { - m_process->Run(m_main_thread_priority, m_main_thread_stack_size); + m_process->Run(m_system.Kernel(), m_main_thread_priority, m_main_thread_stack_size); } // Mark as started. @@ -92,13 +91,13 @@ bool Process::Run() { void Process::Terminate() { if (m_process) { - m_process->Terminate(); + m_process->Terminate(m_system.Kernel()); } } void Process::ResetSignal() { if (m_process) { - m_process->Reset(); + m_process->Reset(m_system.Kernel()); } } @@ -139,8 +138,7 @@ u64 Process::GetProgramId() const { void Process::Suspend(bool suspended) { if (m_process) { - m_process->SetActivity(suspended ? Kernel::Svc::ProcessActivity::Paused - : Kernel::Svc::ProcessActivity::Runnable); + m_process->SetActivity(m_system.Kernel(), suspended ? Kernel::Svc::ProcessActivity::Paused : Kernel::Svc::ProcessActivity::Runnable); } } diff --git a/src/core/hle/service/psc/time/alarms.cpp b/src/core/hle/service/psc/time/alarms.cpp index 5e52c19f82..c2de95f653 100644 --- a/src/core/hle/service/psc/time/alarms.cpp +++ b/src/core/hle/service/psc/time/alarms.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,8 +10,10 @@ namespace Service::PSC::Time { Alarm::Alarm(Core::System& system, KernelHelpers::ServiceContext& ctx, AlarmType type) - : m_ctx{ctx}, m_event{ctx.CreateEvent("Psc:Alarm:Event")} { - m_event->Clear(); + : m_ctx{ctx} + , m_event{ctx.CreateEvent("Psc:Alarm:Event")} +{ + m_event->Clear(system.Kernel()); switch (type) { case WakeupAlarm: @@ -37,7 +42,7 @@ Alarms::~Alarms() { m_ctx.CloseEvent(m_event); } -Result Alarms::Enable(Alarm& alarm, s64 time) { +Result Alarms::Enable(Kernel::KernelCore& kernel, Alarm& alarm, s64 time) { R_UNLESS(m_steady_clock.IsInitialized(), ResultClockUninitialized); std::scoped_lock l{m_mutex}; @@ -49,21 +54,21 @@ Result Alarms::Enable(Alarm& alarm, s64 time) { time_ns = Common::AlignUp(time_ns, one_second_ns); alarm.SetAlertTime(time_ns); - Insert(alarm); - R_RETURN(UpdateClosestAndSignal()); + Insert(kernel, alarm); + R_RETURN(UpdateClosestAndSignal(kernel)); } -void Alarms::Disable(Alarm& alarm) { +void Alarms::Disable(Kernel::KernelCore& kernel, Alarm& alarm) { std::scoped_lock l{m_mutex}; if (!alarm.IsLinked()) { return; } - Erase(alarm); - UpdateClosestAndSignal(); + Erase(kernel, alarm); + UpdateClosestAndSignal(kernel); } -void Alarms::CheckAndSignal() { +void Alarms::CheckAndSignal(Kernel::KernelCore& kernel) { std::scoped_lock l{m_mutex}; if (m_alarms.empty()) { return; @@ -72,9 +77,9 @@ void Alarms::CheckAndSignal() { bool alarm_signalled{false}; for (auto& alarm : m_alarms) { if (m_steady_clock.GetRawTime() >= alarm.GetAlertTime()) { - alarm.Signal(); + alarm.Signal(kernel); alarm.Lock(); - Erase(alarm); + Erase(kernel, alarm); m_power_state_request_manager.UpdatePendingPowerStateRequestPriority( alarm.GetPriority()); @@ -87,7 +92,7 @@ void Alarms::CheckAndSignal() { } m_power_state_request_manager.SignalPowerStateRequestAvailability(); - UpdateClosestAndSignal(); + UpdateClosestAndSignal(kernel); } bool Alarms::GetClosestAlarm(Alarm** out_alarm) { @@ -97,7 +102,7 @@ bool Alarms::GetClosestAlarm(Alarm** out_alarm) { return alarm != nullptr; } -void Alarms::Insert(Alarm& alarm) { +void Alarms::Insert(Kernel::KernelCore& kernel, Alarm& alarm) { // Alarms are sorted by alert time, then priority auto it{m_alarms.begin()}; while (it != m_alarms.end()) { @@ -113,15 +118,15 @@ void Alarms::Insert(Alarm& alarm) { m_alarms.push_back(alarm); } -void Alarms::Erase(Alarm& alarm) { +void Alarms::Erase(Kernel::KernelCore& kernel, Alarm& alarm) { m_alarms.erase(m_alarms.iterator_to(alarm)); } -Result Alarms::UpdateClosestAndSignal() { +Result Alarms::UpdateClosestAndSignal(Kernel::KernelCore& kernel) { m_closest_alarm = m_alarms.empty() ? nullptr : std::addressof(m_alarms.front()); R_SUCCEED_IF(m_closest_alarm == nullptr); - m_event->Signal(); + m_event->Signal(kernel); R_SUCCEED(); } @@ -183,7 +188,7 @@ void ISteadyClockAlarm::Enable(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; auto time{rp.Pop()}; - auto res = m_alarms.Enable(m_alarm, time); + auto res = m_alarms.Enable(system.Kernel(), m_alarm, time); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res); @@ -192,7 +197,7 @@ void ISteadyClockAlarm::Enable(HLERequestContext& ctx) { void ISteadyClockAlarm::Disable(HLERequestContext& ctx) { LOG_DEBUG(Service_Time, "called."); - m_alarms.Disable(m_alarm); + m_alarms.Disable(system.Kernel(), m_alarm); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); diff --git a/src/core/hle/service/psc/time/alarms.h b/src/core/hle/service/psc/time/alarms.h index 597770028b..79b66c06ea 100644 --- a/src/core/hle/service/psc/time/alarms.h +++ b/src/core/hle/service/psc/time/alarms.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -48,8 +51,8 @@ struct Alarm : public Common::IntrusiveListBaseNode { return m_priority; } - void Signal() { - m_event->Signal(); + void Signal(Kernel::KernelCore& kernel) { + m_event->Signal(kernel); } Result Lock() { @@ -83,15 +86,15 @@ public: return m_steady_clock.GetRawTime(); } - Result Enable(Alarm& alarm, s64 time); - void Disable(Alarm& alarm); - void CheckAndSignal(); + Result Enable(Kernel::KernelCore& kernel, Alarm& alarm, s64 time); + void Disable(Kernel::KernelCore& kernel, Alarm& alarm); + void CheckAndSignal(Kernel::KernelCore& kernel); bool GetClosestAlarm(Alarm** out_alarm); private: - void Insert(Alarm& alarm); - void Erase(Alarm& alarm); - Result UpdateClosestAndSignal(); + void Insert(Kernel::KernelCore& kernel, Alarm& alarm); + void Erase(Kernel::KernelCore& kernel, Alarm& alarm); + Result UpdateClosestAndSignal(Kernel::KernelCore& kernel); Core::System& m_system; KernelHelpers::ServiceContext m_ctx; diff --git a/src/core/hle/service/psc/time/clocks/context_writers.cpp b/src/core/hle/service/psc/time/clocks/context_writers.cpp index a44486b438..4e54a07a37 100644 --- a/src/core/hle/service/psc/time/clocks/context_writers.cpp +++ b/src/core/hle/service/psc/time/clocks/context_writers.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -6,10 +9,10 @@ namespace Service::PSC::Time { -void ContextWriter::SignalAllNodes() { +void ContextWriter::SignalAllNodes(Kernel::KernelCore& kernel) { std::scoped_lock l{m_mutex}; for (auto& operation : m_operation_events) { - operation.m_event->Signal(); + operation.m_event->Signal(kernel); } } @@ -33,7 +36,7 @@ Result LocalSystemClockContextWriter::Write(const SystemClockContext& context) { m_shared_memory.SetLocalSystemContext(context); - SignalAllNodes(); + SignalAllNodes(m_system.Kernel()); R_SUCCEED(); } @@ -57,7 +60,7 @@ Result NetworkSystemClockContextWriter::Write(const SystemClockContext& context) m_shared_memory.SetNetworkSystemContext(context); - SignalAllNodes(); + SignalAllNodes(m_system.Kernel()); R_SUCCEED(); } @@ -75,7 +78,7 @@ Result EphemeralNetworkSystemClockContextWriter::Write(const SystemClockContext& m_in_use = true; } - SignalAllNodes(); + SignalAllNodes(m_system.Kernel()); R_SUCCEED(); } diff --git a/src/core/hle/service/psc/time/clocks/context_writers.h b/src/core/hle/service/psc/time/clocks/context_writers.h index 6643fc9f2a..2adc7d2546 100644 --- a/src/core/hle/service/psc/time/clocks/context_writers.h +++ b/src/core/hle/service/psc/time/clocks/context_writers.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -11,6 +14,9 @@ #include "core/hle/service/psc/time/common.h" #include "core/hle/service/psc/time/shared_memory.h" +namespace Kernel { +class KernelCore; +} namespace Core { class System; } @@ -25,7 +31,7 @@ public: virtual ~ContextWriter() = default; virtual Result Write(const SystemClockContext& context) = 0; - void SignalAllNodes(); + void SignalAllNodes(Kernel::KernelCore& kernel); void Link(OperationEvent& operation_event); private: diff --git a/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp b/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp index 31ed273966..7a51e51f3c 100644 --- a/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/psc/time/clocks/standard_user_system_clock_core.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -57,7 +60,7 @@ Result StandardUserSystemClockCore::GetTimePoint(SteadyClockTimePoint& out_time_ void StandardUserSystemClockCore::SetTimePointAndSignal(SteadyClockTimePoint& time_point) { m_time_point = time_point; - m_event->Signal(); + m_event->Signal(m_system.Kernel()); } } // namespace Service::PSC::Time diff --git a/src/core/hle/service/psc/time/power_state_request_manager.cpp b/src/core/hle/service/psc/time/power_state_request_manager.cpp index b28b513649..7a494f47cb 100644 --- a/src/core/hle/service/psc/time/power_state_request_manager.cpp +++ b/src/core/hle/service/psc/time/power_state_request_manager.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 2023 yuzu Emulator Project @@ -35,7 +35,7 @@ void PowerStateRequestManager::SignalPowerStateRequestAvailability() { } m_has_pending_request = false; m_available_request_priority = m_pending_request_priority; - m_event->Signal(); + m_event->Signal(m_system.Kernel()); } } @@ -45,7 +45,7 @@ bool PowerStateRequestManager::GetAndClearPowerStateRequest(u32& out_priority) { if (m_has_available_request) { out_priority = m_available_request_priority; m_has_available_request = false; - m_event->Clear(); + m_event->Clear(m_system.Kernel()); } return had_request; } diff --git a/src/core/hle/service/psc/time/service_manager.cpp b/src/core/hle/service/psc/time/service_manager.cpp index ed9fb32cdf..4646def3db 100644 --- a/src/core/hle/service/psc/time/service_manager.cpp +++ b/src/core/hle/service/psc/time/service_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -238,7 +241,7 @@ Result ServiceManager::GetClosestAlarmUpdatedEvent( Result ServiceManager::CheckAndSignalAlarms() { LOG_DEBUG(Service_Time, "called."); - m_alarms.CheckAndSignal(); + m_alarms.CheckAndSignal(m_system.Kernel()); R_SUCCEED(); } diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index f144b8e497..5e964d850e 100644 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -41,19 +41,19 @@ public: void SignalChargerTypeChanged() { if (should_signal && should_signal_charger_type) { - state_change_event->Signal(); + state_change_event->Signal(system.Kernel()); } } void SignalPowerSupplyChanged() { if (should_signal && should_signal_power_supply) { - state_change_event->Signal(); + state_change_event->Signal(system.Kernel()); } } void SignalBatteryVoltageStateChanged() { if (should_signal && should_signal_battery_voltage) { - state_change_event->Signal(); + state_change_event->Signal(system.Kernel()); } } diff --git a/src/core/hle/service/ro/ro.cpp b/src/core/hle/service/ro/ro.cpp index cd50e69ce1..9268fa740a 100644 --- a/src/core/hle/service/ro/ro.cpp +++ b/src/core/hle/service/ro/ro.cpp @@ -54,7 +54,7 @@ struct NrrInfo { struct ProcessContext { constexpr ProcessContext() = default; - void Initialize(Kernel::KProcess* process, u64 process_id) { + void Initialize(Kernel::KernelCore& kernel, Kernel::KProcess* process, u64 process_id) { ASSERT(!m_in_use); m_nro_in_use = {}; @@ -67,15 +67,15 @@ struct ProcessContext { m_in_use = true; if (m_process) { - m_process->Open(); + m_process->Open(kernel); } } - void Finalize() { + void Finalize(Kernel::KernelCore& kernel) { ASSERT(m_in_use); if (m_process) { - m_process->Close(); + m_process->Close(kernel); } m_nro_in_use = {}; @@ -304,7 +304,7 @@ class RoContext { public: explicit RoContext() = default; - Result RegisterProcess(size_t* out_context_id, Kernel::KProcess* process, u64 process_id) { + Result RegisterProcess(Kernel::KernelCore& kernel, size_t* out_context_id, Kernel::KProcess* process, u64 process_id) { // Validate process id. R_UNLESS(process->GetProcessId() == process_id, RO::ResultInvalidProcess); @@ -312,7 +312,7 @@ public: R_UNLESS(this->GetContextByProcessId(process_id) == nullptr, RO::ResultInvalidSession); // Allocate a context to manage the process handle. - *out_context_id = this->AllocateContext(process, process_id); + *out_context_id = this->AllocateContext(kernel, process, process_id); R_SUCCEED(); } @@ -324,8 +324,8 @@ public: R_SUCCEED(); } - void UnregisterProcess(size_t context_id) { - this->FreeContext(context_id); + void UnregisterProcess(Kernel::KernelCore& kernel, size_t context_id) { + this->FreeContext(kernel, context_id); } Result RegisterModuleInfo(size_t context_id, u64 nrr_address, u64 nrr_size, NrrKind nrr_kind, @@ -478,13 +478,13 @@ private: return nullptr; } - size_t AllocateContext(Kernel::KProcess* process, u64 process_id) { + size_t AllocateContext(Kernel::KernelCore& kernel, Kernel::KProcess* process, u64 process_id) { // Find a free process context. for (size_t i = 0; i < MaxSessions; i++) { ProcessContext* context = std::addressof(process_contexts[i]); if (context->IsFree()) { - context->Initialize(process, process_id); + context->Initialize(kernel, process, process_id); return i; } } @@ -493,9 +493,9 @@ private: UNREACHABLE(); } - void FreeContext(size_t context_id) { + void FreeContext(Kernel::KernelCore& kernel, size_t context_id) { if (ProcessContext* context = GetContextById(context_id); context != nullptr) { - context->Finalize(); + context->Finalize(kernel); } } }; @@ -522,7 +522,7 @@ public: } ~RoInterface() { - m_ro->UnregisterProcess(m_context_id); + m_ro->UnregisterProcess(system.Kernel(), m_context_id); } Result MapManualLoadModuleMemory(Out out_load_address, ClientProcessId client_pid, @@ -548,20 +548,16 @@ public: R_RETURN(m_ro->UnregisterModuleInfo(m_context_id, nrr_address)); } - Result RegisterProcessHandle(ClientProcessId client_pid, - InCopyHandle process) { + Result RegisterProcessHandle(ClientProcessId client_pid, InCopyHandle process) { // Register the process. - R_RETURN(m_ro->RegisterProcess(std::addressof(m_context_id), process.Get(), *client_pid)); + R_RETURN(m_ro->RegisterProcess(system.Kernel(), std::addressof(m_context_id), process.Get(), *client_pid)); } - Result RegisterProcessModuleInfo(ClientProcessId client_pid, u64 nrr_address, u64 nrr_size, - InCopyHandle process) { + Result RegisterProcessModuleInfo(ClientProcessId client_pid, u64 nrr_address, u64 nrr_size, InCopyHandle process) { // Validate the process. R_TRY(m_ro->ValidateProcess(m_context_id, *client_pid)); - // Register the module. - R_RETURN(m_ro->RegisterModuleInfo(m_context_id, nrr_address, nrr_size, m_nrr_kind, - m_nrr_kind == NrrKind::JitPlugin)); + R_RETURN(m_ro->RegisterModuleInfo(m_context_id, nrr_address, nrr_size, m_nrr_kind, m_nrr_kind == NrrKind::JitPlugin)); } private: diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index 3d898725e8..ee0dc83ee8 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -28,13 +31,15 @@ enum class UserDataTag { class Port : public MultiWaitHolder, public Common::IntrusiveListBaseNode { public: - explicit Port(Kernel::KServerPort* server_port, SessionRequestHandlerFactory&& handler_factory) - : MultiWaitHolder(server_port), m_handler_factory(std::move(handler_factory)) { + explicit Port(Kernel::KernelCore& kernel, Kernel::KServerPort* server_port, SessionRequestHandlerFactory&& handler_factory) + : MultiWaitHolder(server_port), m_handler_factory(std::move(handler_factory)) + , m_kernel{kernel} + { this->SetUserData(static_cast(UserDataTag::Port)); } ~Port() { - this->GetNativeHandle()->Close(); + this->GetNativeHandle()->Close(m_kernel); } SessionRequestHandlerPtr CreateHandler() { @@ -43,18 +48,20 @@ public: private: const SessionRequestHandlerFactory m_handler_factory; + Kernel::KernelCore& m_kernel; }; class Session : public MultiWaitHolder, public Common::IntrusiveListBaseNode { public: - explicit Session(Kernel::KServerSession* server_session, - std::shared_ptr&& manager) - : MultiWaitHolder(server_session), m_manager(std::move(manager)) { + explicit Session(Kernel::KernelCore& kernel, Kernel::KServerSession* server_session, std::shared_ptr&& manager) + : MultiWaitHolder(server_session), m_manager(std::move(manager)) + , m_kernel{kernel} + { this->SetUserData(static_cast(UserDataTag::Session)); } ~Session() { - this->GetNativeHandle()->Close(); + this->GetNativeHandle()->Close(m_kernel); } std::shared_ptr& GetManager() { @@ -68,12 +75,16 @@ public: private: std::shared_ptr m_manager; std::shared_ptr m_context; + Kernel::KernelCore& m_kernel; }; -ServerManager::ServerManager(Core::System& system) : m_system{system}, m_selection_mutex{system} { +ServerManager::ServerManager(Core::System& system) + : m_system{system} + , m_selection_mutex{system} +{ // Initialize event. m_wakeup_event = Kernel::KEvent::Create(system.Kernel()); - m_wakeup_event->Initialize(nullptr); + m_wakeup_event->Initialize(m_system.Kernel(), nullptr); // Register event. Kernel::KEvent::Register(system.Kernel(), m_wakeup_event); @@ -86,7 +97,7 @@ ServerManager::ServerManager(Core::System& system) : m_system{system}, m_selecti ServerManager::~ServerManager() { // Signal stop. m_stop_source.request_stop(); - m_wakeup_event->Signal(); + m_wakeup_event->Signal(m_system.Kernel()); // Wait for processing to stop. m_stopped.Wait(); @@ -109,11 +120,11 @@ ServerManager::~ServerManager() { } // Close wakeup event. - m_wakeup_event->GetReadableEvent().Close(); - m_wakeup_event->Close(); + m_wakeup_event->GetReadableEvent().Close(m_system.Kernel()); + m_wakeup_event->Close(m_system.Kernel()); if (m_deferral_event) { - m_deferral_event->GetReadableEvent().Close(); + m_deferral_event->GetReadableEvent().Close(m_system.Kernel()); // Write event is owned by ServiceManager } } @@ -125,7 +136,7 @@ void ServerManager::RunServer(std::unique_ptr&& server_manager) { Result ServerManager::RegisterSession(Kernel::KServerSession* server_session, std::shared_ptr manager) { // We are taking ownership of the server session, so don't open it. - auto* session = new Session(server_session, std::move(manager)); + auto* session = new Session(m_system.Kernel(), server_session, std::move(manager)); // Begin tracking the server session. { @@ -148,7 +159,7 @@ Result ServerManager::RegisterNamedService(const std::string& service_name, max_sessions, handler_factory)); // We are taking ownership of the server port, so don't open it. - auto* server = new Port(server_port, std::move(handler_factory)); + auto* server = new Port(m_system.Kernel(), server_port, std::move(handler_factory)); // Begin tracking the server port. { @@ -177,15 +188,15 @@ Result ServerManager::ManageNamedPort(const std::string& service_name, u32 max_sessions) { // Create a new port. auto* port = Kernel::KPort::Create(m_system.Kernel()); - port->Initialize(max_sessions, false, 0); + port->Initialize(m_system.Kernel(), max_sessions, false, 0); // Register the port. Kernel::KPort::Register(m_system.Kernel(), port); // Ensure that our reference to the port is closed if we fail to register it. SCOPE_EXIT { - port->GetClientPort().Close(); - port->GetServerPort().Close(); + port->GetClientPort().Close(m_system.Kernel()); + port->GetServerPort().Close(m_system.Kernel()); }; // Register the object name with the kernel. @@ -193,10 +204,10 @@ Result ServerManager::ManageNamedPort(const std::string& service_name, service_name.c_str())); // Open a new reference to the server port. - port->GetServerPort().Open(); + port->GetServerPort().Open(m_system.Kernel()); // Transfer ownership into a new port object. - auto* server = new Port(std::addressof(port->GetServerPort()), std::move(handler_factory)); + auto* server = new Port(m_system.Kernel(), std::addressof(port->GetServerPort()), std::move(handler_factory)); // Begin tracking the port. { @@ -217,7 +228,7 @@ Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) { ASSERT(m_deferral_event != nullptr); // Initialize the event. - m_deferral_event->Initialize(nullptr); + m_deferral_event->Initialize(m_system.Kernel(), nullptr); // Register the event. Kernel::KEvent::Register(m_system.Kernel(), m_deferral_event); @@ -258,7 +269,7 @@ void ServerManager::LinkToDeferredList(MultiWaitHolder* holder) { } // Signal the wakeup event. - m_wakeup_event->Signal(); + m_wakeup_event->Signal(m_system.Kernel()); } void ServerManager::LinkDeferred() { @@ -281,7 +292,7 @@ MultiWaitHolder* ServerManager::WaitSignaled() { auto* selected = m_multi_wait.WaitAny(m_system.Kernel()); if (selected == std::addressof(*m_wakeup_holder)) { // Clear and restart if we were woken up. - m_wakeup_event->Clear(); + m_wakeup_event->Clear(m_system.Kernel()); } else { // Unlink and handle the event. selected->UnlinkFromMultiWait(); @@ -323,7 +334,7 @@ Result ServerManager::LoopProcessImpl() { Result ServerManager::OnPortEvent(Port* server) { // Accept a new server session. auto* server_port = static_cast(server->GetNativeHandle()); - Kernel::KServerSession* server_session = server_port->AcceptSession(); + Kernel::KServerSession* server_session = server_port->AcceptSession(m_system.Kernel()); ASSERT(server_session != nullptr); // Create the session manager and install the handler. @@ -345,7 +356,7 @@ Result ServerManager::OnSessionEvent(Session* session) { // Try to receive a message. auto* server_session = static_cast(session->GetNativeHandle()); - res = server_session->ReceiveRequestHLE(&session->GetContext(), session->GetManager()); + res = server_session->ReceiveRequestHLE(m_system.Kernel(), &session->GetContext(), session->GetManager()); // If the session has been closed, we're done. if (res == Kernel::ResultSessionClosed) { @@ -382,7 +393,7 @@ Result ServerManager::CompleteSyncRequest(Session* session) { } // Send the reply. - res = server_session->SendReplyHLE(); + res = server_session->SendReplyHLE(m_system.Kernel()); // If the session has been closed, we're done. if (res == Kernel::ResultSessionClosed || service_res == IPC::ResultSessionClosed) { @@ -401,7 +412,7 @@ Result ServerManager::CompleteSyncRequest(Session* session) { Result ServerManager::OnDeferralEvent() { // Clear event before grabbing the list. - m_deferral_event->Clear(); + m_deferral_event->Clear(m_system.Kernel()); // Get and clear list. const auto deferrals = [&] { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 1095dcf6c3..419e3537b6 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -29,11 +32,11 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { ServiceManager::~ServiceManager() { for (auto& [name, port] : service_ports) { - port->Close(); + port->Close(kernel); } if (deferral_event) { - deferral_event->Close(); + deferral_event->Close(kernel); } } @@ -60,7 +63,7 @@ Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, st } auto* port = Kernel::KPort::Create(kernel); - port->Initialize(ServerSessionCountMax, false, 0); + port->Initialize(kernel, ServerSessionCountMax, false, 0); // Register the port. Kernel::KPort::Register(kernel, port); @@ -68,7 +71,7 @@ Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, st service_ports.emplace(name, std::addressof(port->GetClientPort())); registered_services.emplace(name, handler); if (deferral_event) { - deferral_event->Signal(); + deferral_event->Signal(kernel); } // Set our output. @@ -191,7 +194,7 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques // Create a new session. Kernel::KClientSession* session{}; - if (const auto result = client_port->CreateSession(&session); result.IsError()) { + if (const auto result = client_port->CreateSession(kernel, &session); result.IsError()) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); return result; } diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 00c88f6de1..7d7ef38152 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -37,8 +37,7 @@ void Controller::CloneCurrentObject(HLERequestContext& ctx) { // once this is a proper process // Reserve a new session from the process resource limit. - Kernel::KScopedResourceReservation session_reservation( - Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax); + Kernel::KScopedResourceReservation session_reservation(system.Kernel(), Kernel::GetCurrentProcessPointer(kernel), Kernel::LimitableResource::SessionCountMax); ASSERT(session_reservation.Succeeded()); // Create the session. @@ -46,7 +45,7 @@ void Controller::CloneCurrentObject(HLERequestContext& ctx) { ASSERT(session != nullptr); // Initialize the session. - session->Initialize(nullptr, 0); + session->Initialize(kernel, nullptr, 0); // Commit the session reservation. session_reservation.Commit(); diff --git a/src/core/hle/service/vi/vsync_manager.cpp b/src/core/hle/service/vi/vsync_manager.cpp index bdc4dfa966..59d0b82e0a 100644 --- a/src/core/hle/service/vi/vsync_manager.cpp +++ b/src/core/hle/service/vi/vsync_manager.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -9,18 +12,10 @@ namespace Service::VI { VsyncManager::VsyncManager() = default; VsyncManager::~VsyncManager() = default; -void VsyncManager::SignalVsync() { +void VsyncManager::SignalVsync(Kernel::KernelCore& kernel) { for (auto* event : m_vsync_events) { - event->Signal(); + event->Signal(kernel); } } -void VsyncManager::LinkVsyncEvent(Event* event) { - m_vsync_events.insert(event); -} - -void VsyncManager::UnlinkVsyncEvent(Event* event) { - m_vsync_events.erase(event); -} - } // namespace Service::VI diff --git a/src/core/hle/service/vi/vsync_manager.h b/src/core/hle/service/vi/vsync_manager.h index 5d45bb5eec..9c04516749 100644 --- a/src/core/hle/service/vi/vsync_manager.h +++ b/src/core/hle/service/vi/vsync_manager.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -5,6 +8,10 @@ #include +namespace Kernel { +class KernelCore; +} + namespace Service { class Event; } @@ -18,9 +25,13 @@ public: explicit VsyncManager(); ~VsyncManager(); - void SignalVsync(); - void LinkVsyncEvent(Event* event); - void UnlinkVsyncEvent(Event* event); + void SignalVsync(Kernel::KernelCore& kernel); + void LinkVsyncEvent(Event* event) { + m_vsync_events.insert(event); + } + void UnlinkVsyncEvent(Event* event) { + m_vsync_events.erase(event); + } private: std::set m_vsync_events; diff --git a/src/hid_core/hid_core.cpp b/src/hid_core/hid_core.cpp index 410c84afbc..12cd0c1f27 100644 --- a/src/hid_core/hid_core.cpp +++ b/src/hid_core/hid_core.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -10,18 +13,20 @@ namespace Core::HID { -HIDCore::HIDCore() - : player_1{std::make_unique(NpadIdType::Player1)}, - player_2{std::make_unique(NpadIdType::Player2)}, - player_3{std::make_unique(NpadIdType::Player3)}, - player_4{std::make_unique(NpadIdType::Player4)}, - player_5{std::make_unique(NpadIdType::Player5)}, - player_6{std::make_unique(NpadIdType::Player6)}, - player_7{std::make_unique(NpadIdType::Player7)}, - player_8{std::make_unique(NpadIdType::Player8)}, - other{std::make_unique(NpadIdType::Other)}, - handheld{std::make_unique(NpadIdType::Handheld)}, - console{std::make_unique()}, devices{std::make_unique()} {} +HIDCore::HIDCore(Kernel::KernelCore& kernel_) + : player_1{std::make_unique(NpadIdType::Player1)} + , player_2{std::make_unique(NpadIdType::Player2)} + , player_3{std::make_unique(NpadIdType::Player3)} + , player_4{std::make_unique(NpadIdType::Player4)} + , player_5{std::make_unique(NpadIdType::Player5)} + , player_6{std::make_unique(NpadIdType::Player6)} + , player_7{std::make_unique(NpadIdType::Player7)} + , player_8{std::make_unique(NpadIdType::Player8)} + , other{std::make_unique(NpadIdType::Other)} + , handheld{std::make_unique(NpadIdType::Handheld)} + , console{std::make_unique()}, devices{std::make_unique()} + , kernel{kernel_} +{} HIDCore::~HIDCore() = default; diff --git a/src/hid_core/hid_core.h b/src/hid_core/hid_core.h index dae29c5062..7da11897ca 100644 --- a/src/hid_core/hid_core.h +++ b/src/hid_core/hid_core.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -8,6 +11,10 @@ #include "common/common_funcs.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Core::HID { class EmulatedConsole; class EmulatedController; @@ -18,7 +25,7 @@ namespace Core::HID { class HIDCore { public: - explicit HIDCore(); + explicit HIDCore(Kernel::KernelCore& kernel); ~HIDCore(); YUZU_NON_COPYABLE(HIDCore); @@ -69,7 +76,6 @@ public: /// Number of emulated controllers static constexpr std::size_t available_controllers{10}; -private: std::unique_ptr player_1; std::unique_ptr player_2; std::unique_ptr player_3; @@ -82,6 +88,7 @@ private: std::unique_ptr handheld; std::unique_ptr console; std::unique_ptr devices; + Kernel::KernelCore& kernel; NpadStyleTag supported_style_tag{NpadStyleSet::All}; NpadIdType last_active_controller{NpadIdType::Handheld}; }; diff --git a/src/hid_core/hidbus/ringcon.cpp b/src/hid_core/hidbus/ringcon.cpp index 1927a6f856..b942cad480 100644 --- a/src/hid_core/hidbus/ringcon.cpp +++ b/src/hid_core/hidbus/ringcon.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 @@ -141,12 +141,12 @@ bool RingController::SetCommand(std::span data) { case RingConCommands::ReadRepCount: case RingConCommands::ReadTotalPushCount: ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); - send_command_async_event->Signal(); + send_command_async_event->Signal(system.Kernel()); return true; case RingConCommands::ResetRepCount: ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); total_rep_count = 0; - send_command_async_event->Signal(); + send_command_async_event->Signal(system.Kernel()); return true; case RingConCommands::SaveCalData: { ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes"); @@ -154,14 +154,14 @@ bool RingController::SetCommand(std::span data) { SaveCalData save_info{}; std::memcpy(&save_info, data.data(), sizeof(SaveCalData)); user_calibration = save_info.calibration; - send_command_async_event->Signal(); + send_command_async_event->Signal(system.Kernel()); return true; } default: LOG_ERROR(Service_HID, "Command not implemented {}", command); command = RingConCommands::Error; // Signal a reply to avoid softlocking the game - send_command_async_event->Signal(); + send_command_async_event->Signal(system.Kernel()); return false; } } diff --git a/src/hid_core/resource_manager.cpp b/src/hid_core/resource_manager.cpp index 0c10d1bec9..d28c6510a2 100644 --- a/src/hid_core/resource_manager.cpp +++ b/src/hid_core/resource_manager.cpp @@ -91,7 +91,7 @@ ResourceManager::~ResourceManager() { system.CoreTiming().UnscheduleEvent(mouse_keyboard_update_event); system.CoreTiming().UnscheduleEvent(motion_update_event); system.CoreTiming().UnscheduleEvent(touch_update_event); - input_event->Finalize(); + input_event->Finalize(system.Kernel()); }; void ResourceManager::Initialize() { diff --git a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp index d5f37247e1..a80f8271f9 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.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 2024 yuzu Emulator Project @@ -16,7 +16,9 @@ namespace Service::HID { -NpadAbstractBatteryHandler::NpadAbstractBatteryHandler() {} +NpadAbstractBatteryHandler::NpadAbstractBatteryHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractBatteryHandler::~NpadAbstractBatteryHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.h b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.h index 85ac5eb72f..9c270aa92d 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_battery_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_battery_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,6 +10,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { struct AppletResourceHolder; class NpadAbstractedPadHolder; @@ -15,7 +22,7 @@ class NpadAbstractPropertiesHandler; /// Handles Npad request from HID interfaces class NpadAbstractBatteryHandler final { public: - explicit NpadAbstractBatteryHandler(); + explicit NpadAbstractBatteryHandler(Kernel::KernelCore& kernel_); ~NpadAbstractBatteryHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -44,6 +51,7 @@ private: Core::HID::NpadPowerInfo left_battery{}; Core::HID::NpadPowerInfo right_battery{}; bool has_new_battery_data{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp index 36deb25c94..239fc7656e 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_button_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_button_handler.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 2024 yuzu Emulator Project @@ -16,7 +16,9 @@ namespace Service::HID { -NpadAbstractButtonHandler::NpadAbstractButtonHandler() {} +NpadAbstractButtonHandler::NpadAbstractButtonHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractButtonHandler::~NpadAbstractButtonHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_button_handler.h b/src/hid_core/resources/abstracted_pad/abstract_button_handler.h index 01eafe96df..6e49471b5e 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_button_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_button_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,6 +10,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { struct NpadSharedMemoryEntry; @@ -17,7 +24,7 @@ class NpadAbstractPropertiesHandler; /// Handles Npad request from HID interfaces class NpadAbstractButtonHandler final { public: - explicit NpadAbstractButtonHandler(); + explicit NpadAbstractButtonHandler(Kernel::KernelCore& kernel_); ~NpadAbstractButtonHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -70,6 +77,7 @@ private: u64 gc_sampling_number{}; GcTrigger gc_trigger_state{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp index 16ec2257fb..a2aaa1d8ec 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.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 2024 yuzu Emulator Project @@ -14,7 +14,9 @@ namespace Service::HID { -NpadAbstractIrSensorHandler::NpadAbstractIrSensorHandler() {} +NpadAbstractIrSensorHandler::NpadAbstractIrSensorHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractIrSensorHandler::~NpadAbstractIrSensorHandler() = default; @@ -52,7 +54,7 @@ void NpadAbstractIrSensorHandler::UpdateIrSensorState() { if (sensor_state == previous_state) { return; } - ir_sensor_event->Signal(); + ir_sensor_event->Signal(kernel); return; } @@ -77,7 +79,7 @@ void NpadAbstractIrSensorHandler::UpdateIrSensorState() { if (sensor_state == previous_state) { return; } - ir_sensor_event->Signal(); + ir_sensor_event->Signal(kernel); return; } @@ -86,7 +88,7 @@ void NpadAbstractIrSensorHandler::UpdateIrSensorState() { return; } - ir_sensor_event->Signal(); + ir_sensor_event->Signal(kernel); return; } @@ -105,7 +107,7 @@ Result NpadAbstractIrSensorHandler::ActivateIrSensor(bool is_enabled) { } sensor_state = NpadIrSensorState::Available; } - ir_sensor_event->Signal(); + ir_sensor_event->Signal(kernel); return ResultSuccess; } diff --git a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h index 9978115116..799d83e82f 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_ir_sensor_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -12,6 +15,7 @@ class EmulatedController; } namespace Kernel { +class KernelCore; class KEvent; class KReadableEvent; } // namespace Kernel @@ -30,7 +34,7 @@ class NpadAbstractPropertiesHandler; /// Handles Npad request from HID interfaces class NpadAbstractIrSensorHandler final { public: - explicit NpadAbstractIrSensorHandler(); + explicit NpadAbstractIrSensorHandler(Kernel::KernelCore& kernel_); ~NpadAbstractIrSensorHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -56,5 +60,6 @@ private: Kernel::KEvent* ir_sensor_event{nullptr}; Core::HID::EmulatedController* xcd_handle{}; NpadIrSensorState sensor_state{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp index 813d3d3188..94d895509b 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_led_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_led_handler.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 2024 yuzu Emulator Project @@ -15,7 +15,9 @@ namespace Service::HID { -NpadAbstractLedHandler::NpadAbstractLedHandler() {} +NpadAbstractLedHandler::NpadAbstractLedHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractLedHandler::~NpadAbstractLedHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_led_handler.h b/src/hid_core/resources/abstracted_pad/abstract_led_handler.h index 09528129b6..7ff12a9e75 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_led_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_led_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,6 +10,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { struct AppletResourceHolder; class NpadAbstractedPadHolder; @@ -15,7 +22,7 @@ class NpadAbstractPropertiesHandler; /// Handles Npad request from HID interfaces class NpadAbstractLedHandler final { public: - explicit NpadAbstractLedHandler(); + explicit NpadAbstractLedHandler(Kernel::KernelCore& kernel_); ~NpadAbstractLedHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -39,5 +46,6 @@ private: Core::HID::LedPattern left_pattern{0, 0, 0, 0}; Core::HID::LedPattern right_pattern{0, 0, 0, 0}; u64 led_interval{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp index 2b763d8e0f..d87446030a 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.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 2024 yuzu Emulator Project @@ -12,7 +12,9 @@ namespace Service::HID { -NpadAbstractMcuHandler::NpadAbstractMcuHandler() {} +NpadAbstractMcuHandler::NpadAbstractMcuHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractMcuHandler::~NpadAbstractMcuHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h index 9902dd03a7..44be82cd43 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_mcu_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,6 +10,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { struct IAbstractedPad; class NpadAbstractedPadHolder; @@ -28,7 +35,7 @@ static_assert(sizeof(NpadMcuHolder) == 0x10, "NpadMcuHolder is an invalid size") /// Handles Npad request from HID interfaces class NpadAbstractMcuHandler final { public: - explicit NpadAbstractMcuHandler(); + explicit NpadAbstractMcuHandler(Kernel::KernelCore& kernel_); ~NpadAbstractMcuHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -48,5 +55,6 @@ private: s32 ref_counter{}; std::array mcu_holder{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp index 80f5f3ba62..9990add4cc 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.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 2024 yuzu Emulator Project @@ -14,7 +14,9 @@ namespace Service::HID { -NpadAbstractNfcHandler::NpadAbstractNfcHandler() {} +NpadAbstractNfcHandler::NpadAbstractNfcHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractNfcHandler::~NpadAbstractNfcHandler() = default; @@ -48,13 +50,13 @@ void NpadAbstractNfcHandler::UpdateNfcState() { if (count == 0) { if (sensor_state == NpadNfcState::Active) { - nfc_activate_event->Signal(); + nfc_activate_event->Signal(kernel); } if (sensor_state == NpadNfcState::Unavailable) { return; } sensor_state = NpadNfcState::Unavailable; - input_event->Signal(); + input_event->Signal(kernel); return; } @@ -79,19 +81,18 @@ void NpadAbstractNfcHandler::UpdateNfcState() { return; } sensor_state = NpadNfcState::Available; - input_event->Signal(); + input_event->Signal(kernel); return; } if (sensor_state == NpadNfcState::Active) { - nfc_activate_event->Signal(); + nfc_activate_event->Signal(kernel); } if (sensor_state == NpadNfcState::Unavailable) { return; } sensor_state = NpadNfcState::Unavailable; - input_event->Signal(); - return; + input_event->Signal(kernel); } bool NpadAbstractNfcHandler::HasNfcSensor() { @@ -123,7 +124,7 @@ Result NpadAbstractNfcHandler::ActivateNfc(bool is_enabled) { } if (sensor_state != new_state) { sensor_state = new_state; - nfc_activate_event->Signal(); + nfc_activate_event->Signal(kernel); } return ResultSuccess; } diff --git a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h index 0702722a6b..223a0afd4e 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_nfc_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -8,7 +11,9 @@ #include "hid_core/hid_types.h" namespace Kernel { +class KernelCore; class KReadableEvent; +class KEvent; } enum class NpadNfcState : u32 { @@ -24,7 +29,7 @@ class NpadAbstractPropertiesHandler; /// Handles Npad request from HID interfaces class NpadAbstractNfcHandler final { public: - explicit NpadAbstractNfcHandler(); + explicit NpadAbstractNfcHandler(Kernel::KernelCore& kernel_); ~NpadAbstractNfcHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -53,5 +58,6 @@ private: Kernel::KEvent* input_event{nullptr}; u64 xcd_handle{}; NpadNfcState sensor_state{NpadNfcState::Unavailable}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp b/src/hid_core/resources/abstracted_pad/abstract_pad.cpp index d7cf2bba9b..b828c9b11e 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_pad.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 2024 yuzu Emulator Project @@ -12,7 +12,20 @@ namespace Service::HID { -AbstractPad::AbstractPad() {} +AbstractPad::AbstractPad(Kernel::KernelCore& kernel_) + //: abstract_pad_holder{kernel_} + : properties_handler{kernel_} + , led_handler{kernel_} + , ir_sensor_handler{kernel_} + , nfc_handler{kernel_} + , mcu_handler{kernel_} + , vibration_handler{kernel_} + , sixaxis_handler{kernel_} + , button_handler{kernel_} + , battery_handler{kernel_} + , palma_handler{kernel_} + , kernel{kernel_} +{} AbstractPad::~AbstractPad() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_pad.h b/src/hid_core/resources/abstracted_pad/abstract_pad.h index 3297924574..99d886d40c 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_pad.h +++ b/src/hid_core/resources/abstracted_pad/abstract_pad.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -27,6 +30,10 @@ #include "hid_core/resources/vibration/n64_vibration_device.h" #include "hid_core/resources/vibration/vibration_device.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { class AppletResource; class SixAxisResource; @@ -49,7 +56,7 @@ struct HandheldConfig; /// Handles Npad request from HID interfaces class AbstractPad final { public: - explicit AbstractPad(); + explicit AbstractPad(Kernel::KernelCore& kernel_); ~AbstractPad(); void SetExternals(AppletResourceHolder* applet_resource, @@ -88,17 +95,19 @@ public: private: AppletResourceHolder* applet_resource_holder{nullptr}; + + // TODO: fix NpadAbstractedPadHolder abstract_pad_holder{}; - NpadAbstractPropertiesHandler properties_handler{}; - NpadAbstractLedHandler led_handler{}; - NpadAbstractIrSensorHandler ir_sensor_handler{}; - NpadAbstractNfcHandler nfc_handler{}; - NpadAbstractMcuHandler mcu_handler{}; - NpadAbstractVibrationHandler vibration_handler{}; - NpadAbstractSixAxisHandler sixaxis_handler{}; - NpadAbstractButtonHandler button_handler{}; - NpadAbstractBatteryHandler battery_handler{}; - NpadAbstractPalmaHandler palma_handler{}; + NpadAbstractPropertiesHandler properties_handler; + NpadAbstractLedHandler led_handler; + NpadAbstractIrSensorHandler ir_sensor_handler; + NpadAbstractNfcHandler nfc_handler; + NpadAbstractMcuHandler mcu_handler; + NpadAbstractVibrationHandler vibration_handler; + NpadAbstractSixAxisHandler sixaxis_handler; + NpadAbstractButtonHandler button_handler; + NpadAbstractBatteryHandler battery_handler; + NpadAbstractPalmaHandler palma_handler; NpadN64VibrationDevice vibration_n64{}; NpadVibrationDevice vibration_left{}; @@ -114,6 +123,7 @@ private: s32 ref_counter{}; Core::HID::NpadInterfaceType interface_type{Core::HID::NpadInterfaceType::None}; + Kernel::KernelCore& kernel; }; using FullAbstractPad = std::array; diff --git a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp index 7766bedfd0..981f92ea00 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.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 2024 yuzu Emulator Project @@ -10,7 +10,9 @@ namespace Service::HID { -NpadAbstractPalmaHandler::NpadAbstractPalmaHandler() {} +NpadAbstractPalmaHandler::NpadAbstractPalmaHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractPalmaHandler::~NpadAbstractPalmaHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.h b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.h index fbd2e67e53..c09572a7b6 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_palma_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_palma_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -7,6 +10,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { class NpadAbstractedPadHolder; class NpadAbstractPropertiesHandler; @@ -14,7 +21,7 @@ class PalmaResource; class NpadAbstractPalmaHandler final { public: - explicit NpadAbstractPalmaHandler(); + explicit NpadAbstractPalmaHandler(Kernel::KernelCore& kernel_); ~NpadAbstractPalmaHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -32,6 +39,7 @@ private: PalmaResource* palma_resource{nullptr}; s32 ref_counter{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp index c225670043..db011bc6dd 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.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 2024 yuzu Emulator Project @@ -14,7 +14,9 @@ namespace Service::HID { -NpadAbstractPropertiesHandler::NpadAbstractPropertiesHandler() {} +NpadAbstractPropertiesHandler::NpadAbstractPropertiesHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractPropertiesHandler::~NpadAbstractPropertiesHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.h b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.h index fa68278998..1b8cf4be82 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_properties_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_properties_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -10,6 +13,10 @@ #include "hid_core/hid_types.h" #include "hid_core/resources/npad/npad_types.h" +namespace Kernel { +class KernelCore; +} + namespace Service::HID { struct NpadSharedMemoryEntry; @@ -25,7 +32,7 @@ struct ColorProperties { /// Handles Npad request from HID interfaces class NpadAbstractPropertiesHandler final { public: - explicit NpadAbstractPropertiesHandler(); + explicit NpadAbstractPropertiesHandler(Kernel::KernelCore& kernel_); ~NpadAbstractPropertiesHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -82,5 +89,6 @@ private: ColorProperties fullkey_color{}; ColorProperties left_color{}; ColorProperties right_color{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp index a8d2e5b2a0..54055751a2 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.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 2024 yuzu Emulator Project @@ -15,7 +15,9 @@ namespace Service::HID { -NpadAbstractSixAxisHandler::NpadAbstractSixAxisHandler() {} +NpadAbstractSixAxisHandler::NpadAbstractSixAxisHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractSixAxisHandler::~NpadAbstractSixAxisHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h index 9c20459e91..c126c25a23 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_sixaxis_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -6,6 +9,11 @@ #include "common/common_types.h" #include "core/hle/result.h" #include "hid_core/hid_types.h" +#include "hid_core/resources/shared_memory_format.h" + +namespace Kernel { +class KernelCore; +} namespace Service::HID { class SixAxisResource; @@ -17,7 +25,7 @@ struct NpadSixAxisSensorLifo; /// Handles Npad request from HID interfaces class NpadAbstractSixAxisHandler final { public: - explicit NpadAbstractSixAxisHandler(); + explicit NpadAbstractSixAxisHandler(Kernel::KernelCore& kernel_); ~NpadAbstractSixAxisHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -56,6 +64,7 @@ private: SixAxisResource* six_axis_resource{nullptr}; s32 ref_counter{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp index 3266422133..a0a37806fc 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.cpp +++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.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 2024 yuzu Emulator Project @@ -19,7 +19,9 @@ namespace Service::HID { -NpadAbstractVibrationHandler::NpadAbstractVibrationHandler() {} +NpadAbstractVibrationHandler::NpadAbstractVibrationHandler(Kernel::KernelCore& kernel_) + : kernel{kernel_} +{} NpadAbstractVibrationHandler::~NpadAbstractVibrationHandler() = default; diff --git a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h index 8bc8129c24..d57bf27814 100644 --- a/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h +++ b/src/hid_core/resources/abstracted_pad/abstract_vibration_handler.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -9,6 +12,10 @@ #include "core/hle/result.h" #include "hid_core/hid_types.h" +namespace Kernel { +class KernelCore; +} + namespace Core::HID { class HIDCore; } @@ -25,7 +32,7 @@ class NpadVibration; /// Keeps track of battery levels and updates npad battery shared memory values class NpadAbstractVibrationHandler final { public: - explicit NpadAbstractVibrationHandler(); + explicit NpadAbstractVibrationHandler(Kernel::KernelCore& kernel_); ~NpadAbstractVibrationHandler(); void SetAbstractPadHolder(NpadAbstractedPadHolder* holder); @@ -55,5 +62,6 @@ private: NpadGcVibrationDevice* gc_vibration_device{nullptr}; NpadVibration* vibration_handler{nullptr}; s32 ref_counter{}; + Kernel::KernelCore& kernel; }; } // namespace Service::HID diff --git a/src/hid_core/resources/applet_resource.cpp b/src/hid_core/resources/applet_resource.cpp index 31480a0e90..a7b9658cac 100644 --- a/src/hid_core/resources/applet_resource.cpp +++ b/src/hid_core/resources/applet_resource.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 2023 yuzu Emulator Project @@ -14,7 +14,10 @@ namespace Service::HID { AppletResource::AppletResource(Core::System& system_) : system{system_} {} -AppletResource::~AppletResource() = default; +AppletResource::~AppletResource() { + for (size_t i = 0; i < shared_memory_holder.size(); ++i) + shared_memory_holder[i].Finalize(system); +} Result AppletResource::CreateAppletResource(u64 aruid) { const u64 index = GetIndexFromAruid(aruid); @@ -34,7 +37,7 @@ Result AppletResource::CreateAppletResource(u64 aruid) { return result; } if (shared_memory.GetAddress() == nullptr) { - shared_memory.Finalize(); + shared_memory.Finalize(system); return ResultSharedMemoryNotInitialized; } } @@ -139,7 +142,7 @@ void AppletResource::FreeAppletResourceId(u64 aruid) { if (aruid_data.flag.is_assigned) { aruid_data.shared_memory_format = nullptr; aruid_data.flag.is_assigned.Assign(false); - shared_memory_holder[index].Finalize(); + shared_memory_holder[index].Finalize(system); } } diff --git a/src/hid_core/resources/npad/npad.cpp b/src/hid_core/resources/npad/npad.cpp index 04d8a85301..20f72c55f9 100644 --- a/src/hid_core/resources/npad/npad.cpp +++ b/src/hid_core/resources/npad/npad.cpp @@ -29,7 +29,22 @@ namespace Service::HID { NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service_context_) - : hid_core{hid_core_}, service_context{service_context_}, npad_resource{service_context} { + : hid_core{hid_core_} + , service_context{service_context_} + , npad_resource{hid_core_.kernel, service_context} + , abstracted_pads{{ + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + AbstractPad{hid_core_.kernel}, + }} +{ for (std::size_t aruid_index = 0; aruid_index < AruidIndexMax; ++aruid_index) { for (std::size_t i = 0; i < controller_data[aruid_index].size(); ++i) { auto& controller = controller_data[aruid_index][i]; @@ -43,7 +58,6 @@ NPad::NPad(Core::HID::HIDCore& hid_core_, KernelHelpers::ServiceContext& service } } for (std::size_t i = 0; i < abstracted_pads.size(); ++i) { - abstracted_pads[i] = AbstractPad{}; abstracted_pads[i].SetNpadId(IndexToNpadIdType(i)); } } diff --git a/src/hid_core/resources/npad/npad.h b/src/hid_core/resources/npad/npad.h index 99e761127d..6018d45650 100644 --- a/src/hid_core/resources/npad/npad.h +++ b/src/hid_core/resources/npad/npad.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -209,7 +212,6 @@ private: NpadVibration vibration_handler{}; std::atomic press_state{}; - std::array, AruidIndexMax> - controller_data{}; + std::array, AruidIndexMax> controller_data{}; }; } // namespace Service::HID diff --git a/src/hid_core/resources/npad/npad_resource.cpp b/src/hid_core/resources/npad/npad_resource.cpp index 08546f8dc4..f582f1eaa3 100644 --- a/src/hid_core/resources/npad/npad_resource.cpp +++ b/src/hid_core/resources/npad/npad_resource.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 2023 yuzu Emulator Project @@ -13,7 +13,10 @@ namespace Service::HID { -NPadResource::NPadResource(KernelHelpers::ServiceContext& context) : service_context{context} {} +NPadResource::NPadResource(Kernel::KernelCore& kernel_, KernelHelpers::ServiceContext& context) + : kernel{kernel_} + , service_context{context} +{} NPadResource::~NPadResource() = default; @@ -526,7 +529,7 @@ Result NPadResource::AcquireNpadStyleSetUpdateEventHandle(u64 aruid, *out_event = &controller_state.style_set_update_event->GetReadableEvent(); if (controller_state.is_styleset_update_event_initialized) { - controller_state.style_set_update_event->Signal(); + controller_state.style_set_update_event->Signal(kernel); } return ResultSuccess; @@ -539,7 +542,7 @@ Result NPadResource::SignalStyleSetUpdateEvent(u64 aruid, Core::HID::NpadIdType } auto controller = state[aruid_index].controller_state[NpadIdTypeToIndex(npad_id)]; if (controller.is_styleset_update_event_initialized) { - controller.style_set_update_event->Signal(); + controller.style_set_update_event->Signal(kernel); } return ResultSuccess; } diff --git a/src/hid_core/resources/npad/npad_resource.h b/src/hid_core/resources/npad/npad_resource.h index 8ee5702fd4..425b11e771 100644 --- a/src/hid_core/resources/npad/npad_resource.h +++ b/src/hid_core/resources/npad/npad_resource.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -20,6 +23,7 @@ class System; } namespace Kernel { +class KernelCore; class KReadableEvent; } @@ -37,8 +41,7 @@ struct NpadState { DataStatusFlag flag{}; u64 aruid{}; NPadData data{}; - std::array, MaxSupportedNpadIdTypes> - button_config; + std::array, MaxSupportedNpadIdTypes> button_config; std::array controller_state; NpadRevision npad_revision; }; @@ -46,7 +49,7 @@ struct NpadState { /// Handles Npad request from HID interfaces class NPadResource final { public: - explicit NPadResource(KernelHelpers::ServiceContext& context); + explicit NPadResource(Kernel::KernelCore& kernel, KernelHelpers::ServiceContext& context); ~NPadResource(); NPadData* GetActiveData(); @@ -127,6 +130,7 @@ private: NpadJoyHoldType default_hold_type{}; s32 ref_counter{}; + Kernel::KernelCore& kernel; KernelHelpers::ServiceContext& service_context; }; } // namespace Service::HID diff --git a/src/hid_core/resources/palma/palma.cpp b/src/hid_core/resources/palma/palma.cpp index 0652455f5f..1a1a3aae18 100644 --- a/src/hid_core/resources/palma/palma.cpp +++ b/src/hid_core/resources/palma/palma.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 2022 yuzu Emulator Project @@ -77,7 +77,7 @@ Result Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle, u64 palma_a operation.operation = PackedPalmaOperationType::PlayActivity; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -96,7 +96,7 @@ Result Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) { operation.operation = PackedPalmaOperationType::ReadStep; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -125,7 +125,7 @@ Result Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle) { operation.operation = PackedPalmaOperationType::ReadUniqueCode; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -136,7 +136,7 @@ Result Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle& handle) { operation.operation = PackedPalmaOperationType::SetUniqueCodeInvalid; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -149,7 +149,7 @@ Result Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandle& handle, operation.operation = PackedPalmaOperationType::WriteRgbLedPatternEntry; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -161,7 +161,7 @@ Result Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle, PalmaWave operation.operation = PackedPalmaOperationType::WriteWaveEntry; operation.result = PalmaResultSuccess; operation.data = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -174,7 +174,7 @@ Result Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& operation.operation = PackedPalmaOperationType::ReadDataBaseIdentificationVersion; operation.result = PalmaResultSuccess; operation.data[0] = {}; - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } @@ -186,7 +186,7 @@ Result Palma::GetPalmaDataBaseIdentificationVersion(const PalmaConnectionHandle& operation.result = PalmaResultSuccess; operation.data = {}; operation.data[0] = static_cast(database_id_version); - operation_complete_event->Signal(); + operation_complete_event->Signal(hid_core.kernel); return ResultSuccess; } diff --git a/src/hid_core/resources/shared_memory_holder.cpp b/src/hid_core/resources/shared_memory_holder.cpp index ada593d8ba..c94829821a 100644 --- a/src/hid_core/resources/shared_memory_holder.cpp +++ b/src/hid_core/resources/shared_memory_holder.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -9,17 +12,10 @@ #include "hid_core/resources/shared_memory_holder.h" namespace Service::HID { -SharedMemoryHolder::SharedMemoryHolder() {} - -SharedMemoryHolder::~SharedMemoryHolder() { - Finalize(); -} Result SharedMemoryHolder::Initialize(Core::System& system) { shared_memory = Kernel::KSharedMemory::Create(system.Kernel()); - const Result result = shared_memory->Initialize( - system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, - Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); + const Result result = shared_memory->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, Kernel::Svc::MemoryPermission::None, Kernel::Svc::MemoryPermission::Read, sizeof(SharedMemoryFormat)); if (result.IsError()) { return result; } @@ -31,9 +27,9 @@ Result SharedMemoryHolder::Initialize(Core::System& system) { return ResultSuccess; } -void SharedMemoryHolder::Finalize() { +void SharedMemoryHolder::Finalize(Core::System& system) { if (address != nullptr) { - shared_memory->Close(); + shared_memory->Close(system.Kernel()); } is_created = false; is_mapped = false; diff --git a/src/hid_core/resources/shared_memory_holder.h b/src/hid_core/resources/shared_memory_holder.h index 943407c00a..5fcaddecc0 100644 --- a/src/hid_core/resources/shared_memory_holder.h +++ b/src/hid_core/resources/shared_memory_holder.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later @@ -19,17 +22,13 @@ struct SharedMemoryFormat; // This is nn::hid::detail::SharedMemoryHolder class SharedMemoryHolder { public: - SharedMemoryHolder(); - ~SharedMemoryHolder(); - Result Initialize(Core::System& system); - void Finalize(); + void Finalize(Core::System& system); bool IsMapped(); SharedMemoryFormat* GetAddress(); Kernel::KSharedMemory* GetHandle(); -private: bool is_owner{}; bool is_created{}; bool is_mapped{}; diff --git a/src/hid_core/resources/touch_screen/touch_screen_resource.cpp b/src/hid_core/resources/touch_screen/touch_screen_resource.cpp index 018a43b6c0..d340f186b3 100644 --- a/src/hid_core/resources/touch_screen/touch_screen_resource.cpp +++ b/src/hid_core/resources/touch_screen/touch_screen_resource.cpp @@ -494,7 +494,7 @@ void TouchResource::ReadTouchInput() { has_moved |= (delta_x > 1 || delta_y > 1); } if (has_moved) { - input_event->Signal(); + input_event->Signal(system.Kernel()); } } }