[video_core, hle] remove redundant parent references in system structs (#3908)

reworked a bit to remove references of parent objects and instead pass as arguments to methods to prevent useless reloads

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Co-authored-by: maufeat <sahyno1996@gmail.com>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3908
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: crueter <crueter@eden-emu.dev>
This commit is contained in:
lizzie
2026-06-23 06:31:25 +02:00
committed by crueter
parent f8facda35f
commit 3aa0d46259
307 changed files with 4419 additions and 4477 deletions
+6 -5
View File
@@ -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,17 +25,15 @@ Result SetThreadActivity(Core::System& system, Handle thread_handle,
R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue);
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Check that the activity is being set on a non-current thread for the current process.
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()),
ResultInvalidHandle);
R_UNLESS(thread->GetOwnerProcess() == GetCurrentProcessPointer(system.Kernel()), ResultInvalidHandle);
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;
}
+4 -2
View File
@@ -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
@@ -37,8 +40,7 @@ Result FlushProcessDataCache(Core::System& system, Handle process_handle, u64 ad
R_UNLESS(size == static_cast<uint64_t>(size), ResultInvalidCurrentMemory);
// Get the process from its handle.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
KScopedAutoObject process = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Verify the region is within range.
+15 -25
View File
@@ -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,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,24 +43,23 @@ 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(out, code_mem));
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(system.Kernel(), out, code_mem));
R_SUCCEED();
}
@@ -85,8 +81,8 @@ Result ControlCodeMemory(Core::System& system, Handle code_memory_handle,
// Get the code memory from its handle.
KScopedAutoObject code_mem = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KCodeMemory>(code_memory_handle);
.GetHandleTable()
.GetObject<KCodeMemory>(system.Kernel(), code_memory_handle);
R_UNLESS(code_mem.IsNotNull(), ResultInvalidHandle);
// NOTE: Here, Atmosphere extends the SVC to allow code memory operations on one's own process.
@@ -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);
@@ -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
@@ -29,17 +32,17 @@ 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);
// Add to the handle table.
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(out, das));
R_TRY(GetCurrentProcess(system.Kernel()).GetHandleTable().Add(system.Kernel(), out, das));
R_SUCCEED();
}
@@ -47,8 +50,8 @@ Result CreateDeviceAddressSpace(Core::System& system, Handle* out, uint64_t das_
Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Attach.
@@ -58,8 +61,8 @@ Result AttachDeviceAddressSpace(Core::System& system, DeviceName device_name, Ha
Result DetachDeviceAddressSpace(Core::System& system, DeviceName device_name, Handle das_handle) {
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Detach.
@@ -99,13 +102,13 @@ Result MapDeviceAddressSpaceByForce(Core::System& system, Handle das_handle, Han
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
@@ -140,13 +143,13 @@ Result MapDeviceAddressSpaceAligned(Core::System& system, Handle das_handle, Han
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
@@ -172,13 +175,12 @@ Result UnmapDeviceAddressSpace(Core::System& system, Handle das_handle, Handle p
// Get the device address space.
KScopedAutoObject das = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(das_handle);
.GetHandleTable()
.GetObject<KDeviceAddressSpace>(system.Kernel(), das_handle);
R_UNLESS(das.IsNotNull(), ResultInvalidHandle);
// Get the process.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
KScopedAutoObject process = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the process address is within range.
+18 -19
View File
@@ -22,9 +22,9 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
// Fail-safe for system applets
const auto program_id = GetCurrentProcess(system.Kernel()).GetProgramId();
if ((program_id & 0xFFFFFFFFFFFFFF00ull) == 0x0100000000001000ull) {
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
KScopedAutoObject event = handle_table.GetObject<KEvent>(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);
@@ -34,10 +34,10 @@ Result SignalEvent(Core::System& system, Handle event_handle) {
// Get the event.
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
KScopedAutoObject event = handle_table.GetObject<KEvent>(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) {
@@ -48,18 +48,18 @@ Result ClearEvent(Core::System& system, Handle event_handle) {
// Try to clear the writable event.
{
KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
KScopedAutoObject event = handle_table.GetObject<KEvent>(system.Kernel(), event_handle);
if (event.IsNotNull()) {
event->Clear();
event->Clear(system.Kernel());
R_SUCCEED();
}
}
// Try to clear the readable event.
{
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(event_handle);
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(system.Kernel(), event_handle);
if (readable_event.IsNotNull()) {
readable_event->Clear();
readable_event->Clear(system.Kernel());
R_SUCCEED();
}
}
@@ -71,43 +71,42 @@ 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(out_write, event));
R_TRY(handle_table.Add(system.Kernel(), out_write, event));
// Ensure that we maintain a clean handle state on exit.
ON_RESULT_FAILURE {
handle_table.Remove(*out_write);
handle_table.Remove(system.Kernel(), *out_write);
};
// Add the readable event to the handle table.
R_RETURN(handle_table.Add(out_read, std::addressof(event->GetReadableEvent())));
R_RETURN(handle_table.Add(system.Kernel(), out_read, std::addressof(event->GetReadableEvent())));
}
Result SignalEvent64(Core::System& system, Handle event_handle) {
+2 -2
View File
@@ -106,14 +106,14 @@ void Break(Core::System& system, BreakReason reason, u64 info1, u64 info2) {
handle_debug_buffer(info1, info2);
system.CurrentPhysicalCore().LogBacktrace();
system.CurrentPhysicalCore().LogBacktrace(system.Kernel());
}
const bool should_break = !notification_only;
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);
}
}
+10 -10
View File
@@ -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
@@ -46,7 +46,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
R_UNLESS(info_sub_id == 0, ResultInvalidEnumValue);
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
switch (info_id_type) {
@@ -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:
@@ -175,7 +175,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
}
Handle resource_handle{};
R_TRY(handle_table.Add(std::addressof(resource_handle), resource_limit));
R_TRY(handle_table.Add(system.Kernel(), std::addressof(resource_handle), resource_limit));
*result = resource_handle;
R_SUCCEED();
@@ -203,8 +203,8 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
}
KScopedAutoObject thread = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KThread>(static_cast<Handle>(handle));
.GetHandleTable()
.GetObject<KThread>(system.Kernel(), Handle(handle));
if (thread.IsNull()) {
LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
static_cast<Handle>(handle));
@@ -256,7 +256,7 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle
// Get a new handle for the current process.
Handle tmp;
R_TRY(handle_table.Add(std::addressof(tmp), current_process));
R_TRY(handle_table.Add(system.Kernel(), std::addressof(tmp), current_process));
// Set the output.
*result = tmp;
+20 -25
View File
@@ -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
@@ -20,19 +20,17 @@ namespace Kernel::Svc {
namespace {
Result SendSyncRequestImpl(KernelCore& kernel, uintptr_t message, size_t buffer_size,
Handle session_handle) {
Result SendSyncRequestImpl(KernelCore& kernel, uintptr_t message, size_t buffer_size, Handle session_handle) {
// Get the client session.
KScopedAutoObject session =
GetCurrentProcess(kernel).GetHandleTable().GetObject<KClientSession>(session_handle);
KScopedAutoObject session = GetCurrentProcess(kernel).GetHandleTable().GetObject<KClientSession>(kernel, session_handle);
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,
@@ -41,8 +39,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
int64_t timeout_ns) {
// Reply to the target, if one is specified.
if (reply_target != InvalidHandle) {
KScopedAutoObject session =
GetCurrentProcess(kernel).GetHandleTable().GetObject<KServerSession>(reply_target);
KScopedAutoObject session = GetCurrentProcess(kernel).GetHandleTable().GetObject<KServerSession>(kernel, reply_target);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
// If we fail to reply, we want to set the output index to -1.
@@ -51,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.
@@ -77,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);
}
@@ -87,7 +83,7 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
if (R_SUCCEEDED(result)) {
KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
if (session != nullptr) {
result = session->ReceiveRequest(message, buffer_size, message_paddr);
result = session->ReceiveRequest(kernel, message, buffer_size, message_paddr);
if (ResultNotFound == result) {
continue;
}
@@ -127,14 +123,14 @@ Result ReplyAndReceiveImpl(KernelCore& kernel, int32_t* out_index, uintptr_t mes
// Convert the handles to objects.
R_UNLESS(
handle_table.GetMultipleObjects<KSynchronizationObject>(objs, handles, num_handles),
handle_table.GetMultipleObjects<KSynchronizationObject>(kernel, objs, handles, num_handles),
ResultInvalidHandle);
}
// 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);
}
};
@@ -188,16 +184,15 @@ 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.
KScopedAutoObject session = process.GetHandleTable().GetObject<KClientSession>(session_handle);
KScopedAutoObject session = process.GetHandleTable().GetObject<KClientSession>(system.Kernel(), session_handle);
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.
@@ -205,30 +200,30 @@ 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.
KEvent::Register(system.Kernel(), event);
// Add the readable event to the handle table.
R_TRY(handle_table.Add(out_event_handle, std::addressof(event->GetReadableEvent())));
R_TRY(handle_table.Add(system.Kernel(), out_event_handle, std::addressof(event->GetReadableEvent())));
// Ensure that if we fail to send the request, we close the readable handle.
ON_RESULT_FAILURE {
handle_table.Remove(*out_event_handle);
handle_table.Remove(system.Kernel(), *out_event_handle);
};
// 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,
+9 -6
View File
@@ -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
@@ -14,12 +17,12 @@ namespace Kernel::Svc {
Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* args) {
// Get the light client session from its handle.
KScopedAutoObject session = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KLightClientSession>(session_handle);
.GetHandleTable()
.GetObject<KLightClientSession>(system.Kernel(), session_handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
// Send the request.
R_TRY(session->SendSyncRequest(args));
R_TRY(session->SendSyncRequest(system.Kernel(), args));
R_SUCCEED();
}
@@ -27,12 +30,12 @@ Result SendSyncRequestLight(Core::System& system, Handle session_handle, u32* ar
Result ReplyAndReceiveLight(Core::System& system, Handle session_handle, u32* args) {
// Get the light server session from its handle.
KScopedAutoObject session = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KLightServerSession>(session_handle);
.GetHandleTable()
.GetObject<KLightServerSession>(system.Kernel(), session_handle);
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
// Handle the request.
R_TRY(session->ReplyAndReceive(args));
R_TRY(session->ReplyAndReceive(system.Kernel(), args));
R_SUCCEED();
}
+28 -28
View File
@@ -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
@@ -33,18 +36,18 @@ Result ConnectToNamedPort(Core::System& system, Handle* out, u64 user_name) {
// Reserve a handle for the port.
// NOTE: Nintendo really does write directly to the output handle here.
R_TRY(handle_table.Reserve(out));
R_TRY(handle_table.Reserve(system.Kernel(), out));
ON_RESULT_FAILURE {
handle_table.Unreserve(*out);
handle_table.Unreserve(system.Kernel(), *out);
};
// 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(*out, session);
session->Close();
handle_table.Register(system.Kernel(), *out, session);
session->Close(system.Kernel());
// We succeeded.
R_SUCCEED();
@@ -65,27 +68,27 @@ 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.
KPort::Register(kernel, port);
// Add the client to the handle table.
R_TRY(handle_table.Add(out_client, std::addressof(port->GetClientPort())));
R_TRY(handle_table.Add(system.Kernel(), out_client, std::addressof(port->GetClientPort())));
// Ensure that we maintain a clean handle state on exit.
ON_RESULT_FAILURE {
handle_table.Remove(*out_client);
handle_table.Remove(system.Kernel(), *out_client);
};
// Add the server to the handle table.
R_RETURN(handle_table.Add(out_server, std::addressof(port->GetServerPort())));
R_RETURN(handle_table.Add(system.Kernel(), out_server, std::addressof(port->GetServerPort())));
}
Result ConnectToPort(Core::System& system, Handle* out, Handle port) {
@@ -93,36 +96,33 @@ Result ConnectToPort(Core::System& system, Handle* out, Handle port) {
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
// Get the client port.
KScopedAutoObject client_port = handle_table.GetObject<KClientPort>(port);
KScopedAutoObject client_port = handle_table.GetObject<KClientPort>(system.Kernel(), port);
R_UNLESS(client_port.IsNotNull(), ResultInvalidHandle);
// Reserve a handle for the port.
// NOTE: Nintendo really does write directly to the output handle here.
R_TRY(handle_table.Reserve(out));
R_TRY(handle_table.Reserve(system.Kernel(), out));
ON_RESULT_FAILURE {
handle_table.Unreserve(*out);
handle_table.Unreserve(system.Kernel(), *out);
};
// Create the session.
KAutoObject* session;
if (client_port->IsLight()) {
R_TRY(client_port->CreateLightSession(
reinterpret_cast<KLightClientSession**>(std::addressof(session))));
if (client_port->IsLight(system.Kernel())) {
R_TRY(client_port->CreateLightSession(system.Kernel(), reinterpret_cast<KLightClientSession**>(std::addressof(session))));
} else {
R_TRY(client_port->CreateSession(
reinterpret_cast<KClientSession**>(std::addressof(session))));
R_TRY(client_port->CreateSession(system.Kernel(), reinterpret_cast<KClientSession**>(std::addressof(session))));
}
// Register the session.
handle_table.Register(*out, session);
session->Close();
handle_table.Register(system.Kernel(), *out, session);
session->Close(system.Kernel());
// We succeeded.
R_SUCCEED();
}
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
int32_t max_sessions) {
Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, int32_t max_sessions) {
// Copy the provided name from user memory to kernel memory.
auto string_name =
GetCurrentMemory(system.Kernel()).ReadCString(user_name, KObjectName::NameLengthMax);
@@ -144,21 +144,21 @@ 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.
R_TRY(handle_table.Add(out_server_handle, std::addressof(port->GetServerPort())));
R_TRY(handle_table.Add(system.Kernel(), out_server_handle, std::addressof(port->GetServerPort())));
ON_RESULT_FAILURE {
handle_table.Remove(*out_server_handle);
handle_table.Remove(system.Kernel(), *out_server_handle);
};
// Create a new object name.
+4 -4
View File
@@ -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
@@ -27,8 +27,8 @@ Result GetProcessId(Core::System& system, u64* out_process_id, Handle handle) {
// Get the object from the handle table.
KScopedAutoObject obj = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KAutoObject>(static_cast<Handle>(handle));
.GetHandleTable()
.GetObject<KAutoObject>(system.Kernel(), Handle(handle));
R_UNLESS(obj.IsNotNull(), ResultInvalidHandle);
// Get the process from the object.
@@ -98,7 +98,7 @@ Result GetProcessInfo(Core::System& system, s64* out, Handle process_handle,
LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type={:#X}", process_handle, info_type);
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
process_handle);
@@ -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
@@ -48,7 +48,7 @@ Result SetProcessMemoryPermission(Core::System& system, Handle process_handle, u
// Get the process from its handle.
KScopedAutoObject process =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(process_handle);
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KProcess>(system.Kernel(), process_handle);
R_UNLESS(process.IsNotNull(), ResultInvalidHandle);
// Validate that the address is in range.
@@ -76,7 +76,7 @@ Result MapProcessMemory(Core::System& system, u64 dst_address, Handle process_ha
// Get the processes.
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
KScopedAutoObject src_process =
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(system.Kernel(), process_handle);
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
// Get the page tables.
@@ -117,7 +117,7 @@ Result UnmapProcessMemory(Core::System& system, u64 dst_address, Handle process_
// Get the processes.
KProcess* dst_process = GetCurrentProcessPointer(system.Kernel());
KScopedAutoObject src_process =
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(process_handle);
dst_process->GetHandleTable().GetObjectWithoutPseudoHandle<KProcess>(system.Kernel(), process_handle);
R_UNLESS(src_process.IsNotNull(), ResultInvalidHandle);
// Get the page tables.
@@ -174,7 +174,7 @@ Result MapProcessCodeMemory(Core::System& system, Handle process_handle, u64 dst
}
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
process_handle);
@@ -234,7 +234,7 @@ Result UnmapProcessCodeMemory(Core::System& system, Handle process_handle, u64 d
}
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).",
process_handle);
+4 -1
View File
@@ -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
@@ -23,7 +26,7 @@ Result QueryProcessMemory(Core::System& system, uint64_t out_memory_info, PageIn
Handle process_handle, uint64_t address) {
LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address);
const auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
KScopedAutoObject process = handle_table.GetObject<KProcess>(process_handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), process_handle);
if (process.IsNull()) {
LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
process_handle);
+10 -7
View File
@@ -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
@@ -19,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.
@@ -29,7 +32,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) {
KResourceLimit::Register(kernel, resource_limit);
// Add the limit to the handle table.
R_RETURN(GetCurrentProcess(kernel).GetHandleTable().Add(out_handle, resource_limit));
R_RETURN(GetCurrentProcess(kernel).GetHandleTable().Add(system.Kernel(), out_handle, resource_limit));
}
Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value,
@@ -42,8 +45,8 @@ Result GetResourceLimitLimitValue(Core::System& system, s64* out_limit_value,
// Get the resource limit.
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KResourceLimit>(resource_limit_handle);
.GetHandleTable()
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
// Get the limit value.
@@ -62,8 +65,8 @@ Result GetResourceLimitCurrentValue(Core::System& system, s64* out_current_value
// Get the resource limit.
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KResourceLimit>(resource_limit_handle);
.GetHandleTable()
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
// Get the current value.
@@ -83,7 +86,7 @@ Result SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_ha
// Get the resource limit.
KScopedAutoObject resource_limit = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KResourceLimit>(resource_limit_handle);
.GetObject<KResourceLimit>(system.Kernel(), resource_limit_handle);
R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle);
// Set the limit value.
+18 -15
View File
@@ -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
@@ -23,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());
@@ -62,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();
@@ -70,23 +73,23 @@ 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.
T::Register(system.Kernel(), session);
// Add the server session to the handle table.
R_TRY(handle_table.Add(out_server, std::addressof(session->GetServerSession())));
R_TRY(handle_table.Add(system.Kernel(), out_server, std::addressof(session->GetServerSession())));
// Ensure that we maintain a clean handle state on exit.
ON_RESULT_FAILURE {
handle_table.Remove(*out_server);
handle_table.Remove(system.Kernel(), *out_server);
};
// Add the client session to the handle table.
R_RETURN(handle_table.Add(out_client, std::addressof(session->GetClientSession())));
R_RETURN(handle_table.Add(system.Kernel(), out_client, std::addressof(session->GetClientSession())));
}
} // namespace
@@ -105,29 +108,29 @@ Result AcceptSession(Core::System& system, Handle* out, Handle port_handle) {
auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
// Get the server port.
KScopedAutoObject port = handle_table.GetObject<KServerPort>(port_handle);
KScopedAutoObject port = handle_table.GetObject<KServerPort>(system.Kernel(), port_handle);
R_UNLESS(port.IsNotNull(), ResultInvalidHandle);
// Reserve an entry for the new session.
R_TRY(handle_table.Reserve(out));
R_TRY(handle_table.Reserve(system.Kernel(), out));
ON_RESULT_FAILURE {
handle_table.Unreserve(*out);
handle_table.Unreserve(system.Kernel(), *out);
};
// 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.
R_UNLESS(session != nullptr, ResultNotFound);
// Register the session.
handle_table.Register(*out, session);
session->Close();
handle_table.Register(system.Kernel(), *out, session);
session->Close(system.Kernel());
R_SUCCEED();
}
@@ -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
@@ -49,18 +49,18 @@ Result MapSharedMemory(Core::System& system, Handle shmem_handle, u64 address, u
auto& page_table = process.GetPageTable();
// Get the shared memory.
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(system.Kernel(), shmem_handle);
R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle);
// Verify that the mapping is in range.
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.
@@ -79,7 +79,7 @@ Result UnmapSharedMemory(Core::System& system, Handle shmem_handle, u64 address,
auto& page_table = process.GetPageTable();
// Get the shared memory.
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(shmem_handle);
KScopedAutoObject shmem = process.GetHandleTable().GetObject<KSharedMemory>(system.Kernel(), shmem_handle);
R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle);
// Verify that the mapping is in range.
@@ -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();
}
+22 -30
View File
@@ -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
@@ -20,7 +20,7 @@ Result CloseHandle(Core::System& system, Handle handle) {
LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
// Remove the handle.
R_UNLESS(GetCurrentProcess(system.Kernel()).GetHandleTable().Remove(handle),
R_UNLESS(GetCurrentProcess(system.Kernel()).GetHandleTable().Remove(system.Kernel(), handle),
ResultInvalidHandle);
R_SUCCEED();
@@ -35,17 +35,17 @@ Result ResetSignal(Core::System& system, Handle handle) {
// Try to reset as readable event.
{
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(handle);
KScopedAutoObject readable_event = handle_table.GetObject<KReadableEvent>(system.Kernel(), handle);
if (readable_event.IsNotNull()) {
R_RETURN(readable_event->Reset());
R_RETURN(readable_event->Reset(system.Kernel()));
}
}
// Try to reset as process.
{
KScopedAutoObject process = handle_table.GetObject<KProcess>(handle);
KScopedAutoObject process = handle_table.GetObject<KProcess>(system.Kernel(), handle);
if (process.IsNotNull()) {
R_RETURN(process->Reset());
R_RETURN(process->Reset(system.Kernel()));
}
}
@@ -62,35 +62,30 @@ 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<KSynchronizationObject>(
objs.data(), handles.data(), num_handles),
ResultInvalidHandle);
R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(system.Kernel(), objs.data(), handles.data(), num_handles), ResultInvalidHandle);
}
// 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;
@@ -100,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);
@@ -111,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<KThread>(handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(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());
}
}
+22 -30
View File
@@ -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,13 +69,13 @@ 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);
// Add the thread to the handle table.
R_TRY(process.GetHandleTable().Add(out_handle, thread));
R_TRY(process.GetHandleTable().Add(system.Kernel(), out_handle, thread));
// Pass the thread handle to the thread local region.
process.GetMemory().Write32(GetInteger(thread->GetTlsAddress()) + 0x110, *out_handle);
@@ -88,12 +88,11 @@ Result StartThread(Core::System& system, Handle thread_handle) {
LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Try to start the thread.
R_TRY(thread->Run());
R_TRY(thread->Run(system.Kernel()));
R_SUCCEED();
}
@@ -102,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
@@ -130,7 +129,7 @@ void SleepThread(Core::System& system, s64 ns) {
// Sleep.
// NOTE: Nintendo does not check the result of this sleep.
static_cast<void>(GetCurrentThread(kernel).Sleep(timeout));
static_cast<void>(GetCurrentThread(kernel).Sleep(kernel, timeout));
} else if (yield_type == Svc::YieldType::WithoutCoreMigration) {
KScheduler::YieldWithoutCoreMigration(kernel);
} else if (yield_type == Svc::YieldType::WithCoreMigration) {
@@ -144,27 +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<KThread>(thread_handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(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();
@@ -175,8 +170,7 @@ Result GetThreadPriority(Core::System& system, s32* out_priority, Handle handle)
LOG_TRACE(Kernel_SVC, "called");
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Get the thread's priority.
@@ -195,11 +189,11 @@ Result SetThreadPriority(Core::System& system, Handle thread_handle, s32 priorit
R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority);
// Get the thread from its handle.
KScopedAutoObject thread = process.GetHandleTable().GetObject<KThread>(thread_handle);
KScopedAutoObject thread = process.GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Set the thread priority.
thread->SetBasePriority(priority);
thread->SetBasePriority(system.Kernel(), priority);
R_SUCCEED();
}
@@ -248,12 +242,11 @@ Result GetThreadCoreMask(Core::System& system, s32* out_core_id, u64* out_affini
LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
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,18 +272,17 @@ Result SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
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.
Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
// Get the thread from its handle.
KScopedAutoObject thread =
GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(thread_handle);
KScopedAutoObject thread = GetCurrentProcess(system.Kernel()).GetHandleTable().GetObject<KThread>(system.Kernel(), thread_handle);
R_UNLESS(thread.IsNotNull(), ResultInvalidHandle);
// Get the thread's id.
@@ -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,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.
@@ -53,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();
@@ -69,7 +71,7 @@ Result CreateTransferMemory(Core::System& system, Handle* out, u64 address, u64
KTransferMemory::Register(kernel, trmem);
// Add the transfer memory to the handle table.
R_RETURN(handle_table.Add(out, trmem));
R_RETURN(handle_table.Add(system.Kernel(), out, trmem));
}
Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t address, uint64_t size,
@@ -86,7 +88,7 @@ Result MapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t add
// Get the transfer memory.
KScopedAutoObject trmem = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KTransferMemory>(trmem_handle);
.GetObject<KTransferMemory>(system.Kernel(), trmem_handle);
R_UNLESS(trmem.IsNotNull(), ResultInvalidHandle);
// Verify that the mapping is in range.
@@ -96,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();
@@ -113,7 +115,7 @@ Result UnmapTransferMemory(Core::System& system, Handle trmem_handle, uint64_t a
// Get the transfer memory.
KScopedAutoObject trmem = GetCurrentProcess(system.Kernel())
.GetHandleTable()
.GetObject<KTransferMemory>(trmem_handle);
.GetObject<KTransferMemory>(system.Kernel(), trmem_handle);
R_UNLESS(trmem.IsNotNull(), ResultInvalidHandle);
// Verify that the mapping is in range.
@@ -123,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();
}