From 4238754d8c3fd97153b2ade89477c0a2c39682a5 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 17 Oct 2018 13:47:42 -0400 Subject: [PATCH 1/9] kernel/process: move next_process_id to kernel instance --- src/core/hle/kernel/kernel.cpp | 3 --- src/core/hle/kernel/kernel.h | 4 ++++ src/core/hle/kernel/process.cpp | 3 +-- src/core/hle/kernel/process.h | 4 +--- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ba7223db4..306dc6cdd 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -23,9 +23,6 @@ KernelSystem::KernelSystem(u32 system_mode) { resource_limits = std::make_unique(*this); Kernel::ThreadingInit(); Kernel::TimersInit(); - // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are - // reserved for low-level services - Process::next_process_id = 10; } /// Shutdown the kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 98a5d14a2..015fbe87f 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -183,6 +183,10 @@ public: private: std::unique_ptr resource_limits; std::atomic next_object_id{0}; + + // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are + // reserved for low-level services + u32 next_process_id = 10; }; } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index ae799d15f..7f089a4c4 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -32,8 +32,6 @@ SharedPtr KernelSystem::CreateCodeSet(std::string name, u64 program_id) CodeSet::CodeSet(KernelSystem& kernel) : Object(kernel) {} CodeSet::~CodeSet() {} -u32 Process::next_process_id; - SharedPtr KernelSystem::CreateProcess(SharedPtr code_set) { SharedPtr process(new Process(*this)); @@ -41,6 +39,7 @@ SharedPtr KernelSystem::CreateProcess(SharedPtr code_set) { process->flags.raw = 0; process->flags.memory_region.Assign(MemoryRegion::APPLICATION); process->status = ProcessStatus::Created; + process->process_id = ++next_process_id; process_list.push_back(process); return process; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index a141dff4c..70be04ff5 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -123,8 +123,6 @@ public: return HANDLE_TYPE; } - static u32 next_process_id; - SharedPtr codeset; /// Resource limit descriptor for this process SharedPtr resource_limit; @@ -145,7 +143,7 @@ public: ProcessStatus status; /// The id of this process - u32 process_id = next_process_id++; + u32 process_id; /** * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them From d9342622b031f6ce9721e9560971769f2dd941ec Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 17 Oct 2018 14:06:47 -0400 Subject: [PATCH 2/9] kennel/process: move process list to kernel instance --- src/core/hle/kernel/kernel.h | 7 +++++++ src/core/hle/kernel/process.cpp | 9 +-------- src/core/hle/kernel/process.h | 5 ----- src/core/hle/kernel/thread.cpp | 1 - src/core/hle/service/fs/fs_user.cpp | 2 +- 5 files changed, 9 insertions(+), 15 deletions(-) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 015fbe87f..d3907a382 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include "common/common_types.h" #include "core/hle/result.h" @@ -180,6 +181,9 @@ public: u32 GenerateObjectID(); + /// Retrieves a process from the current list of processes. + SharedPtr GetProcessById(u32 process_id) const; + private: std::unique_ptr resource_limits; std::atomic next_object_id{0}; @@ -187,6 +191,9 @@ private: // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are // reserved for low-level services u32 next_process_id = 10; + + // Lists all processes that exist in the current session. + std::vector> process_list; }; } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 7f089a4c4..23a4684a6 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -17,9 +17,6 @@ namespace Kernel { -// Lists all processes that exist in the current session. -static std::vector> process_list; - SharedPtr KernelSystem::CreateCodeSet(std::string name, u64 program_id) { SharedPtr codeset(new CodeSet(*this)); @@ -306,11 +303,7 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} Kernel::Process::~Process() {} -void ClearProcessList() { - process_list.clear(); -} - -SharedPtr GetProcessById(u32 process_id) { +SharedPtr KernelSystem::GetProcessById(u32 process_id) const { auto itr = std::find_if( process_list.begin(), process_list.end(), [&](const SharedPtr& process) { return process->process_id == process_id; }); diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 70be04ff5..89ce9bf8a 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -198,10 +198,5 @@ private: KernelSystem& kernel; }; -void ClearProcessList(); - -/// Retrieves a process from the current list of processes. -SharedPtr GetProcessById(u32 process_id); - extern SharedPtr g_current_process; } // namespace Kernel diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 6844e76d5..99d9df133 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -516,7 +516,6 @@ void ThreadingShutdown() { } thread_list.clear(); ready_queue.clear(); - ClearProcessList(); } const std::vector>& GetThreadList() { diff --git a/src/core/hle/service/fs/fs_user.cpp b/src/core/hle/service/fs/fs_user.cpp index 7b1316e48..f9b883fe7 100644 --- a/src/core/hle/service/fs/fs_user.cpp +++ b/src/core/hle/service/fs/fs_user.cpp @@ -619,7 +619,7 @@ void FS_USER::GetProgramLaunchInfo(Kernel::HLERequestContext& ctx) { // TODO(Subv): The real FS service manages its own process list and only checks the processes // that were registered with the 'fs:REG' service. - auto process = Kernel::GetProcessById(process_id); + auto process = system.Kernel().GetProcessById(process_id); IPC::RequestBuilder rb = rp.MakeBuilder(5, 0); From 8fb3d8ff38907ddb28526a66a04505c0cefe9b58 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Wed, 17 Oct 2018 15:23:56 -0400 Subject: [PATCH 3/9] kernel/process: move current process to kernel instance Two functional change: QueryProcessMemory uses the process passed from handle instead current_process Thread::Stop() uses TLS from owner_process instead of current_process --- src/core/core.cpp | 6 ++- src/core/core.h | 3 ++ src/core/file_sys/archive_savedata.cpp | 10 +++-- src/core/file_sys/archive_selfncch.cpp | 3 +- src/core/hle/kernel/handle_table.cpp | 5 ++- src/core/hle/kernel/kernel.cpp | 9 ++++- src/core/hle/kernel/kernel.h | 5 +++ src/core/hle/kernel/process.cpp | 2 - src/core/hle/kernel/process.h | 2 - src/core/hle/kernel/shared_memory.cpp | 4 +- src/core/hle/kernel/svc.cpp | 45 ++++++++++++--------- src/core/hle/kernel/thread.cpp | 8 ++-- src/core/hle/service/apt/applet_manager.cpp | 2 +- src/core/hle/service/cecd/cecd.cpp | 4 +- src/core/hle/service/cecd/cecd.h | 2 + src/core/hle/service/service.cpp | 9 +++-- src/core/memory.cpp | 20 +++++---- src/tests/core/arm/arm_test_common.cpp | 10 +++-- src/tests/core/arm/arm_test_common.h | 2 +- 19 files changed, 96 insertions(+), 55 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 4d4379299..910083644 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -126,7 +126,9 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file return init_result; } - const Loader::ResultStatus load_result{app_loader->Load(Kernel::g_current_process)}; + Kernel::SharedPtr process; + const Loader::ResultStatus load_result{app_loader->Load(process)}; + kernel->SetCurrentProcess(process); if (Loader::ResultStatus::Success != load_result) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast(load_result)); System::Shutdown(); @@ -140,7 +142,7 @@ System::ResultStatus System::Load(EmuWindow& emu_window, const std::string& file return ResultStatus::ErrorLoader; } } - Memory::SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table); + Memory::SetCurrentPageTable(&kernel->GetCurrentProcess()->vm_manager.page_table); status = ResultStatus::Success; m_emu_window = &emu_window; m_filepath = filepath; diff --git a/src/core/core.h b/src/core/core.h index 9341f79a4..ea986f433 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -251,8 +251,11 @@ private: std::unique_ptr archive_manager; +public: // HACK: this is temporary exposed for tests, + // due to WIP kernel refactor causing desync state in memory std::unique_ptr kernel; +private: static System s_instance; ResultStatus status = ResultStatus::Success; diff --git a/src/core/file_sys/archive_savedata.cpp b/src/core/file_sys/archive_savedata.cpp index d551f590f..6e518af8b 100644 --- a/src/core/file_sys/archive_savedata.cpp +++ b/src/core/file_sys/archive_savedata.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include "core/core.h" #include "core/file_sys/archive_savedata.h" #include "core/hle/kernel/process.h" @@ -16,16 +17,19 @@ ArchiveFactory_SaveData::ArchiveFactory_SaveData( : sd_savedata_source(std::move(sd_savedata)) {} ResultVal> ArchiveFactory_SaveData::Open(const Path& path) { - return sd_savedata_source->Open(Kernel::g_current_process->codeset->program_id); + return sd_savedata_source->Open( + Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); } ResultCode ArchiveFactory_SaveData::Format(const Path& path, const FileSys::ArchiveFormatInfo& format_info) { - return sd_savedata_source->Format(Kernel::g_current_process->codeset->program_id, format_info); + return sd_savedata_source->Format( + Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id, format_info); } ResultVal ArchiveFactory_SaveData::GetFormatInfo(const Path& path) const { - return sd_savedata_source->GetFormatInfo(Kernel::g_current_process->codeset->program_id); + return sd_savedata_source->GetFormatInfo( + Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id); } } // namespace FileSys diff --git a/src/core/file_sys/archive_selfncch.cpp b/src/core/file_sys/archive_selfncch.cpp index 14be1f966..dc2c61666 100644 --- a/src/core/file_sys/archive_selfncch.cpp +++ b/src/core/file_sys/archive_selfncch.cpp @@ -7,6 +7,7 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "common/swap.h" +#include "core/core.h" #include "core/file_sys/archive_selfncch.h" #include "core/file_sys/errors.h" #include "core/file_sys/ivfc_archive.h" @@ -279,7 +280,7 @@ void ArchiveFactory_SelfNCCH::Register(Loader::AppLoader& app_loader) { ResultVal> ArchiveFactory_SelfNCCH::Open(const Path& path) { auto archive = std::make_unique( - ncch_data[Kernel::g_current_process->codeset->program_id]); + ncch_data[Core::System::GetInstance().Kernel().GetCurrentProcess()->codeset->program_id]); return MakeResult>(std::move(archive)); } diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index a0805a752..99b65fa93 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -5,6 +5,7 @@ #include #include "common/assert.h" #include "common/logging/log.h" +#include "core/core.h" // TODO: for current_process. Remove this later #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/process.h" @@ -76,7 +77,9 @@ SharedPtr HandleTable::GetGeneric(Handle handle) const { if (handle == CurrentThread) { return GetCurrentThread(); } else if (handle == CurrentProcess) { - return g_current_process; + // TODO: should this return HandleTable's parent process, or kernel's current process? + // Should change this either way + return Core::System::GetInstance().Kernel().GetCurrentProcess(); } if (!IsValid(handle)) { diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 306dc6cdd..bed63ff91 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -30,7 +30,6 @@ KernelSystem::~KernelSystem() { g_handle_table.Clear(); // Free all kernel objects Kernel::ThreadingShutdown(); - g_current_process = nullptr; Kernel::TimersShutdown(); Kernel::MemoryShutdown(); @@ -48,4 +47,12 @@ u32 KernelSystem::GenerateObjectID() { return next_object_id++; } +SharedPtr KernelSystem::GetCurrentProcess() const { + return current_process; +} + +void KernelSystem::SetCurrentProcess(SharedPtr process) { + current_process = std::move(process); +} + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index d3907a382..d461dc6e8 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -184,6 +184,9 @@ public: /// Retrieves a process from the current list of processes. SharedPtr GetProcessById(u32 process_id) const; + SharedPtr GetCurrentProcess() const; + void SetCurrentProcess(SharedPtr process); + private: std::unique_ptr resource_limits; std::atomic next_object_id{0}; @@ -194,6 +197,8 @@ private: // Lists all processes that exist in the current session. std::vector> process_list; + + SharedPtr current_process; }; } // namespace Kernel diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 23a4684a6..c6be6effc 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -313,6 +313,4 @@ SharedPtr KernelSystem::GetProcessById(u32 process_id) const { return *itr; } - -SharedPtr g_current_process; } // namespace Kernel diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 89ce9bf8a..762e0c0a1 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -197,6 +197,4 @@ private: friend class KernelSystem; KernelSystem& kernel; }; - -extern SharedPtr g_current_process; } // namespace Kernel diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 35bd53003..70a937222 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -52,8 +52,8 @@ SharedPtr KernelSystem::CreateSharedMemory(SharedPtr owne } // Refresh the address mappings for the current process. - if (Kernel::g_current_process != nullptr) { - Kernel::g_current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); + if (current_process != nullptr) { + current_process->vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); } } else { auto& vm_manager = shared_memory->owner_process->vm_manager; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index c2eeb786f..b27ee5293 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -83,7 +83,7 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add } VMAPermission vma_permissions = (VMAPermission)permissions; - auto& process = *g_current_process; + auto& process = *Core::System::GetInstance().Kernel().GetCurrentProcess(); switch (operation & MEMOP_OPERATION_MASK) { case MEMOP_FREE: { @@ -145,16 +145,17 @@ static ResultCode ControlMemory(u32* out_addr, u32 operation, u32 addr0, u32 add } static void ExitProcess() { - LOG_INFO(Kernel_SVC, "Process {} exiting", g_current_process->process_id); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + LOG_INFO(Kernel_SVC, "Process {} exiting", current_process->process_id); - ASSERT_MSG(g_current_process->status == ProcessStatus::Running, "Process has already exited"); + ASSERT_MSG(current_process->status == ProcessStatus::Running, "Process has already exited"); - g_current_process->status = ProcessStatus::Exited; + current_process->status = ProcessStatus::Exited; // Stop all the process threads that are currently waiting for objects. auto& thread_list = GetThreadList(); for (auto& thread : thread_list) { - if (thread->owner_process != g_current_process) + if (thread->owner_process != current_process) continue; if (thread == GetCurrentThread()) @@ -195,7 +196,8 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o case MemoryPermission::WriteExecute: case MemoryPermission::ReadWriteExecute: case MemoryPermission::DontCare: - return shared_memory->Map(g_current_process.get(), addr, permissions_type, + return shared_memory->Map(Core::System::GetInstance().Kernel().GetCurrentProcess().get(), + addr, permissions_type, static_cast(other_permissions)); default: LOG_ERROR(Kernel_SVC, "unknown permissions=0x{:08X}", permissions); @@ -213,7 +215,8 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { if (shared_memory == nullptr) return ERR_INVALID_HANDLE; - return shared_memory->Unmap(g_current_process.get(), addr); + return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(), + addr); } /// Connect to an OS service given the port name, returns the handle to the port to out @@ -733,14 +736,16 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point return ERR_OUT_OF_RANGE; } - SharedPtr& resource_limit = g_current_process->resource_limit; + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + + SharedPtr& resource_limit = current_process->resource_limit; if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) { return ERR_NOT_AUTHORIZED; } if (processor_id == ThreadProcessorIdDefault) { // Set the target CPU to the one specified in the process' exheader. - processor_id = g_current_process->ideal_processor; + processor_id = current_process->ideal_processor; ASSERT(processor_id != ThreadProcessorIdDefault); } @@ -761,9 +766,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point break; } - CASCADE_RESULT(SharedPtr thread, Core::System::GetInstance().Kernel().CreateThread( - name, entry_point, priority, arg, processor_id, - stack_top, g_current_process)); + CASCADE_RESULT(SharedPtr thread, + Core::System::GetInstance().Kernel().CreateThread( + name, entry_point, priority, arg, processor_id, stack_top, current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 @@ -810,7 +815,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { // Note: The kernel uses the current process's resource limit instead of // the one from the thread owner's resource limit. - SharedPtr& resource_limit = g_current_process->resource_limit; + SharedPtr& resource_limit = + Core::System::GetInstance().Kernel().GetCurrentProcess()->resource_limit; if (resource_limit->GetMaxResourceValue(ResourceTypes::PRIORITY) > priority) { return ERR_NOT_AUTHORIZED; } @@ -1097,16 +1103,18 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 return ERR_INVALID_ADDRESS; } + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + // When trying to create a memory block with address = 0, // if the process has the Shared Device Memory flag in the exheader, // then we have to allocate from the same region as the caller process instead of the BASE // region. MemoryRegion region = MemoryRegion::BASE; - if (addr == 0 && g_current_process->flags.shared_device_mem) - region = g_current_process->flags.memory_region; + if (addr == 0 && current_process->flags.shared_device_mem) + region = current_process->flags.memory_region; shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( - g_current_process, size, static_cast(my_permission), + current_process, size, static_cast(my_permission), static_cast(other_permission), addr, region); CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory))); @@ -1407,8 +1415,9 @@ void CallSVC(u32 immediate) { // Lock the global kernel mutex when we enter the kernel HLE. std::lock_guard lock(HLE::g_hle_lock); - ASSERT_MSG(g_current_process->status == ProcessStatus::Running, - "Running threads from exiting processes is unimplemented"); + DEBUG_ASSERT_MSG(Core::System::GetInstance().Kernel().GetCurrentProcess()->status == + ProcessStatus::Running, + "Running threads from exiting processes is unimplemented"); const FunctionDef* info = GetSVCInfo(immediate); if (info) { diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 99d9df133..bc4aba38b 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -96,7 +96,7 @@ void Thread::Stop() { u32 tls_page = (tls_address - Memory::TLS_AREA_VADDR) / Memory::PAGE_SIZE; u32 tls_slot = ((tls_address - Memory::TLS_AREA_VADDR) % Memory::PAGE_SIZE) / Memory::TLS_ENTRY_SIZE; - Kernel::g_current_process->tls_slots[tls_page].reset(tls_slot); + owner_process->tls_slots[tls_page].reset(tls_slot); } /** @@ -127,7 +127,7 @@ static void SwitchContext(Thread* new_thread) { // Cancel any outstanding wakeup events for this thread CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); - auto previous_process = Kernel::g_current_process; + auto previous_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); current_thread = new_thread; @@ -135,8 +135,8 @@ static void SwitchContext(Thread* new_thread) { new_thread->status = ThreadStatus::Running; if (previous_process != current_thread->owner_process) { - Kernel::g_current_process = current_thread->owner_process; - SetCurrentPageTable(&Kernel::g_current_process->vm_manager.page_table); + Core::System::GetInstance().Kernel().SetCurrentProcess(current_thread->owner_process); + SetCurrentPageTable(¤t_thread->owner_process->vm_manager.page_table); } Core::CPU().LoadContext(new_thread->context); diff --git a/src/core/hle/service/apt/applet_manager.cpp b/src/core/hle/service/apt/applet_manager.cpp index bc02c5eb6..076f5f6cf 100644 --- a/src/core/hle/service/apt/applet_manager.cpp +++ b/src/core/hle/service/apt/applet_manager.cpp @@ -258,7 +258,7 @@ ResultVal AppletManager::Initialize(AppletId ap slot_data->applet_id = static_cast(app_id); // Note: In the real console the title id of a given applet slot is set by the APT module when // calling StartApplication. - slot_data->title_id = Kernel::g_current_process->codeset->program_id; + slot_data->title_id = system.Kernel().GetCurrentProcess()->codeset->program_id; slot_data->attributes.raw = attributes.raw; if (slot_data->applet_id == AppletId::Application || diff --git a/src/core/hle/service/cecd/cecd.cpp b/src/core/hle/service/cecd/cecd.cpp index f2759e7fc..df217d76e 100644 --- a/src/core/hle/service/cecd/cecd.cpp +++ b/src/core/hle/service/cecd/cecd.cpp @@ -97,7 +97,7 @@ void Module::Interface::Open(Kernel::HLERequestContext& ctx) { if (path_type == CecDataPathType::MboxProgramId) { std::vector program_id(8); - u64_le le_program_id = Kernel::g_current_process->codeset->program_id; + u64_le le_program_id = cecd->system.Kernel().GetCurrentProcess()->codeset->program_id; std::memcpy(program_id.data(), &le_program_id, sizeof(u64)); session_data->file->Write(0, sizeof(u64), true, program_id.data()); session_data->file->Close(); @@ -1351,7 +1351,7 @@ Module::SessionData::~SessionData() { Module::Interface::Interface(std::shared_ptr cecd, const char* name, u32 max_session) : ServiceFramework(name, max_session), cecd(std::move(cecd)) {} -Module::Module(Core::System& system) { +Module::Module(Core::System& system) : system(system) { using namespace Kernel; cecinfo_event = system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "CECD::cecinfo_event"); change_state_event = diff --git a/src/core/hle/service/cecd/cecd.h b/src/core/hle/service/cecd/cecd.h index 3102bc318..d8023f5cf 100644 --- a/src/core/hle/service/cecd/cecd.h +++ b/src/core/hle/service/cecd/cecd.h @@ -610,6 +610,8 @@ private: Kernel::SharedPtr cecinfo_event; Kernel::SharedPtr change_state_event; + + Core::System& system; }; /// Initialize CECD service(s) diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 6bdafd0e8..117bf2b2c 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -188,11 +188,13 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses return ReportUnimplementedFunction(cmd_buf, info); } + Kernel::SharedPtr current_process = + Core::System::GetInstance().Kernel().GetCurrentProcess(); + // TODO(yuriks): The kernel should be the one handling this as part of translation after // everything else is migrated Kernel::HLERequestContext context(std::move(server_session)); - context.PopulateFromIncomingCommandBuffer(cmd_buf, *Kernel::g_current_process, - Kernel::g_handle_table); + context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf)); handler_invoker(this, info->handler_callback, context); @@ -204,8 +206,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses // the thread to sleep then the writing of the command buffer will be deferred to the wakeup // callback. if (thread->status == Kernel::ThreadStatus::Running) { - context.WriteToOutgoingCommandBuffer(cmd_buf, *Kernel::g_current_process, - Kernel::g_handle_table); + context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); } } diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 52252c932..f109c752f 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -111,7 +111,7 @@ static u8* GetPointerFromVMA(const Kernel::Process& process, VAddr vaddr) { * using a VMA from the current process. */ static u8* GetPointerFromVMA(VAddr vaddr) { - return GetPointerFromVMA(*Kernel::g_current_process, vaddr); + return GetPointerFromVMA(*Core::System::GetInstance().Kernel().GetCurrentProcess(), vaddr); } /** @@ -128,7 +128,8 @@ static MMIORegionPointer GetMMIOHandler(const PageTable& page_table, VAddr vaddr } static MMIORegionPointer GetMMIOHandler(VAddr vaddr) { - const PageTable& page_table = Kernel::g_current_process->vm_manager.page_table; + const PageTable& page_table = + Core::System::GetInstance().Kernel().GetCurrentProcess()->vm_manager.page_table; return GetMMIOHandler(page_table, vaddr); } @@ -229,7 +230,7 @@ bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) { } bool IsValidVirtualAddress(const VAddr vaddr) { - return IsValidVirtualAddress(*Kernel::g_current_process, vaddr); + return IsValidVirtualAddress(*Core::System::GetInstance().Kernel().GetCurrentProcess(), vaddr); } bool IsValidPhysicalAddress(const PAddr paddr) { @@ -524,7 +525,8 @@ void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_ } void ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_t size) { - ReadBlock(*Kernel::g_current_process, src_addr, dest_buffer, size); + ReadBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), src_addr, dest_buffer, + size); } void Write8(const VAddr addr, const u8 data) { @@ -592,7 +594,8 @@ void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const voi } void WriteBlock(const VAddr dest_addr, const void* src_buffer, const std::size_t size) { - WriteBlock(*Kernel::g_current_process, dest_addr, src_buffer, size); + WriteBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, src_buffer, + size); } void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { @@ -644,7 +647,7 @@ void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std: } void ZeroBlock(const VAddr dest_addr, const std::size_t size) { - ZeroBlock(*Kernel::g_current_process, dest_addr, size); + ZeroBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, size); } void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, @@ -699,7 +702,7 @@ void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, } void CopyBlock(VAddr dest_addr, VAddr src_addr, const std::size_t size) { - CopyBlock(*Kernel::g_current_process, dest_addr, src_addr, size); + CopyBlock(*Core::System::GetInstance().Kernel().GetCurrentProcess(), dest_addr, src_addr, size); } template <> @@ -778,7 +781,8 @@ std::optional PhysicalToVirtualAddress(const PAddr addr) { } else if (addr >= VRAM_PADDR && addr < VRAM_PADDR_END) { return addr - VRAM_PADDR + VRAM_VADDR; } else if (addr >= FCRAM_PADDR && addr < FCRAM_PADDR_END) { - return addr - FCRAM_PADDR + Kernel::g_current_process->GetLinearHeapAreaAddress(); + return addr - FCRAM_PADDR + + Core::System::GetInstance().Kernel().GetCurrentProcess()->GetLinearHeapAreaAddress(); } else if (addr >= DSP_RAM_PADDR && addr < DSP_RAM_PADDR_END) { return addr - DSP_RAM_PADDR + DSP_RAM_VADDR; } else if (addr >= IO_AREA_PADDR && addr < IO_AREA_PADDR_END) { diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp index 4706c2512..1127a504f 100644 --- a/src/tests/core/arm/arm_test_common.cpp +++ b/src/tests/core/arm/arm_test_common.cpp @@ -17,10 +17,14 @@ TestEnvironment::TestEnvironment(bool mutable_memory_) : mutable_memory(mutable_memory_), test_memory(std::make_shared(this)) { CoreTiming::Init(); - kernel = std::make_unique(0); + // HACK: some memory functions are currently referring kernel from the global instance, + // so we need to create the kernel object there. + // Change this when all global states are eliminated. + Core::System::GetInstance().kernel = std::make_unique(0); + kernel = Core::System::GetInstance().kernel.get(); - Kernel::g_current_process = kernel->CreateProcess(kernel->CreateCodeSet("", 0)); - page_table = &Kernel::g_current_process->vm_manager.page_table; + kernel->SetCurrentProcess(kernel->CreateProcess(kernel->CreateCodeSet("", 0))); + page_table = &kernel->GetCurrentProcess()->vm_manager.page_table; page_table->pointers.fill(nullptr); page_table->attributes.fill(Memory::PageType::Unmapped); diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h index 4f396416f..b52d26e3c 100644 --- a/src/tests/core/arm/arm_test_common.h +++ b/src/tests/core/arm/arm_test_common.h @@ -80,7 +80,7 @@ private: std::shared_ptr test_memory; std::vector write_records; - std::unique_ptr kernel; + Kernel::KernelSystem* kernel; }; } // namespace ArmTests From 5b45a3e1b57d9636c5ef7e2a954820f9c88a78b7 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Thu, 18 Oct 2018 21:40:22 -0400 Subject: [PATCH 4/9] Kernel/Timer: use unordered_map for callback recording --- src/core/hle/kernel/timer.cpp | 31 ++++++++++++++++++------------- src/core/hle/kernel/timer.h | 4 ++-- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index 8ef96e058..d9d89abd0 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp @@ -3,6 +3,7 @@ // Refer to the license.txt file included. #include +#include #include "common/assert.h" #include "common/logging/log.h" #include "core/core_timing.h" @@ -15,12 +16,15 @@ namespace Kernel { /// The event type of the generic timer callback event static CoreTiming::EventType* timer_callback_event_type = nullptr; -// TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing -// us to simply use a pool index or similar. -static Kernel::HandleTable timer_callback_handle_table; + +static u64 next_timer_callback_id; +static std::unordered_map timer_callback_table; Timer::Timer(KernelSystem& kernel) : WaitObject(kernel) {} -Timer::~Timer() {} +Timer::~Timer() { + Cancel(); + timer_callback_table.erase(callback_id); +} SharedPtr KernelSystem::CreateTimer(ResetType reset_type, std::string name) { SharedPtr timer(new Timer(*this)); @@ -30,7 +34,8 @@ SharedPtr KernelSystem::CreateTimer(ResetType reset_type, std::string nam timer->name = std::move(name); timer->initial_delay = 0; timer->interval_delay = 0; - timer->callback_handle = timer_callback_handle_table.Create(timer).Unwrap(); + timer->callback_id = ++next_timer_callback_id; + timer_callback_table[timer->callback_id] = timer.get(); return timer; } @@ -57,12 +62,12 @@ void Timer::Set(s64 initial, s64 interval) { // Immediately invoke the callback Signal(0); } else { - CoreTiming::ScheduleEvent(nsToCycles(initial), timer_callback_event_type, callback_handle); + CoreTiming::ScheduleEvent(nsToCycles(initial), timer_callback_event_type, callback_id); } } void Timer::Cancel() { - CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_handle); + CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_id); } void Timer::Clear() { @@ -87,17 +92,16 @@ void Timer::Signal(s64 cycles_late) { if (interval_delay != 0) { // Reschedule the timer with the interval delay CoreTiming::ScheduleEvent(nsToCycles(interval_delay) - cycles_late, - timer_callback_event_type, callback_handle); + timer_callback_event_type, callback_id); } } /// The timer callback event, called when a timer is fired -static void TimerCallback(u64 timer_handle, s64 cycles_late) { - SharedPtr timer = - timer_callback_handle_table.Get(static_cast(timer_handle)); +static void TimerCallback(u64 callback_id, s64 cycles_late) { + SharedPtr timer = timer_callback_table.at(callback_id); if (timer == nullptr) { - LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:08x}", timer_handle); + LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016x}", callback_id); return; } @@ -105,7 +109,8 @@ static void TimerCallback(u64 timer_handle, s64 cycles_late) { } void TimersInit() { - timer_callback_handle_table.Clear(); + next_timer_callback_id = 0; + timer_callback_table.clear(); timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); } diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index c039bb4f1..653dacb5b 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h @@ -71,8 +71,8 @@ private: bool signaled; ///< Whether the timer has been signaled or not std::string name; ///< Name of timer (optional) - /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. - Handle callback_handle; + /// ID used as userdata to reference this object when inserting into the CoreTiming queue. + u64 callback_id; friend class KernelSystem; }; From fda2a5cf5492ca7db730636cf47e918b84c2b4bb Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Thu, 18 Oct 2018 22:19:29 -0400 Subject: [PATCH 5/9] kernel/thread: use std::unordered_map for callback record --- src/core/hle/kernel/thread.cpp | 25 ++++++++++++------------- src/core/hle/kernel/thread.h | 3 --- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index bc4aba38b..220e6aa17 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include "common/assert.h" #include "common/common_types.h" @@ -37,9 +38,8 @@ void Thread::Acquire(Thread* thread) { ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); } -// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing -// us to simply use a pool index or similar. -static Kernel::HandleTable wakeup_callback_handle_table; +static u64 next_callback_id; +static std::unordered_map wakeup_callback_table; // Lists all thread ids that aren't deleted/etc. static std::vector> thread_list; @@ -69,9 +69,8 @@ Thread* GetCurrentThread() { void Thread::Stop() { // Cancel any outstanding wakeup events for this thread - CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); - wakeup_callback_handle_table.Close(callback_handle); - callback_handle = 0; + CoreTiming::UnscheduleEvent(ThreadWakeupEventType, thread_id); + wakeup_callback_table.erase(thread_id); // Clean up thread from ready queue // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) @@ -125,7 +124,7 @@ static void SwitchContext(Thread* new_thread) { "Thread must be ready to become running."); // Cancel any outstanding wakeup events for this thread - CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->callback_handle); + CoreTiming::UnscheduleEvent(ThreadWakeupEventType, new_thread->thread_id); auto previous_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); @@ -185,13 +184,13 @@ void ExitCurrentThread() { /** * Callback that will wake up the thread it was scheduled for - * @param thread_handle The handle of the thread that's been awoken + * @param thread_id The ID of the thread that's been awoken * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time */ -static void ThreadWakeupCallback(u64 thread_handle, s64 cycles_late) { - SharedPtr thread = wakeup_callback_handle_table.Get((Handle)thread_handle); +static void ThreadWakeupCallback(u64 thread_id, s64 cycles_late) { + SharedPtr thread = wakeup_callback_table.at(thread_id); if (thread == nullptr) { - LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", (Handle)thread_handle); + LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", thread_id); return; } @@ -217,7 +216,7 @@ void Thread::WakeAfterDelay(s64 nanoseconds) { if (nanoseconds == -1) return; - CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), ThreadWakeupEventType, callback_handle); + CoreTiming::ScheduleEvent(nsToCycles(nanoseconds), ThreadWakeupEventType, thread_id); } void Thread::ResumeFromWait() { @@ -359,7 +358,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr thread->wait_objects.clear(); thread->wait_address = 0; thread->name = std::move(name); - thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); + wakeup_callback_table[thread->thread_id] = thread.get(); thread->owner_process = owner_process; // Find the next available TLS index, and mark it as used diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index 9e6a22759..bb0ab5b15 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -199,9 +199,6 @@ public: std::string name; - /// Handle used as userdata to reference this object when inserting into the CoreTiming queue. - Handle callback_handle; - using WakeupCallback = void(ThreadWakeupReason reason, SharedPtr thread, SharedPtr object); // Callback that will be invoked when the thread is resumed from a waiting state. If the thread From eb285c33fd2751b8f03afb5b8e207cfa6e4b17cc Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 19 Oct 2018 21:04:18 -0400 Subject: [PATCH 6/9] kernel: make handle table per-process --- src/core/hle/kernel/handle_table.cpp | 9 +- src/core/hle/kernel/handle_table.h | 6 +- src/core/hle/kernel/hle_ipc.cpp | 15 ++- src/core/hle/kernel/hle_ipc.h | 6 +- src/core/hle/kernel/ipc.cpp | 6 +- src/core/hle/kernel/kernel.cpp | 2 - src/core/hle/kernel/process.cpp | 3 +- src/core/hle/kernel/process.h | 3 + src/core/hle/kernel/svc.cpp | 167 +++++++++++++++++--------- src/core/hle/service/service.cpp | 4 +- src/tests/core/hle/kernel/hle_ipc.cpp | 67 ++++++----- 11 files changed, 169 insertions(+), 119 deletions(-) diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 99b65fa93..87ba03f36 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -5,7 +5,6 @@ #include #include "common/assert.h" #include "common/logging/log.h" -#include "core/core.h" // TODO: for current_process. Remove this later #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/process.h" @@ -13,9 +12,7 @@ namespace Kernel { -HandleTable g_handle_table; - -HandleTable::HandleTable() { +HandleTable::HandleTable(KernelSystem& kernel) : kernel(kernel) { next_generation = 1; Clear(); } @@ -77,9 +74,7 @@ SharedPtr HandleTable::GetGeneric(Handle handle) const { if (handle == CurrentThread) { return GetCurrentThread(); } else if (handle == CurrentProcess) { - // TODO: should this return HandleTable's parent process, or kernel's current process? - // Should change this either way - return Core::System::GetInstance().Kernel().GetCurrentProcess(); + return kernel.GetCurrentProcess(); } if (!IsValid(handle)) { diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index 5497dd74a..00cb47a33 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -42,7 +42,7 @@ enum KernelHandle : Handle { */ class HandleTable final : NonCopyable { public: - HandleTable(); + explicit HandleTable(KernelSystem& kernel); /** * Allocates a handle for the given object. @@ -119,8 +119,8 @@ private: /// Head of the free slots linked list. u16 next_free_slot; + + KernelSystem& kernel; }; -extern HandleTable g_handle_table; - } // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 1da7c8a81..a72d33dd9 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -50,7 +50,7 @@ SharedPtr HLERequestContext::SleepClientThread(SharedPtr thread, std::array cmd_buff; Memory::ReadBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); - context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process, Kernel::g_handle_table); + context.WriteToOutgoingCommandBuffer(cmd_buff.data(), *process); // Copy the translated command buffer back into the thread's command buffer area. Memory::WriteBlock(*process, thread->GetCommandBufferAddress(), cmd_buff.data(), cmd_buff.size() * sizeof(u32)); @@ -98,8 +98,7 @@ void HLERequestContext::AddStaticBuffer(u8 buffer_id, std::vector data) { } ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, - Process& src_process, - HandleTable& src_table) { + Process& src_process) { IPC::Header header{src_cmdbuf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -122,10 +121,10 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr Handle handle = src_cmdbuf[i]; SharedPtr object = nullptr; if (handle != 0) { - object = src_table.GetGeneric(handle); + object = src_process.handle_table.GetGeneric(handle); ASSERT(object != nullptr); // TODO(yuriks): Return error if (descriptor == IPC::DescriptorType::MoveHandle) { - src_table.Close(handle); + src_process.handle_table.Close(handle); } } @@ -163,8 +162,8 @@ ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const u32_le* sr return RESULT_SUCCESS; } -ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, - HandleTable& dst_table) const { +ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, + Process& dst_process) const { IPC::Header header{cmd_buf[0]}; std::size_t untranslated_size = 1u + header.normal_params_size; @@ -189,7 +188,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P Handle handle = 0; if (object != nullptr) { // TODO(yuriks): Figure out the proper error handling for if this fails - handle = dst_table.Create(object).Unwrap(); + handle = dst_process.handle_table.Create(object).Unwrap(); } dst_cmdbuf[i++] = handle; } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 3a2b81b16..a41264834 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -226,11 +226,9 @@ public: MappedBuffer& GetMappedBuffer(u32 id_from_cmdbuf); /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process, - HandleTable& src_table); + ResultCode PopulateFromIncomingCommandBuffer(const u32_le* src_cmdbuf, Process& src_process); /// Writes data from this context back to the requesting process/thread. - ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process, - HandleTable& dst_table) const; + ResultCode WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, Process& dst_process) const; private: std::array cmd_buf; diff --git a/src/core/hle/kernel/ipc.cpp b/src/core/hle/kernel/ipc.cpp index 8db9d241f..b50a2429f 100644 --- a/src/core/hle/kernel/ipc.cpp +++ b/src/core/hle/kernel/ipc.cpp @@ -60,9 +60,9 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtrhandle_table.GetGeneric(handle); if (descriptor == IPC::DescriptorType::MoveHandle) { - g_handle_table.Close(handle); + src_process->handle_table.Close(handle); } } @@ -73,7 +73,7 @@ ResultCode TranslateCommandBuffer(SharedPtr src_thread, SharedPtrhandle_table.Create(std::move(object)); cmd_buf[i++] = result.ValueOr(0); } break; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index bed63ff91..afe6af195 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -27,8 +27,6 @@ KernelSystem::KernelSystem(u32 system_mode) { /// Shutdown the kernel KernelSystem::~KernelSystem() { - g_handle_table.Clear(); // Free all kernel objects - Kernel::ThreadingShutdown(); Kernel::TimersShutdown(); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index c6be6effc..21204eeb8 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -300,7 +300,8 @@ ResultCode Process::LinearFree(VAddr target, u32 size) { return RESULT_SUCCESS; } -Kernel::Process::Process(KernelSystem& kernel) : Object(kernel), kernel(kernel) {} +Kernel::Process::Process(KernelSystem& kernel) + : Object(kernel), handle_table(kernel), kernel(kernel) {} Kernel::Process::~Process() {} SharedPtr KernelSystem::GetProcessById(u32 process_id) const { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 762e0c0a1..fa04d8c42 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -13,6 +13,7 @@ #include #include "common/bit_field.h" #include "common/common_types.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/vm_manager.h" @@ -123,6 +124,8 @@ public: return HANDLE_TYPE; } + HandleTable handle_table; + SharedPtr codeset; /// Resource limit descriptor for this process SharedPtr resource_limit; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b27ee5293..94a820f34 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -182,7 +182,9 @@ static ResultCode MapMemoryBlock(Handle handle, u32 addr, u32 permissions, u32 o "otherpermission={}", handle, addr, permissions, other_permissions); - SharedPtr shared_memory = g_handle_table.Get(handle); + SharedPtr shared_memory = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (shared_memory == nullptr) return ERR_INVALID_HANDLE; @@ -211,12 +213,12 @@ static ResultCode UnmapMemoryBlock(Handle handle, u32 addr) { // TODO(Subv): Return E0A01BF5 if the address is not in the application's heap - SharedPtr shared_memory = g_handle_table.Get(handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr shared_memory = current_process->handle_table.Get(handle); if (shared_memory == nullptr) return ERR_INVALID_HANDLE; - return shared_memory->Unmap(Core::System::GetInstance().Kernel().GetCurrentProcess().get(), - addr); + return shared_memory->Unmap(current_process.get(), addr); } /// Connect to an OS service given the port name, returns the handle to the port to out @@ -244,13 +246,17 @@ static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) { CASCADE_RESULT(client_session, client_port->Connect()); // Return the client session - CASCADE_RESULT(*out_handle, g_handle_table.Create(client_session)); + CASCADE_RESULT(*out_handle, + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Create( + client_session)); return RESULT_SUCCESS; } /// Makes a blocking IPC call to an OS service. static ResultCode SendSyncRequest(Handle handle) { - SharedPtr session = g_handle_table.Get(handle); + SharedPtr session = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (session == nullptr) { return ERR_INVALID_HANDLE; } @@ -265,12 +271,14 @@ static ResultCode SendSyncRequest(Handle handle) { /// Close a handle static ResultCode CloseHandle(Handle handle) { LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); - return g_handle_table.Close(handle); + return Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Close(handle); } /// Wait for a handle to synchronize, timeout after the specified nanoseconds static ResultCode WaitSynchronization1(Handle handle, s64 nano_seconds) { - auto object = g_handle_table.Get(handle); + auto object = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); Thread* thread = GetCurrentThread(); if (object == nullptr) @@ -341,7 +349,9 @@ static ResultCode WaitSynchronizationN(s32* out, VAddr handles_address, s32 hand for (int i = 0; i < handle_count; ++i) { Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); - auto object = g_handle_table.Get(handle); + auto object = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; @@ -505,9 +515,11 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ using ObjectPtr = SharedPtr; std::vector objects(handle_count); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + for (int i = 0; i < handle_count; ++i) { Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); - auto object = g_handle_table.Get(handle); + auto object = current_process->handle_table.Get(handle); if (object == nullptr) return ERR_INVALID_HANDLE; objects[i] = object; @@ -518,7 +530,7 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ u32* cmd_buff = GetCommandBuffer(); IPC::Header header{cmd_buff[0]}; if (reply_target != 0 && header.command_id != 0xFFFF) { - auto session = g_handle_table.Get(reply_target); + auto session = current_process->handle_table.Get(reply_target); if (session == nullptr) return ERR_INVALID_HANDLE; @@ -618,8 +630,10 @@ static ResultCode ReplyAndReceive(s32* index, VAddr handles_address, s32 handle_ /// Create an address arbiter (to allocate access to shared resources) static ResultCode CreateAddressArbiter(Handle* out_handle) { - SharedPtr arbiter = Core::System::GetInstance().Kernel().CreateAddressArbiter(); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(arbiter))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr arbiter = kernel.CreateAddressArbiter(); + CASCADE_RESULT(*out_handle, + kernel.GetCurrentProcess()->handle_table.Create(std::move(arbiter))); LOG_TRACE(Kernel_SVC, "returned handle=0x{:08X}", *out_handle); return RESULT_SUCCESS; } @@ -630,7 +644,9 @@ static ResultCode ArbitrateAddress(Handle handle, u32 address, u32 type, u32 val LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}, address=0x{:08X}, type=0x{:08X}, value=0x{:08X}", handle, address, type, value); - SharedPtr arbiter = g_handle_table.Get(handle); + SharedPtr arbiter = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (arbiter == nullptr) return ERR_INVALID_HANDLE; @@ -678,11 +694,12 @@ static void OutputDebugString(VAddr address, int len) { static ResultCode GetResourceLimit(Handle* resource_limit, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr process = current_process->handle_table.Get(process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; - CASCADE_RESULT(*resource_limit, g_handle_table.Create(process->resource_limit)); + CASCADE_RESULT(*resource_limit, current_process->handle_table.Create(process->resource_limit)); return RESULT_SUCCESS; } @@ -694,7 +711,8 @@ static ResultCode GetResourceLimitCurrentValues(VAddr values, Handle resource_li resource_limit_handle, names, name_count); SharedPtr resource_limit = - g_handle_table.Get(resource_limit_handle); + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -714,7 +732,8 @@ static ResultCode GetResourceLimitLimitValues(VAddr values, Handle resource_limi resource_limit_handle, names, name_count); SharedPtr resource_limit = - g_handle_table.Get(resource_limit_handle); + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + resource_limit_handle); if (resource_limit == nullptr) return ERR_INVALID_HANDLE; @@ -773,7 +792,7 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(thread))); + CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(thread))); Core::System::GetInstance().PrepareReschedule(); @@ -795,7 +814,8 @@ static void ExitThread() { /// Gets the priority for the specified thread static ResultCode GetThreadPriority(u32* priority, Handle handle) { - const SharedPtr thread = g_handle_table.Get(handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -809,7 +829,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { return ERR_OUT_OF_RANGE; } - SharedPtr thread = g_handle_table.Get(handle); + SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -834,9 +855,10 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) { /// Create a mutex static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { - SharedPtr mutex = Core::System::GetInstance().Kernel().CreateMutex(initial_locked != 0); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr mutex = kernel.CreateMutex(initial_locked != 0); mutex->name = fmt::format("mutex-{:08x}", Core::CPU().GetReg(14)); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(mutex))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(mutex))); LOG_TRACE(Kernel_SVC, "called initial_locked={} : created handle=0x{:08X}", initial_locked ? "true" : "false", *out_handle); @@ -848,7 +870,8 @@ static ResultCode CreateMutex(Handle* out_handle, u32 initial_locked) { static ResultCode ReleaseMutex(Handle handle) { LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}", handle); - SharedPtr mutex = g_handle_table.Get(handle); + SharedPtr mutex = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (mutex == nullptr) return ERR_INVALID_HANDLE; @@ -859,7 +882,9 @@ static ResultCode ReleaseMutex(Handle handle) { static ResultCode GetProcessId(u32* process_id, Handle process_handle) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); - const SharedPtr process = g_handle_table.Get(process_handle); + const SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -871,7 +896,9 @@ static ResultCode GetProcessId(u32* process_id, Handle process_handle) { static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); - const SharedPtr thread = g_handle_table.Get(thread_handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + thread_handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -887,7 +914,8 @@ static ResultCode GetProcessIdOfThread(u32* process_id, Handle thread_handle) { static ResultCode GetThreadId(u32* thread_id, Handle handle) { LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", handle); - const SharedPtr thread = g_handle_table.Get(handle); + const SharedPtr thread = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (thread == nullptr) return ERR_INVALID_HANDLE; @@ -897,10 +925,12 @@ static ResultCode GetThreadId(u32* thread_id, Handle handle) { /// Creates a semaphore static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max_count) { + KernelSystem& kernel = Core::System::GetInstance().Kernel(); CASCADE_RESULT(SharedPtr semaphore, - Core::System::GetInstance().Kernel().CreateSemaphore(initial_count, max_count)); + kernel.CreateSemaphore(initial_count, max_count)); semaphore->name = fmt::format("semaphore-{:08x}", Core::CPU().GetReg(14)); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(semaphore))); + CASCADE_RESULT(*out_handle, + kernel.GetCurrentProcess()->handle_table.Create(std::move(semaphore))); LOG_TRACE(Kernel_SVC, "called initial_count={}, max_count={}, created handle=0x{:08X}", initial_count, max_count, *out_handle); @@ -911,7 +941,9 @@ static ResultCode CreateSemaphore(Handle* out_handle, s32 initial_count, s32 max static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) { LOG_TRACE(Kernel_SVC, "called release_count={}, handle=0x{:08X}", release_count, handle); - SharedPtr semaphore = g_handle_table.Get(handle); + SharedPtr semaphore = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + handle); if (semaphore == nullptr) return ERR_INVALID_HANDLE; @@ -923,7 +955,9 @@ static ResultCode ReleaseSemaphore(s32* count, Handle handle, s32 release_count) /// Query process memory static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* page_info, Handle process_handle, u32 addr) { - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; @@ -949,9 +983,10 @@ static ResultCode QueryMemory(MemoryInfo* memory_info, PageInfo* page_info, u32 /// Create an event static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { - SharedPtr evt = Core::System::GetInstance().Kernel().CreateEvent( - static_cast(reset_type), fmt::format("event-{:08x}", Core::CPU().GetReg(14))); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(evt))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr evt = kernel.CreateEvent(static_cast(reset_type), + fmt::format("event-{:08x}", Core::CPU().GetReg(14))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(evt))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, *out_handle); @@ -960,7 +995,9 @@ static ResultCode CreateEvent(Handle* out_handle, u32 reset_type) { /// Duplicates a kernel handle static ResultCode DuplicateHandle(Handle* out, Handle handle) { - CASCADE_RESULT(*out, g_handle_table.Duplicate(handle)); + CASCADE_RESULT( + *out, + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Duplicate(handle)); LOG_TRACE(Kernel_SVC, "duplicated 0x{:08X} to 0x{:08X}", handle, *out); return RESULT_SUCCESS; } @@ -969,7 +1006,8 @@ static ResultCode DuplicateHandle(Handle* out, Handle handle) { static ResultCode SignalEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle); - SharedPtr evt = g_handle_table.Get(handle); + SharedPtr evt = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -982,7 +1020,8 @@ static ResultCode SignalEvent(Handle handle) { static ResultCode ClearEvent(Handle handle) { LOG_TRACE(Kernel_SVC, "called event=0x{:08X}", handle); - SharedPtr evt = g_handle_table.Get(handle); + SharedPtr evt = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (evt == nullptr) return ERR_INVALID_HANDLE; @@ -992,9 +1031,10 @@ static ResultCode ClearEvent(Handle handle) { /// Creates a timer static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { - SharedPtr timer = Core::System::GetInstance().Kernel().CreateTimer( + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr timer = kernel.CreateTimer( static_cast(reset_type), fmt ::format("timer-{:08x}", Core::CPU().GetReg(14))); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(timer))); + CASCADE_RESULT(*out_handle, kernel.GetCurrentProcess()->handle_table.Create(std::move(timer))); LOG_TRACE(Kernel_SVC, "called reset_type=0x{:08X} : created handle=0x{:08X}", reset_type, *out_handle); @@ -1005,7 +1045,8 @@ static ResultCode CreateTimer(Handle* out_handle, u32 reset_type) { static ResultCode ClearTimer(Handle handle) { LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle); - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1021,7 +1062,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { return ERR_OUT_OF_RANGE_KERNEL; } - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1034,7 +1076,8 @@ static ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { static ResultCode CancelTimer(Handle handle) { LOG_TRACE(Kernel_SVC, "called timer=0x{:08X}", handle); - SharedPtr timer = g_handle_table.Get(handle); + SharedPtr timer = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get(handle); if (timer == nullptr) return ERR_INVALID_HANDLE; @@ -1116,7 +1159,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( current_process, size, static_cast(my_permission), static_cast(other_permission), addr, region); - CASCADE_RESULT(*out_handle, g_handle_table.Create(std::move(shared_memory))); + CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); LOG_WARNING(Kernel_SVC, "called addr=0x{:08X}", addr); return RESULT_SUCCESS; @@ -1127,48 +1170,58 @@ static ResultCode CreatePort(Handle* server_port, Handle* client_port, VAddr nam // TODO(Subv): Implement named ports. ASSERT_MSG(name_address == 0, "Named ports are currently unimplemented"); - auto ports = Core::System::GetInstance().Kernel().CreatePortPair(max_sessions); - CASCADE_RESULT(*client_port, - g_handle_table.Create(std::move(std::get>(ports)))); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + SharedPtr current_process = kernel.GetCurrentProcess(); + + auto ports = kernel.CreatePortPair(max_sessions); + CASCADE_RESULT(*client_port, current_process->handle_table.Create( + std::move(std::get>(ports)))); // Note: The 3DS kernel also leaks the client port handle if the server port handle fails to be // created. - CASCADE_RESULT(*server_port, - g_handle_table.Create(std::move(std::get>(ports)))); + CASCADE_RESULT(*server_port, current_process->handle_table.Create( + std::move(std::get>(ports)))); LOG_TRACE(Kernel_SVC, "called max_sessions={}", max_sessions); return RESULT_SUCCESS; } static ResultCode CreateSessionToPort(Handle* out_client_session, Handle client_port_handle) { - SharedPtr client_port = g_handle_table.Get(client_port_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr client_port = + current_process->handle_table.Get(client_port_handle); if (client_port == nullptr) return ERR_INVALID_HANDLE; CASCADE_RESULT(auto session, client_port->Connect()); - CASCADE_RESULT(*out_client_session, g_handle_table.Create(std::move(session))); + CASCADE_RESULT(*out_client_session, current_process->handle_table.Create(std::move(session))); return RESULT_SUCCESS; } static ResultCode CreateSession(Handle* server_session, Handle* client_session) { - auto sessions = Core::System::GetInstance().Kernel().CreateSessionPair(); + KernelSystem& kernel = Core::System::GetInstance().Kernel(); + auto sessions = kernel.CreateSessionPair(); + + SharedPtr current_process = kernel.GetCurrentProcess(); auto& server = std::get>(sessions); - CASCADE_RESULT(*server_session, g_handle_table.Create(std::move(server))); + CASCADE_RESULT(*server_session, current_process->handle_table.Create(std::move(server))); auto& client = std::get>(sessions); - CASCADE_RESULT(*client_session, g_handle_table.Create(std::move(client))); + CASCADE_RESULT(*client_session, current_process->handle_table.Create(std::move(client))); LOG_TRACE(Kernel_SVC, "called"); return RESULT_SUCCESS; } static ResultCode AcceptSession(Handle* out_server_session, Handle server_port_handle) { - SharedPtr server_port = g_handle_table.Get(server_port_handle); + SharedPtr current_process = Core::System::GetInstance().Kernel().GetCurrentProcess(); + SharedPtr server_port = + current_process->handle_table.Get(server_port_handle); if (server_port == nullptr) return ERR_INVALID_HANDLE; CASCADE_RESULT(auto session, server_port->Accept()); - CASCADE_RESULT(*out_server_session, g_handle_table.Create(std::move(session))); + CASCADE_RESULT(*out_server_session, current_process->handle_table.Create(std::move(session))); return RESULT_SUCCESS; } @@ -1218,7 +1271,9 @@ static ResultCode GetSystemInfo(s64* out, u32 type, s32 param) { static ResultCode GetProcessInfo(s64* out, Handle process_handle, u32 type) { LOG_TRACE(Kernel_SVC, "called process=0x{:08X} type={}", process_handle, type); - SharedPtr process = g_handle_table.Get(process_handle); + SharedPtr process = + Core::System::GetInstance().Kernel().GetCurrentProcess()->handle_table.Get( + process_handle); if (process == nullptr) return ERR_INVALID_HANDLE; diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 117bf2b2c..1217376b1 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -194,7 +194,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses // TODO(yuriks): The kernel should be the one handling this as part of translation after // everything else is migrated Kernel::HLERequestContext context(std::move(server_session)); - context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); + context.PopulateFromIncomingCommandBuffer(cmd_buf, *current_process); LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName().c_str(), cmd_buf)); handler_invoker(this, info->handler_callback, context); @@ -206,7 +206,7 @@ void ServiceFrameworkBase::HandleSyncRequest(SharedPtr server_ses // the thread to sleep then the writing of the command buffer will be deferred to the wakeup // callback. if (thread->status == Kernel::ThreadStatus::Running) { - context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process, Kernel::g_handle_table); + context.WriteToOutgoingCommandBuffer(cmd_buf, *current_process); } } diff --git a/src/tests/core/hle/kernel/hle_ipc.cpp b/src/tests/core/hle/kernel/hle_ipc.cpp index 9e093f4e4..068d767b6 100644 --- a/src/tests/core/hle/kernel/hle_ipc.cpp +++ b/src/tests/core/hle/kernel/hle_ipc.cpp @@ -26,14 +26,13 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); - HandleTable handle_table; SECTION("works with empty cmdbuf") { const u32_le input[]{ IPC::MakeHeader(0x1234, 0, 0), }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(context.CommandBuffer()[0] == 0x12340000); } @@ -46,7 +45,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0xAABBCCDD, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(output[1] == 0x12345678); @@ -56,34 +55,34 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel SECTION("translates move handles") { auto a = MakeObject(kernel); - Handle a_handle = handle_table.Create(a).Unwrap(); + Handle a_handle = process->handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), IPC::MoveHandleDesc(1), a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); - REQUIRE(handle_table.GetGeneric(a_handle) == nullptr); + REQUIRE(process->handle_table.GetGeneric(a_handle) == nullptr); } SECTION("translates copy handles") { auto a = MakeObject(kernel); - Handle a_handle = handle_table.Create(a).Unwrap(); + Handle a_handle = process->handle_table.Create(a).Unwrap(); const u32_le input[]{ IPC::MakeHeader(0, 0, 2), IPC::CopyHandleDesc(1), a_handle, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); - REQUIRE(handle_table.GetGeneric(a_handle) == a); + REQUIRE(process->handle_table.GetGeneric(a_handle) == a); } SECTION("translates multi-handle descriptors") { @@ -91,12 +90,15 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel auto b = MakeObject(kernel); auto c = MakeObject(kernel); const u32_le input[]{ - IPC::MakeHeader(0, 0, 5), IPC::MoveHandleDesc(2), - handle_table.Create(a).Unwrap(), handle_table.Create(b).Unwrap(), - IPC::MoveHandleDesc(1), handle_table.Create(c).Unwrap(), + IPC::MakeHeader(0, 0, 5), + IPC::MoveHandleDesc(2), + process->handle_table.Create(a).Unwrap(), + process->handle_table.Create(b).Unwrap(), + IPC::MoveHandleDesc(1), + process->handle_table.Create(c).Unwrap(), }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); REQUIRE(context.GetIncomingHandle(output[2]) == a); @@ -111,7 +113,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0, }; - auto result = context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + auto result = context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(result == RESULT_SUCCESS); auto* output = context.CommandBuffer(); @@ -125,7 +127,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x98989898, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); REQUIRE(context.CommandBuffer()[2] == process->process_id); } @@ -145,7 +147,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); CHECK(context.GetStaticBuffer(0) == *buffer); @@ -166,7 +168,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); std::vector other_buffer(buffer->size()); context.GetMappedBuffer(0).Read(other_buffer.data(), 0, buffer->size()); @@ -199,7 +201,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel 0x12345678, 0xABCDEF00, IPC::MoveHandleDesc(1), - handle_table.Create(a).Unwrap(), + process->handle_table.Create(a).Unwrap(), IPC::CallingPidDesc(), 0, IPC::StaticBufferDesc(buffer_static->size(), 0), @@ -208,7 +210,7 @@ TEST_CASE("HLERequestContext::PopulateFromIncomingCommandBuffer", "[core][kernel target_address_mapped, }; - context.PopulateFromIncomingCommandBuffer(input, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input, *process); auto* output = context.CommandBuffer(); CHECK(output[1] == 0x12345678); @@ -236,14 +238,13 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { HLERequestContext context(std::move(session)); auto process = kernel.CreateProcess(kernel.CreateCodeSet("", 0)); - HandleTable handle_table; auto* input = context.CommandBuffer(); u32_le output[IPC::COMMAND_BUFFER_LENGTH]; SECTION("works with empty cmdbuf") { input[0] = IPC::MakeHeader(0x1234, 0, 0); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(output[0] == 0x12340000); } @@ -254,7 +255,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[2] = 0x21122112; input[3] = 0xAABBCCDD; - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(output[1] == 0x12345678); REQUIRE(output[2] == 0x21122112); @@ -270,10 +271,10 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[3] = IPC::CopyHandleDesc(1); input[4] = context.AddOutgoingHandle(b); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); - REQUIRE(handle_table.GetGeneric(output[2]) == a); - REQUIRE(handle_table.GetGeneric(output[4]) == b); + REQUIRE(process->handle_table.GetGeneric(output[2]) == a); + REQUIRE(process->handle_table.GetGeneric(output[4]) == b); } SECTION("translates null handles") { @@ -281,7 +282,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[1] = IPC::MoveHandleDesc(1); input[2] = context.AddOutgoingHandle(nullptr); - auto result = context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + auto result = context.WriteToOutgoingCommandBuffer(output, *process); REQUIRE(result == RESULT_SUCCESS); REQUIRE(output[2] == 0); @@ -298,11 +299,11 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[4] = IPC::CopyHandleDesc(1); input[5] = context.AddOutgoingHandle(c); - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); - REQUIRE(handle_table.GetGeneric(output[2]) == a); - REQUIRE(handle_table.GetGeneric(output[3]) == b); - REQUIRE(handle_table.GetGeneric(output[5]) == c); + REQUIRE(process->handle_table.GetGeneric(output[2]) == a); + REQUIRE(process->handle_table.GetGeneric(output[3]) == b); + REQUIRE(process->handle_table.GetGeneric(output[5]) == c); } SECTION("translates StaticBuffer descriptors") { @@ -329,7 +330,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { IPC::StaticBufferDesc(output_buffer->size(), 0); output_cmdbuff[IPC::COMMAND_BUFFER_LENGTH + 1] = target_address; - context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process, handle_table); + context.WriteToOutgoingCommandBuffer(output_cmdbuff.data(), *process); CHECK(*output_buffer == input_buffer); REQUIRE(process->vm_manager.UnmapRange(target_address, output_buffer->size()) == @@ -352,7 +353,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { target_address, }; - context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process, handle_table); + context.PopulateFromIncomingCommandBuffer(input_cmdbuff, *process); context.GetMappedBuffer(0).Write(input_buffer.data(), 0, input_buffer.size()); @@ -360,7 +361,7 @@ TEST_CASE("HLERequestContext::WriteToOutgoingCommandBuffer", "[core][kernel]") { input[1] = IPC::MappedBufferDesc(output_buffer->size(), IPC::W); input[2] = 0; - context.WriteToOutgoingCommandBuffer(output, *process, handle_table); + context.WriteToOutgoingCommandBuffer(output, *process); CHECK(output[1] == IPC::MappedBufferDesc(output_buffer->size(), IPC::W)); CHECK(output[2] == target_address); From 8d32843d68907de5cdbe438eb917faf25259f123 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Tue, 23 Oct 2018 10:06:32 -0400 Subject: [PATCH 7/9] thread/kernel: remove unused callback_id we use the thread id for the same purpose now --- src/core/hle/kernel/thread.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 220e6aa17..69680acf8 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -38,7 +38,6 @@ void Thread::Acquire(Thread* thread) { ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); } -static u64 next_callback_id; static std::unordered_map wakeup_callback_table; // Lists all thread ids that aren't deleted/etc. From e5c5d1eccee6dbeb4d2e20dd3d1a80e8f0b4ce26 Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Thu, 25 Oct 2018 19:54:06 -0400 Subject: [PATCH 8/9] Kernel: change owner_process in Thread/SharedMemory to raw pointer Otherwise circular ownership would form in Process->handle_table->thread->owner_process --- src/core/hle/kernel/kernel.h | 4 ++-- src/core/hle/kernel/shared_memory.cpp | 2 +- src/core/hle/kernel/shared_memory.h | 2 +- src/core/hle/kernel/svc.cpp | 8 ++++---- src/core/hle/kernel/thread.cpp | 5 ++--- src/core/hle/kernel/thread.h | 2 +- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index d461dc6e8..223b3ce37 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -102,7 +102,7 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, VAddr stack_top, - SharedPtr owner_process); + Process* owner_process); /** * Creates a semaphore. @@ -156,7 +156,7 @@ public: * linear heap. * @param name Optional object name, used for debugging purposes. */ - SharedPtr CreateSharedMemory(SharedPtr owner_process, u32 size, + SharedPtr CreateSharedMemory(Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address = 0, diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp index 70a937222..4f0b2e8ee 100644 --- a/src/core/hle/kernel/shared_memory.cpp +++ b/src/core/hle/kernel/shared_memory.cpp @@ -14,7 +14,7 @@ namespace Kernel { SharedMemory::SharedMemory(KernelSystem& kernel) : Object(kernel) {} SharedMemory::~SharedMemory() {} -SharedPtr KernelSystem::CreateSharedMemory(SharedPtr owner_process, u32 size, +SharedPtr KernelSystem::CreateSharedMemory(Process* owner_process, u32 size, MemoryPermission permissions, MemoryPermission other_permissions, VAddr address, MemoryRegion region, diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h index d5d862927..18a87b9fe 100644 --- a/src/core/hle/kernel/shared_memory.h +++ b/src/core/hle/kernel/shared_memory.h @@ -58,7 +58,7 @@ public: u8* GetPointer(u32 offset = 0); /// Process that created this shared memory block. - SharedPtr owner_process; + Process* owner_process; /// Address of shared memory block in the owner process if specified. VAddr base_address; /// Physical address of the shared memory block in the linear heap if no address was specified diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 94a820f34..0e7a21c0a 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -785,9 +785,9 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point break; } - CASCADE_RESULT(SharedPtr thread, - Core::System::GetInstance().Kernel().CreateThread( - name, entry_point, priority, arg, processor_id, stack_top, current_process)); + CASCADE_RESULT(SharedPtr thread, Core::System::GetInstance().Kernel().CreateThread( + name, entry_point, priority, arg, processor_id, + stack_top, current_process.get())); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 @@ -1157,7 +1157,7 @@ static ResultCode CreateMemoryBlock(Handle* out_handle, u32 addr, u32 size, u32 region = current_process->flags.memory_region; shared_memory = Core::System::GetInstance().Kernel().CreateSharedMemory( - current_process, size, static_cast(my_permission), + current_process.get(), size, static_cast(my_permission), static_cast(other_permission), addr, region); CASCADE_RESULT(*out_handle, current_process->handle_table.Create(std::move(shared_memory))); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 69680acf8..11ea54fbd 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -320,8 +320,7 @@ static void ResetThreadContext(const std::unique_ptr> KernelSystem::CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, - SharedPtr owner_process) { + VAddr stack_top, Process* owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -447,7 +446,7 @@ SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 pri // Initialize new "main" thread auto thread_res = kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, owner_process); + Memory::HEAP_VADDR_END, owner_process.get()); SharedPtr thread = std::move(thread_res).Unwrap(); diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h index bb0ab5b15..9c7dd45cc 100644 --- a/src/core/hle/kernel/thread.h +++ b/src/core/hle/kernel/thread.h @@ -189,7 +189,7 @@ public: /// Mutexes that this thread is currently waiting for. boost::container::flat_set> pending_mutexes; - SharedPtr owner_process; ///< Process that owns this thread + Process* owner_process; ///< Process that owns this thread /// Objects that the thread is waiting on, in the same order as they were // passed to WaitSynchronization1/N. From 8ad6cbfde2bcd59ad1571eb06085b37ca67e5bde Mon Sep 17 00:00:00 2001 From: Weiyi Wang Date: Fri, 26 Oct 2018 09:37:46 -0400 Subject: [PATCH 9/9] kernel/thread: change owner_process parameter to reference To enforce a valid process object --- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/svc.cpp | 2 +- src/core/hle/kernel/thread.cpp | 14 +++++++------- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 223b3ce37..344635c6a 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -102,7 +102,7 @@ public: */ ResultVal> CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, VAddr stack_top, - Process* owner_process); + Process& owner_process); /** * Creates a semaphore. diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 0e7a21c0a..6a33736ba 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -787,7 +787,7 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point CASCADE_RESULT(SharedPtr thread, Core::System::GetInstance().Kernel().CreateThread( name, entry_point, priority, arg, processor_id, - stack_top, current_process.get())); + stack_top, *current_process)); thread->context->SetFpscr(FPSCR_DEFAULT_NAN | FPSCR_FLUSH_TO_ZERO | FPSCR_ROUND_TOZERO); // 0x03C00000 diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 11ea54fbd..a7b6eba1e 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -320,7 +320,7 @@ static void ResetThreadContext(const std::unique_ptr> KernelSystem::CreateThread(std::string name, VAddr entry_point, u32 priority, u32 arg, s32 processor_id, - VAddr stack_top, Process* owner_process) { + VAddr stack_top, Process& owner_process) { // Check if priority is in ranged. Lowest priority -> highest priority id. if (priority > ThreadPrioLowest) { LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); @@ -334,7 +334,7 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr // TODO(yuriks): Other checks, returning 0xD9001BEA - if (!Memory::IsValidVirtualAddress(*owner_process, entry_point)) { + if (!Memory::IsValidVirtualAddress(owner_process, entry_point)) { LOG_ERROR(Kernel_SVC, "(name={}): invalid entry {:08x}", name, entry_point); // TODO: Verify error return ResultCode(ErrorDescription::InvalidAddress, ErrorModule::Kernel, @@ -357,10 +357,10 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr thread->wait_address = 0; thread->name = std::move(name); wakeup_callback_table[thread->thread_id] = thread.get(); - thread->owner_process = owner_process; + thread->owner_process = &owner_process; // Find the next available TLS index, and mark it as used - auto& tls_slots = owner_process->tls_slots; + auto& tls_slots = owner_process.tls_slots; auto [available_page, available_slot, needs_allocation] = GetFreeThreadLocalSlot(tls_slots); @@ -381,13 +381,13 @@ ResultVal> KernelSystem::CreateThread(std::string name, VAddr // Allocate some memory from the end of the linear heap for this region. linheap_memory->insert(linheap_memory->end(), Memory::PAGE_SIZE, 0); memory_region->used += Memory::PAGE_SIZE; - owner_process->linear_heap_used += Memory::PAGE_SIZE; + owner_process.linear_heap_used += Memory::PAGE_SIZE; tls_slots.emplace_back(0); // The page is completely available at the start available_page = tls_slots.size() - 1; available_slot = 0; // Use the first slot in the new page - auto& vm_manager = owner_process->vm_manager; + auto& vm_manager = owner_process.vm_manager; vm_manager.RefreshMemoryBlockMappings(linheap_memory.get()); // Map the page to the current process' address space. @@ -446,7 +446,7 @@ SharedPtr SetupMainThread(KernelSystem& kernel, u32 entry_point, u32 pri // Initialize new "main" thread auto thread_res = kernel.CreateThread("main", entry_point, priority, 0, owner_process->ideal_processor, - Memory::HEAP_VADDR_END, owner_process.get()); + Memory::HEAP_VADDR_END, *owner_process); SharedPtr thread = std::move(thread_res).Unwrap();