From da7e9553dea4b1eaefb71aca8642ccce7c7f50fb Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 3 Apr 2021 19:11:46 -0700 Subject: hle: kernel: Migrate more of KThread to KAutoObject. --- src/yuzu/debugger/wait_tree.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 3bca6277b..ef0ab0960 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -91,7 +91,7 @@ std::size_t WaitTreeItem::Row() const { std::vector> WaitTreeItem::MakeThreadItemList() { std::vector> item_list; std::size_t row = 0; - auto add_threads = [&](const std::vector>& threads) { + auto add_threads = [&](const std::vector& threads) { for (std::size_t i = 0; i < threads.size(); ++i) { if (threads[i]->GetThreadTypeForDebugging() == Kernel::ThreadType::User) { item_list.push_back(std::make_unique(*threads[i])); @@ -183,10 +183,12 @@ bool WaitTreeExpandableItem::IsExpandable() const { } QString WaitTreeSynchronizationObject::GetText() const { - return tr("[%1]%2 %3") - .arg(object.GetObjectId()) - .arg(QString::fromStdString(object.GetTypeName()), - QString::fromStdString(object.GetName())); + // return tr("[%1]%2 %3") + // .arg(object.GetObjectId()) + // .arg(QString::fromStdString(object.GetTypeName()), + // QString::fromStdString(object.GetName())); + + return tr("UNIMPLEMENTED"); } std::unique_ptr WaitTreeSynchronizationObject::make( -- cgit v1.2.3 From 7ccbdd4d8d3dea7294d2cac38779cceea9745d52 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 3 Apr 2021 22:22:36 -0700 Subject: hle: kernel: Migrate KProcess to KAutoObject. --- src/core/core.cpp | 9 +++++--- src/core/hle/kernel/handle_table.cpp | 10 ++++---- src/core/hle/kernel/handle_table.h | 4 ++-- src/core/hle/kernel/init/init_slab_setup.cpp | 9 +++++--- src/core/hle/kernel/init/init_slab_setup.h | 2 +- src/core/hle/kernel/k_synchronization_object.h | 5 ++-- src/core/hle/kernel/kernel.cpp | 8 +++---- src/core/hle/kernel/kernel.h | 4 ++-- src/core/hle/kernel/object.h | 4 ++-- src/core/hle/kernel/process.cpp | 31 ++++++++++++++----------- src/core/hle/kernel/process.h | 32 ++++++++++++++++++-------- src/core/hle/kernel/svc.cpp | 6 ++--- src/core/hle/service/pm/pm.cpp | 12 ++++------ src/yuzu/debugger/wait_tree.cpp | 2 +- 14 files changed, 80 insertions(+), 58 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/core/core.cpp b/src/core/core.cpp index fdaa82c8f..f050a8d4b 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -233,8 +233,11 @@ struct System::Impl { } telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); - auto main_process = - Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); + auto main_process = Kernel::Process::CreateWithKernel(system.Kernel()); + ASSERT(Kernel::Process::Initialize(main_process, system, "main", + Kernel::Process::ProcessType::Userland) + .IsSuccess()); + main_process->Open(); const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); @@ -244,7 +247,7 @@ struct System::Impl { static_cast(load_result)); } AddGlueRegistrationForProcess(*app_loader, *main_process); - kernel.MakeCurrentProcess(main_process.get()); + kernel.MakeCurrentProcess(main_process); kernel.InitializeCores(); // Initialize cheat engine diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 8eec8a3b5..f746c4888 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -100,7 +100,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { } ResultVal HandleTable::Duplicate(Handle handle) { - std::shared_ptr object = GetGeneric(handle); + std::shared_ptr object = SharedFrom(GetGeneric(handle)); if (object == nullptr) { LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); return ResultInvalidHandle; @@ -140,17 +140,17 @@ bool HandleTable::IsValid(Handle handle) const { return slot < table_size && is_object_valid && generations[slot] == generation; } -std::shared_ptr HandleTable::GetGeneric(Handle handle) const { +Object* HandleTable::GetGeneric(Handle handle) const { if (handle == CurrentThread) { - return SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); + return (kernel.CurrentScheduler()->GetCurrentThread()); } else if (handle == CurrentProcess) { - return SharedFrom(kernel.CurrentProcess()); + return (kernel.CurrentProcess()); } if (!IsValid(handle)) { return nullptr; } - return objects[GetSlot(handle)]; + return objects[GetSlot(handle)].get(); } void HandleTable::Clear() { diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index 555fb20e5..24a26b81d 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -98,7 +98,7 @@ public: * Looks up a handle. * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. */ - std::shared_ptr GetGeneric(Handle handle) const; + Object* GetGeneric(Handle handle) const; /** * Looks up a handle while verifying its type. @@ -106,7 +106,7 @@ public: * type differs from the requested one. */ template - std::shared_ptr Get(Handle handle) const { + T* Get(Handle handle) const { return DynamicObjectCast(GetGeneric(handle)); } diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index a290249c7..a6fed524b 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -14,13 +14,16 @@ #include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/memory_types.h" +#include "core/hle/kernel/process.h" #include "core/memory.h" namespace Kernel::Init { #define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS -#define FOREACH_SLAB_TYPE(HANDLER, ...) HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) +#define FOREACH_SLAB_TYPE(HANDLER, ...) \ + HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ + HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) namespace { @@ -33,7 +36,7 @@ enum KSlabType : u32 { #undef DEFINE_SLAB_TYPE_ENUM_MEMBER // Constexpr counts. -constexpr size_t SlabCountKProcess = 80; +constexpr size_t SlabCountProcess = 80; constexpr size_t SlabCountKThread = 800; constexpr size_t SlabCountKEvent = 700; constexpr size_t SlabCountKInterruptEvent = 100; @@ -54,7 +57,7 @@ constexpr size_t SlabCountExtraKThread = 160; // Global to hold our resource counts. KSlabResourceCounts g_slab_resource_counts = { - .num_KProcess = SlabCountKProcess, + .num_Process = SlabCountProcess, .num_KThread = SlabCountKThread, .num_KEvent = SlabCountKEvent, .num_KInterruptEvent = SlabCountKInterruptEvent, diff --git a/src/core/hle/kernel/init/init_slab_setup.h b/src/core/hle/kernel/init/init_slab_setup.h index 6418b97ac..8876678b3 100644 --- a/src/core/hle/kernel/init/init_slab_setup.h +++ b/src/core/hle/kernel/init/init_slab_setup.h @@ -15,7 +15,7 @@ class KMemoryLayout; namespace Kernel::Init { struct KSlabResourceCounts { - size_t num_KProcess; + size_t num_Process; size_t num_KThread; size_t num_KEvent; size_t num_KInterruptEvent; diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index c8e840d89..5a99dbd46 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -53,10 +53,9 @@ private: // Specialization of DynamicObjectCast for KSynchronizationObjects template <> -inline std::shared_ptr DynamicObjectCast( - std::shared_ptr object) { +inline KSynchronizationObject* DynamicObjectCast(Object* object) { if (object != nullptr && object->IsWaitable()) { - return std::static_pointer_cast(object); + return reinterpret_cast(object); } return nullptr; } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d1359e434..1b5b11564 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -614,7 +614,7 @@ struct KernelCore::Impl { std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. - std::vector> process_list; + std::vector process_list; Process* current_process = nullptr; std::unique_ptr global_scheduler_context; Kernel::TimeManager time_manager; @@ -699,8 +699,8 @@ KScopedAutoObject KernelCore::RetrieveThreadFromGlobalHandleTable(Handl return impl->global_handle_table.GetObject(handle); } -void KernelCore::AppendNewProcess(std::shared_ptr process) { - impl->process_list.push_back(std::move(process)); +void KernelCore::AppendNewProcess(Process* process) { + impl->process_list.push_back(process); } void KernelCore::MakeCurrentProcess(Process* process) { @@ -715,7 +715,7 @@ const Process* KernelCore::CurrentProcess() const { return impl->current_process; } -const std::vector>& KernelCore::GetProcessList() const { +const std::vector& KernelCore::GetProcessList() const { return impl->process_list; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 3f5c2aec7..b78602f46 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -91,7 +91,7 @@ public: KScopedAutoObject RetrieveThreadFromGlobalHandleTable(Handle handle) const; /// Adds the given shared pointer to an internal list of active processes. - void AppendNewProcess(std::shared_ptr process); + void AppendNewProcess(Process* process); /// Makes the given process the new current process. void MakeCurrentProcess(Process* process); @@ -103,7 +103,7 @@ public: const Process* CurrentProcess() const; /// Retrieves the list of processes. - const std::vector>& GetProcessList() const; + const std::vector& GetProcessList() const; /// Gets the sole instance of the global scheduler Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h index 501e58b33..5c14aa46f 100644 --- a/src/core/hle/kernel/object.h +++ b/src/core/hle/kernel/object.h @@ -86,9 +86,9 @@ std::shared_ptr SharedFrom(T* raw) { * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. */ template -inline std::shared_ptr DynamicObjectCast(std::shared_ptr object) { +inline T* DynamicObjectCast(Object* object) { if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { - return std::static_pointer_cast(object); + return reinterpret_cast(object); } return nullptr; } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 796dca5ef..fe4558648 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -49,6 +49,8 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, // Register 1 must be a handle to the main thread Handle thread_handle{}; owner_process.GetHandleTable().Add(&thread_handle, thread); + + thread->SetName("main"); thread->GetContext32().cpu_registers[0] = 0; thread->GetContext64().cpu_registers[0] = 0; thread->GetContext32().cpu_registers[1] = thread_handle; @@ -115,10 +117,10 @@ private: std::bitset is_slot_used; }; -std::shared_ptr Process::Create(Core::System& system, std::string name, ProcessType type) { +ResultCode Process::Initialize(Process* process, Core::System& system, std::string name, + ProcessType type) { auto& kernel = system.Kernel(); - std::shared_ptr process = std::make_shared(system); process->name = std::move(name); process->resource_limit = kernel.GetSystemResourceLimit(); @@ -127,6 +129,7 @@ std::shared_ptr Process::Create(Core::System& system, std::string name, process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() : kernel.CreateNewUserProcessID(); process->capabilities.InitializeForMetadatalessProcess(); + process->is_initialized = true; std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))); std::uniform_int_distribution distribution; @@ -134,7 +137,8 @@ std::shared_ptr Process::Create(Core::System& system, std::string name, [&] { return distribution(rng); }); kernel.AppendNewProcess(process); - return process; + + return RESULT_SUCCESS; } std::shared_ptr Process::GetResourceLimit() const { @@ -332,7 +336,7 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { ChangeStatus(ProcessStatus::Running); - SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); + SetupMainThread(kernel.System(), *this, main_thread_priority, main_thread_stack_top); } void Process::PrepareForTermination() { @@ -354,7 +358,7 @@ void Process::PrepareForTermination() { } }; - stop_threads(system.GlobalSchedulerContext().GetThreadList()); + stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList()); FreeTLSRegion(tls_region_address); tls_region_address = 0; @@ -381,7 +385,7 @@ static auto FindTLSPageWithAvailableSlots(std::vector& tls_pages) { } VAddr Process::CreateTLSRegion() { - KScopedSchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(kernel); if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; tls_page_iter != tls_pages.cend()) { return *tls_page_iter->ReserveSlot(); @@ -392,7 +396,7 @@ VAddr Process::CreateTLSRegion() { const VAddr start{page_table->GetKernelMapRegionStart()}; const VAddr size{page_table->GetKernelMapRegionEnd() - start}; - const PAddr tls_map_addr{system.DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; + const PAddr tls_map_addr{kernel.System().DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; const VAddr tls_page_addr{page_table ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize, KMemoryState::ThreadLocal, @@ -412,7 +416,7 @@ VAddr Process::CreateTLSRegion() { } void Process::FreeTLSRegion(VAddr tls_address) { - KScopedSchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(kernel); const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); auto iter = std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { @@ -433,7 +437,8 @@ void Process::LoadModule(CodeSet code_set, VAddr base_addr) { page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); }; - system.Memory().WriteBlock(*this, base_addr, code_set.memory.data(), code_set.memory.size()); + kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), + code_set.memory.size()); ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute); ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read); @@ -445,10 +450,10 @@ bool Process::IsSignaled() const { return is_signaled; } -Process::Process(Core::System& system) - : KSynchronizationObject{system.Kernel()}, page_table{std::make_unique(system)}, - handle_table{system.Kernel()}, address_arbiter{system}, condition_var{system}, - state_lock{system.Kernel()}, system{system} {} +Process::Process(KernelCore& kernel) + : KAutoObjectWithSlabHeapAndContainer{kernel}, + page_table{std::make_unique(kernel.System())}, handle_table{kernel}, + address_arbiter{kernel.System()}, condition_var{kernel.System()}, state_lock{kernel} {} Process::~Process() = default; diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 45eefb90e..df3c7997d 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -13,9 +13,11 @@ #include "common/common_types.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" +#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_condition_variable.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/process_capability.h" +#include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" namespace Core { @@ -60,9 +62,11 @@ enum class ProcessStatus { DebugBreak, }; -class Process final : public KSynchronizationObject { +class Process final : public KAutoObjectWithSlabHeapAndContainer { + KERNEL_AUTOOBJECT_TRAITS(Process, KSynchronizationObject); + public: - explicit Process(Core::System& system); + explicit Process(KernelCore& kernel); ~Process() override; enum : u64 { @@ -85,8 +89,8 @@ public: static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; - static std::shared_ptr Create(Core::System& system, std::string name, - ProcessType type); + static ResultCode Initialize(Process* process, Core::System& system, std::string name, + ProcessType type); std::string GetTypeName() const override { return "Process"; @@ -338,9 +342,21 @@ public: void LoadModule(CodeSet code_set, VAddr base_addr); - bool IsSignaled() const override; + virtual bool IsInitialized() const override { + return is_initialized; + } + + static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + + virtual void Finalize() override { + UNIMPLEMENTED(); + } + + virtual u64 GetId() const override final { + return GetProcessID(); + } - void Finalize() override {} + virtual bool IsSignaled() const override; void PinCurrentThread(); void UnpinCurrentThread(); @@ -462,6 +478,7 @@ private: bool is_signaled{}; bool is_suspended{}; + bool is_initialized{}; std::atomic num_created_threads{}; std::atomic num_threads{}; @@ -474,9 +491,6 @@ private: KThread* exception_thread{}; KLightLock state_lock; - - /// System context - Core::System& system; }; } // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index dca1bcc92..7d676e5f7 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -342,7 +342,7 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, static ResultCode SendSyncRequest(Core::System& system, Handle handle) { auto& kernel = system.Kernel(); const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - std::shared_ptr session = handle_table.Get(handle); + auto session = handle_table.Get(handle); if (!session) { LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); return ResultInvalidHandle; @@ -437,7 +437,7 @@ static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr ha { auto object = handle_table.Get(handle); if (object) { - objects[i] = object.get(); + objects[i] = object; succeeded = true; } } @@ -1190,7 +1190,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add std::lock_guard lock{HLE::g_hle_lock}; LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - std::shared_ptr process = handle_table.Get(process_handle); + auto process = handle_table.Get(process_handle); if (!process) { LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", process_handle); diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index 68736c40c..3a00849e1 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp @@ -17,9 +17,8 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1}; constexpr u64 NO_PROCESS_FOUND_PID{0}; -std::optional> SearchProcessList( - const std::vector>& process_list, - std::function&)> predicate) { +std::optional SearchProcessList(const std::vector& process_list, + std::function predicate) { const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); if (iter == process_list.end()) { @@ -30,7 +29,7 @@ std::optional> SearchProcessList( } void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx, - const std::vector>& process_list) { + const std::vector& process_list) { const auto process = SearchProcessList(process_list, [](const auto& process) { return process->GetProcessID() == Kernel::Process::ProcessIDMin; }); @@ -125,8 +124,7 @@ private: class Info final : public ServiceFramework { public: - explicit Info(Core::System& system_, - const std::vector>& process_list_) + explicit Info(Core::System& system_, const std::vector& process_list_) : ServiceFramework{system_, "pm:info"}, process_list{process_list_} { static const FunctionInfo functions[] = { {0, &Info::GetTitleId, "GetTitleId"}, @@ -156,7 +154,7 @@ private: rb.Push((*process)->GetTitleID()); } - const std::vector>& process_list; + const std::vector& process_list; }; class Shell final : public ServiceFramework { diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index ef0ab0960..f4eeba2c5 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -118,7 +118,7 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa : mutex_address(mutex_address) { mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); owner_handle = static_cast(mutex_value & Kernel::Svc::HandleWaitMask); - owner = handle_table.Get(owner_handle); + owner = SharedFrom(handle_table.Get(owner_handle)); } WaitTreeMutexInfo::~WaitTreeMutexInfo() = default; -- cgit v1.2.3 From aa2844bcf9b2b9bca2ce263270b963ffd13b05e7 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 20 Apr 2021 22:18:56 -0700 Subject: hle: kernel: HandleTable: Remove deprecated APIs. --- src/core/hle/kernel/handle_table.cpp | 77 +++++------------------------------- src/core/hle/kernel/handle_table.h | 32 ++------------- src/core/hle/kernel/hle_ipc.cpp | 8 ++-- src/core/hle/kernel/hle_ipc.h | 10 ++--- src/core/hle/kernel/svc.cpp | 2 +- src/yuzu/debugger/wait_tree.cpp | 2 +- src/yuzu/debugger/wait_tree.h | 8 ++-- 7 files changed, 28 insertions(+), 111 deletions(-) (limited to 'src/yuzu/debugger') diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index 9291f0a76..cd752da4e 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -47,50 +47,6 @@ ResultCode HandleTable::SetSize(s32 handle_table_size) { return RESULT_SUCCESS; } -ResultVal HandleTable::Create(Object* obj) { - DEBUG_ASSERT(obj != nullptr); - - switch (obj->GetHandleType()) { - case HandleType::SharedMemory: - case HandleType::Thread: - case HandleType::Event: - case HandleType::Process: - case HandleType::ReadableEvent: - case HandleType::WritableEvent: - case HandleType::ClientSession: - case HandleType::ServerSession: - case HandleType::Session: - case HandleType::TransferMemory: { - Handle handle{}; - Add(&handle, reinterpret_cast(obj), {}); - return MakeResult(handle); - } - default: - break; - } - - const u16 slot = next_free_slot; - if (slot >= table_size) { - LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); - return ResultOutOfHandles; - } - next_free_slot = generations[slot]; - - const u16 generation = next_generation++; - - // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. - // Horizon OS uses zero to represent an invalid handle, so skip to 1. - if (next_generation >= (1 << 15)) { - next_generation = 1; - } - - generations[slot] = generation; - objects[slot] = std::move(SharedFrom(obj)); - - Handle handle = generation | (slot << 15); - return MakeResult(handle); -} - ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { ASSERT(obj != nullptr); @@ -110,7 +66,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { } generations[slot] = generation; - objects_new[slot] = obj; + objects[slot] = obj; obj->Open(); *out_handle = generation | (slot << 15); @@ -119,12 +75,16 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { } ResultVal HandleTable::Duplicate(Handle handle) { - auto object = GetGeneric(handle); - if (object == nullptr) { + auto object = GetObject(handle); + if (object.IsNull()) { LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); return ResultInvalidHandle; } - return Create(object); + + Handle out_handle{}; + R_TRY(Add(&out_handle, object.GetPointerUnsafe())); + + return MakeResult(out_handle); } bool HandleTable::Remove(Handle handle) { @@ -139,12 +99,7 @@ bool HandleTable::Remove(Handle handle) { objects[slot]->Close(); } - if (objects_new[slot]) { - objects_new[slot]->Close(); - } - objects[slot] = nullptr; - objects_new[slot] = nullptr; generations[slot] = next_free_slot; next_free_slot = slot; @@ -155,28 +110,14 @@ bool HandleTable::Remove(Handle handle) { bool HandleTable::IsValid(Handle handle) const { const std::size_t slot = GetSlot(handle); const u16 generation = GetGeneration(handle); - const bool is_object_valid = (objects[slot] != nullptr) || (objects_new[slot] != nullptr); + const bool is_object_valid = (objects[slot] != nullptr); return slot < table_size && is_object_valid && generations[slot] == generation; } -Object* HandleTable::GetGeneric(Handle handle) const { - if (handle == CurrentThread) { - return (kernel.CurrentScheduler()->GetCurrentThread()); - } else if (handle == CurrentProcess) { - return (kernel.CurrentProcess()); - } - - if (!IsValid(handle)) { - return nullptr; - } - return objects[GetSlot(handle)].get(); -} - void HandleTable::Clear() { for (u16 i = 0; i < table_size; ++i) { generations[i] = static_cast(i + 1); objects[i] = nullptr; - objects_new[i] = nullptr; } next_free_slot = 0; } diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index d6abdcd47..2e0b2d8b8 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -70,13 +70,6 @@ public: */ ResultCode SetSize(s32 handle_table_size); - /** - * Allocates a handle for the given object. - * @return The created Handle or one of the following errors: - * - `ERR_HANDLE_TABLE_FULL`: the maximum number of handles has been exceeded. - */ - ResultVal Create(Object* obj); - /** * Returns a new handle that points to the same object as the passed in handle. * @return The duplicated Handle or one of the following errors: @@ -95,29 +88,13 @@ public: /// Checks if a handle is valid and points to an existing object. bool IsValid(Handle handle) const; - /** - * Looks up a handle. - * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid. - */ - Object* GetGeneric(Handle handle) const; - - /** - * Looks up a handle while verifying its type. - * @return Pointer to the looked-up object, or `nullptr` if the handle is not valid or its - * type differs from the requested one. - */ - template - T* Get(Handle handle) const { - return DynamicObjectCast(GetGeneric(handle)); - } - template KAutoObject* GetObjectImpl(Handle handle) const { if (!IsValid(handle)) { return nullptr; } - auto* obj = objects_new[static_cast(handle >> 15)]; + auto* obj = objects[static_cast(handle >> 15)]; return obj->DynamicCast(); } @@ -133,7 +110,7 @@ public: return nullptr; } - auto* obj = objects_new[static_cast(handle >> 15)]; + auto* obj = objects[static_cast(handle >> 15)]; return obj->DynamicCast(); } @@ -142,7 +119,7 @@ public: if (!IsValid(handle)) { return nullptr; } - auto* obj = objects_new[static_cast(handle >> 15)]; + auto* obj = objects[static_cast(handle >> 15)]; return obj->DynamicCast(); } @@ -203,8 +180,7 @@ public: private: /// Stores the Object referenced by the handle or null if the slot is empty. - std::array, MAX_COUNT> objects; - std::array objects_new{}; + std::array objects{}; /** * The value of `next_generation` when the handle was created, used to check for validity. For diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index d647d9dd3..9e1e63204 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -74,12 +74,12 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_ for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { const u32 copy_handle{rp.Pop()}; copy_handles.push_back(copy_handle); - copy_objects.push_back(handle_table.GetGeneric(copy_handle)); + copy_objects.push_back(handle_table.GetObject(copy_handle).GetPointerUnsafe()); } for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { const u32 move_handle{rp.Pop()}; move_handles.push_back(move_handle); - move_objects.push_back(handle_table.GetGeneric(move_handle)); + move_objects.push_back(handle_table.GetObject(move_handle).GetPointerUnsafe()); } } else { // For responses we just ignore the handles, they're empty and will be populated when @@ -220,12 +220,12 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& thread) { // for specific values in each of these descriptors. for (auto& object : copy_objects) { ASSERT(object != nullptr); - dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); + R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); } for (auto& object : move_objects) { ASSERT(object != nullptr); - dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); + R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); } } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index dc5c3b47d..b7484c445 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -16,7 +16,7 @@ #include "common/concepts.h" #include "common/swap.h" #include "core/hle/ipc.h" -#include "core/hle/kernel/object.h" +#include "core/hle/kernel/k_auto_object.h" union ResultCode; @@ -228,11 +228,11 @@ public: return DynamicObjectCast(move_objects.at(index)); } - void AddMoveObject(Object* object) { + void AddMoveObject(KAutoObject* object) { move_objects.emplace_back(object); } - void AddCopyObject(Object* object) { + void AddCopyObject(KAutoObject* object) { copy_objects.emplace_back(object); } @@ -292,8 +292,8 @@ private: // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector move_handles; boost::container::small_vector copy_handles; - boost::container::small_vector move_objects; - boost::container::small_vector copy_objects; + boost::container::small_vector move_objects; + boost::container::small_vector copy_objects; boost::container::small_vector, 8> domain_objects; std::optional command_header; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index a78bfd1da..fa85bd631 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -328,7 +328,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, // Return the client session auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); + handle_table.Add(out_handle, client_session); return RESULT_SUCCESS; } diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f4eeba2c5..317c42631 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -118,7 +118,7 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa : mutex_address(mutex_address) { mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); owner_handle = static_cast(mutex_value & Kernel::Svc::HandleWaitMask); - owner = SharedFrom(handle_table.Get(owner_handle)); + owner = handle_table.GetObject(owner_handle).GetPointerUnsafe(); } WaitTreeMutexInfo::~WaitTreeMutexInfo() = default; diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 3da2fdfd2..bf8120a71 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -80,10 +80,10 @@ public: std::vector> GetChildren() const override; private: - VAddr mutex_address; - u32 mutex_value; - Kernel::Handle owner_handle; - std::shared_ptr owner; + VAddr mutex_address{}; + u32 mutex_value{}; + Kernel::Handle owner_handle{}; + Kernel::KThread* owner{}; }; class WaitTreeCallstack : public WaitTreeExpandableItem { -- cgit v1.2.3 From bf380b858481ef99d7150d322af2c30ac339bcde Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Apr 2021 21:50:04 -0700 Subject: hle: kernel: Remove deprecated Object class. --- src/core/CMakeLists.txt | 2 - src/core/core.h | 1 - src/core/hle/ipc_helpers.h | 17 ----- src/core/hle/kernel/handle_table.h | 1 - src/core/hle/kernel/hle_ipc.cpp | 1 - src/core/hle/kernel/hle_ipc.h | 10 --- src/core/hle/kernel/k_auto_object.h | 14 ++-- src/core/hle/kernel/k_client_port.h | 15 ---- src/core/hle/kernel/k_client_session.h | 19 ----- src/core/hle/kernel/k_event.h | 11 --- src/core/hle/kernel/k_port.h | 18 ----- src/core/hle/kernel/k_readable_event.h | 12 ---- src/core/hle/kernel/k_resource_limit.h | 15 ---- src/core/hle/kernel/k_server_port.cpp | 1 - src/core/hle/kernel/k_server_port.h | 15 ---- src/core/hle/kernel/k_server_session.h | 18 ----- src/core/hle/kernel/k_session.cpp | 4 +- src/core/hle/kernel/k_session.h | 14 +--- src/core/hle/kernel/k_shared_memory.h | 13 ---- src/core/hle/kernel/k_synchronization_object.h | 9 --- src/core/hle/kernel/k_thread.cpp | 1 - src/core/hle/kernel/k_thread.h | 15 ---- src/core/hle/kernel/k_transfer_memory.h | 15 ---- src/core/hle/kernel/k_writable_event.h | 12 ---- src/core/hle/kernel/kernel.h | 2 - src/core/hle/kernel/object.cpp | 42 ----------- src/core/hle/kernel/object.h | 98 -------------------------- src/core/hle/kernel/process.h | 15 ---- src/core/hle/kernel/time_manager.h | 2 - src/core/hle/service/am/applets/applets.h | 1 - src/core/hle/service/hid/controllers/npad.h | 1 - src/core/hle/service/hid/irs.h | 1 - src/core/hle/service/nvflinger/buffer_queue.h | 1 - src/core/hle/service/nvflinger/nvflinger.h | 1 - src/core/hle/service/service.h | 1 - src/core/hle/service/sm/controller.cpp | 2 +- src/core/hle/service/sm/sm.cpp | 2 +- src/yuzu/debugger/wait_tree.cpp | 28 ++++---- src/yuzu/debugger/wait_tree.h | 7 +- 39 files changed, 34 insertions(+), 423 deletions(-) delete mode 100644 src/core/hle/kernel/object.cpp delete mode 100644 src/core/hle/kernel/object.h (limited to 'src/yuzu/debugger') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index cee6d30f6..4e1387c7e 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -232,8 +232,6 @@ add_library(core STATIC hle/kernel/kernel.cpp hle/kernel/kernel.h hle/kernel/memory_types.h - hle/kernel/object.cpp - hle/kernel/object.h hle/kernel/physical_core.cpp hle/kernel/physical_core.h hle/kernel/physical_memory.h diff --git a/src/core/core.h b/src/core/core.h index f1068d23f..16e191266 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -12,7 +12,6 @@ #include "common/common_types.h" #include "core/file_sys/vfs_types.h" -#include "core/hle/kernel/object.h" namespace Core::Frontend { class EmuWindow; diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 8128445fd..0906b8cfb 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -16,7 +16,6 @@ #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_session.h" -#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace IPC { @@ -381,12 +380,6 @@ public: template T PopRaw(); - template - T* GetMoveObject(std::size_t index); - - template - T* GetCopyObject(std::size_t index); - template std::shared_ptr PopIpcInterface() { ASSERT(context->Session()->IsDomain()); @@ -491,14 +484,4 @@ void RequestParser::Pop(First& first_value, Other&... other_values) { Pop(other_values...); } -template -T* RequestParser::GetMoveObject(std::size_t index) { - return context->GetMoveObject(index); -} - -template -T* RequestParser::GetCopyObject(std::size_t index) { - return context->GetCopyObject(index); -} - } // namespace IPC diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h index 2e0b2d8b8..791e303d1 100644 --- a/src/core/hle/kernel/handle_table.h +++ b/src/core/hle/kernel/handle_table.h @@ -12,7 +12,6 @@ #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Kernel { diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index ddff9ce99..a11528f28 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -23,7 +23,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index d63c730ac..7f7ab74dd 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -212,16 +212,6 @@ public: return move_handles.at(index); } - template - T* GetCopyObject(std::size_t index) { - return DynamicObjectCast(copy_objects.at(index)); - } - - template - T* GetMoveObject(std::size_t index) { - return DynamicObjectCast(move_objects.at(index)); - } - void AddMoveObject(KAutoObject* object) { move_objects.emplace_back(object); } diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 64c012d44..fd6405a0e 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -11,13 +11,14 @@ #include "common/common_types.h" #include "common/intrusive_red_black_tree.h" #include "core/hle/kernel/k_class_token.h" -#include "core/hle/kernel/object.h" namespace Kernel { class KernelCore; class Process; +using Handle = u32; + #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ NON_COPYABLE(CLASS); \ NON_MOVEABLE(CLASS); \ @@ -48,7 +49,7 @@ public: \ private: -class KAutoObject : public Object { +class KAutoObject { protected: class TypeObj { private: @@ -84,16 +85,17 @@ private: KERNEL_AUTOOBJECT_TRAITS(KAutoObject, KAutoObject); private: - std::atomic m_ref_count; + std::atomic m_ref_count{}; protected: KernelCore& kernel; + std::string name; public: static KAutoObject* Create(KAutoObject* ptr); public: - explicit KAutoObject(KernelCore& kernel_) : Object{kernel_}, m_ref_count(0), kernel(kernel_) {} + explicit KAutoObject(KernelCore& kernel_) : kernel(kernel_) {} virtual ~KAutoObject() {} // Destroy is responsible for destroying the auto object's resources when ref_count hits zero. @@ -205,6 +207,10 @@ public: virtual u64 GetId() const { return reinterpret_cast(this); } + + virtual const std::string& GetName() const { + return name; + } }; template diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h index 43a17f4a4..f971a8b2c 100644 --- a/src/core/hle/kernel/k_client_port.h +++ b/src/core/hle/kernel/k_client_port.h @@ -51,26 +51,11 @@ public: ResultCode CreateSession(KClientSession** out); - // DEPRECATED - - std::string GetTypeName() const override { - return "ClientPort"; - } - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ClientPort; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: std::atomic num_sessions{}; std::atomic peak_sessions{}; s32 max_sessions{}; KPort* parent{}; - std::string name; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h index c4b193773..1480597e2 100644 --- a/src/core/hle/kernel/k_client_session.h +++ b/src/core/hle/kernel/k_client_session.h @@ -54,27 +54,8 @@ public: void OnServerClosed(); - // DEPRECATED - - static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - - std::string GetTypeName() const override { - return "ClientSession"; - } - - std::string GetName() const override { - return name; - } - private: - /// The parent session, which links to the server endpoint. KSession* parent{}; - - /// Name of the client session (optional) - std::string name; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index 45634e401..f0b89f882 100644 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -48,17 +48,6 @@ public: return writable_event; } - // DEPRECATED - - std::string GetTypeName() const override { - return "KEvent"; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::Event; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: KReadableEvent readable_event; KWritableEvent writable_event; diff --git a/src/core/hle/kernel/k_port.h b/src/core/hle/kernel/k_port.h index 68c8ed8df..f1b2838d8 100644 --- a/src/core/hle/kernel/k_port.h +++ b/src/core/hle/kernel/k_port.h @@ -51,22 +51,6 @@ public: return server; } - // DEPRECATED - - friend class ServerPort; - std::string GetTypeName() const override { - return "Port"; - } - std::string GetName() const override { - return name; - } - - HandleType GetHandleType() const override { - return {}; - } - - void Finalize() override {} - private: enum class State : u8 { Invalid = 0, @@ -80,8 +64,6 @@ private: KClientPort client; State state{State::Invalid}; bool is_light{}; - - std::string name; ///< Name of client port (optional) }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index 4c22f0584..8514d065a 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -6,7 +6,6 @@ #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_synchronization_object.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" @@ -39,17 +38,6 @@ public: ResultCode Clear(); ResultCode Reset(); - // DEPRECATED - - std::string GetTypeName() const override { - return "KReadableEvent"; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: bool is_signaled{}; KEvent* parent{}; diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 483c66c33..66ebf32df 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h @@ -8,7 +8,6 @@ #include "common/common_types.h" #include "core/hle/kernel/k_light_condition_variable.h" #include "core/hle/kernel/k_light_lock.h" -#include "core/hle/kernel/object.h" union ResultCode; @@ -57,20 +56,6 @@ public: static void PostDestroy([[maybe_unused]] uintptr_t arg) {} - // DEPRECATED - - std::string GetTypeName() const override { - return "KResourceLimit"; - } - std::string GetName() const override { - return GetTypeName(); - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: using ResourceArray = std::array(LimitableResource::Count)>; ResourceArray limit_values{}; diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp index fcc04abaa..5e44c48e2 100644 --- a/src/core/hle/kernel/k_server_port.cpp +++ b/src/core/hle/kernel/k_server_port.cpp @@ -10,7 +10,6 @@ #include "core/hle/kernel/k_server_port.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/svc_results.h" namespace Kernel { diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h index 9f45ca3f4..a46fa8f54 100644 --- a/src/core/hle/kernel/k_server_port.h +++ b/src/core/hle/kernel/k_server_port.h @@ -68,20 +68,6 @@ public: virtual void Destroy() override; virtual bool IsSignaled() const override; - // DEPRECATED - - std::string GetTypeName() const override { - return "ServerPort"; - } - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ServerPort; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: void CleanupSessions(); @@ -89,7 +75,6 @@ private: SessionList session_list; HLEHandler hle_handler; KPort* parent{}; - std::string name; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index d748754d0..4a54e6634 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h @@ -103,21 +103,6 @@ public: convert_to_domain = true; } - // DEPRECATED - - std::string GetTypeName() const override { - return "ServerSession"; - } - - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: /// Queues a sync request from the emulated application. ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); @@ -138,9 +123,6 @@ private: /// When set to True, converts the session to a domain at the end of the command bool convert_to_domain{}; - /// The name of this session (optional) - std::string name; - /// Thread to dispatch service requests std::weak_ptr service_thread; diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp index 6f4276189..6f5947ce7 100644 --- a/src/core/hle/kernel/k_session.cpp +++ b/src/core/hle/kernel/k_session.cpp @@ -15,7 +15,7 @@ KSession::KSession(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel}, server{kernel}, client{kernel} {} KSession::~KSession() = default; -void KSession::Initialize(KClientPort* port_, std::string&& name_) { +void KSession::Initialize(KClientPort* port_, const std::string& name_) { // Increment reference count. // Because reference count is one on creation, this will result // in a reference count of two. Thus, when both server and client are closed @@ -32,7 +32,7 @@ void KSession::Initialize(KClientPort* port_, std::string&& name_) { // Set state and name. SetState(State::Normal); - name = std::move(name_); + name = name_; // Set our owner process. process = kernel.CurrentProcess(); diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h index 1597cc608..f29195fa0 100644 --- a/src/core/hle/kernel/k_session.h +++ b/src/core/hle/kernel/k_session.h @@ -28,7 +28,7 @@ public: explicit KSession(KernelCore& kernel); virtual ~KSession() override; - void Initialize(KClientPort* port_, std::string&& name_); + void Initialize(KClientPort* port_, const std::string& name_); virtual void Finalize() override; @@ -74,17 +74,6 @@ public: return port; } - // DEPRECATED - - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::Session; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: void SetState(State state) { atomic_state = static_cast(state); @@ -100,7 +89,6 @@ private: std::atomic::type> atomic_state{ static_cast::type>(State::Invalid)}; KClientPort* port{}; - std::string name; Process* process{}; bool initialized{}; }; diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 93153ab20..9547546a5 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -32,19 +32,6 @@ public: KMemoryPermission owner_permission_, KMemoryPermission user_permission_, PAddr physical_address_, std::size_t size_, std::string name_); - std::string GetTypeName() const override { - return "SharedMemory"; - } - - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::SharedMemory; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - /** * Maps a shared memory block to an address in the target process' address space * @param target_process Process on which to map the memory block diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index 5a99dbd46..a41dd1220 100644 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -51,13 +51,4 @@ private: ThreadListNode* thread_list_tail{}; }; -// Specialization of DynamicObjectCast for KSynchronizationObjects -template <> -inline KSynchronizationObject* DynamicObjectCast(Object* object) { - if (object != nullptr && object->IsWaitable()) { - return reinterpret_cast(object); - } - return nullptr; -} - } // namespace Kernel diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 5cc0a0064..c59f3113c 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -27,7 +27,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 5c1c17d48..5b943b18b 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -19,7 +19,6 @@ #include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/k_synchronization_object.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_types.h" @@ -120,23 +119,10 @@ public: using ThreadContext64 = Core::ARM_Interface::ThreadContext64; using WaiterList = boost::intrusive::list; - [[nodiscard]] std::string GetName() const override { - return name; - } - void SetName(std::string new_name) { name = std::move(new_name); } - [[nodiscard]] std::string GetTypeName() const override { - return "Thread"; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::Thread; - [[nodiscard]] HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - /** * Gets the thread's current priority * @return The current thread's priority @@ -728,7 +714,6 @@ private: VAddr mutex_wait_address_for_debugging{}; ThreadWaitReasonForDebugging wait_reason_for_debugging{}; ThreadType thread_type_for_debugging{}; - std::string name; public: using ConditionVariableThreadTreeType = ConditionVariableThreadTree; diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index 3c3fa401b..1e4fa9323 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h @@ -55,21 +55,6 @@ public: return is_initialized ? size * PageSize : 0; } - // DEPRECATED - - std::string GetTypeName() const override { - return "TransferMemory"; - } - - std::string GetName() const override { - return GetTypeName(); - } - - static constexpr HandleType HANDLE_TYPE = HandleType::TransferMemory; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: Process* owner{}; VAddr address{}; diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index 7cf43f77e..f5e083482 100644 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h @@ -5,7 +5,6 @@ #pragma once #include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/object.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" @@ -34,17 +33,6 @@ public: return parent; } - // DEPRECATED - - std::string GetTypeName() const override { - return "KWritableEvent"; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - private: KEvent* parent{}; }; diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 723be6b51..de7f83423 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -14,7 +14,6 @@ #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_slab_heap.h" #include "core/hle/kernel/memory_types.h" -#include "core/hle/kernel/object.h" namespace Core { class CPUInterruptHandler; @@ -293,7 +292,6 @@ public: } private: - friend class Object; friend class Process; friend class KThread; diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp deleted file mode 100644 index d7f40c403..000000000 --- a/src/core/hle/kernel/object.cpp +++ /dev/null @@ -1,42 +0,0 @@ -// Copyright 2018 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include "common/assert.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/object.h" - -namespace Kernel { - -Object::Object(KernelCore& kernel_) - : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{"[UNKNOWN KERNEL OBJECT]"} {} -Object::Object(KernelCore& kernel_, std::string&& name_) - : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{std::move(name_)} {} -Object::~Object() = default; - -bool Object::IsWaitable() const { - switch (GetHandleType()) { - case HandleType::ReadableEvent: - case HandleType::Thread: - case HandleType::Process: - case HandleType::ServerPort: - case HandleType::ServerSession: - return true; - - case HandleType::Unknown: - case HandleType::Event: - case HandleType::WritableEvent: - case HandleType::SharedMemory: - case HandleType::TransferMemory: - case HandleType::ResourceLimit: - case HandleType::ClientPort: - case HandleType::ClientSession: - case HandleType::Session: - return false; - } - - UNREACHABLE(); - return false; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h deleted file mode 100644 index 03443b947..000000000 --- a/src/core/hle/kernel/object.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2018 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -#include "common/common_types.h" - -namespace Kernel { - -class KernelCore; - -using Handle = u32; - -enum class HandleType : u32 { - Unknown, - Event, - WritableEvent, - ReadableEvent, - SharedMemory, - TransferMemory, - Thread, - Process, - ResourceLimit, - ClientPort, - ServerPort, - ClientSession, - ServerSession, - Session, -}; - -class Object : NonCopyable, public std::enable_shared_from_this { -public: - explicit Object(KernelCore& kernel_); - explicit Object(KernelCore& kernel_, std::string&& name_); - virtual ~Object(); - - /// Returns a unique identifier for the object. For debugging purposes only. - u32 GetObjectId() const { - return object_id.load(std::memory_order_relaxed); - } - - virtual std::string GetTypeName() const { - return "[BAD KERNEL OBJECT TYPE]"; - } - virtual std::string GetName() const { - return name; - } - virtual HandleType GetHandleType() const = 0; - - void Close() { - // TODO(bunnei): This is a placeholder to decrement the reference count, which we will use - // when we implement KAutoObject instead of using shared_ptr. - } - - /** - * Check if a thread can wait on the object - * @return True if a thread can wait on the object, otherwise false - */ - bool IsWaitable() const; - - virtual void Finalize() = 0; - -protected: - /// The kernel instance this object was created under. - KernelCore& kernel; - -private: - std::atomic object_id{0}; - -protected: - std::string name; -}; - -template -std::shared_ptr SharedFrom(T* raw) { - if (raw == nullptr) - return nullptr; - return std::static_pointer_cast(raw->shared_from_this()); -} - -/** - * Attempts to downcast the given Object pointer to a pointer to T. - * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T. - */ -template -inline T* DynamicObjectCast(Object* object) { - if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) { - return reinterpret_cast(object); - } - return nullptr; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 35fe16433..b775e1fd0 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -92,18 +92,6 @@ public: static ResultCode Initialize(Process* process, Core::System& system, std::string name, ProcessType type); - std::string GetTypeName() const override { - return "Process"; - } - std::string GetName() const override { - return name; - } - - static constexpr HandleType HANDLE_TYPE = HandleType::Process; - HandleType GetHandleType() const override { - return HANDLE_TYPE; - } - /// Gets a reference to the process' page table. KPageTable& PageTable() { return *page_table; @@ -468,9 +456,6 @@ private: /// Process total image size std::size_t image_size{}; - /// Name of this process - std::string name; - /// Schedule count of this process s64 schedule_count{}; diff --git a/src/core/hle/kernel/time_manager.h b/src/core/hle/kernel/time_manager.h index 0d7f05f30..2d175a9c4 100644 --- a/src/core/hle/kernel/time_manager.h +++ b/src/core/hle/kernel/time_manager.h @@ -8,8 +8,6 @@ #include #include -#include "core/hle/kernel/object.h" - namespace Core { class System; } // namespace Core diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 229dc7a1e..5c0b4b459 100644 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -9,7 +9,6 @@ #include "common/swap.h" #include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/object.h" union ResultCode; diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index b0f575561..c050c9a44 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -11,7 +11,6 @@ #include "common/quaternion.h" #include "common/settings.h" #include "core/frontend/input.h" -#include "core/hle/kernel/object.h" #include "core/hle/service/hid/controllers/controller_base.h" namespace Kernel { diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index a1bcb5859..9bc6462b0 100644 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -4,7 +4,6 @@ #pragma once -#include "core/hle/kernel/object.h" #include "core/hle/service/service.h" namespace Core { diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 044e51d08..4ec0b1506 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -15,7 +15,6 @@ #include "common/swap.h" #include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" -#include "core/hle/kernel/object.h" #include "core/hle/service/nvdrv/nvdata.h" namespace Kernel { diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index 1c0aa8ec4..b0febdaec 100644 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -15,7 +15,6 @@ #include #include "common/common_types.h" -#include "core/hle/kernel/object.h" namespace Common { class Event; diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 076f50b0b..884951428 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,7 +11,6 @@ #include "common/common_types.h" #include "common/spin_lock.h" #include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/object.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace Service diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index cb397fcc7..ee026e22f 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -14,7 +14,7 @@ namespace Service::SM { void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); - LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); + LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId()); ctx.Session()->ConvertToDomain(); IPC::ResponseBuilder rb{ctx, 3}; diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 71ab4b6f5..568effbc9 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -140,7 +140,7 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { port->EnqueueSession(&session->GetServerSession()); } - LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetObjectId()); + LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); rb.PushMoveObjects(session->GetClientSession()); diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 317c42631..3ac4a9e2b 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -13,6 +13,7 @@ #include "core/arm/arm_interface.h" #include "core/core.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_class_token.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_synchronization_object.h" @@ -183,20 +184,20 @@ bool WaitTreeExpandableItem::IsExpandable() const { } QString WaitTreeSynchronizationObject::GetText() const { - // return tr("[%1]%2 %3") - // .arg(object.GetObjectId()) - // .arg(QString::fromStdString(object.GetTypeName()), - // QString::fromStdString(object.GetName())); - - return tr("UNIMPLEMENTED"); + return tr("[%1] %2 %3") + .arg(object.GetId()) + .arg(QString::fromStdString(object.GetTypeObj().GetName()), + QString::fromStdString(object.GetName())); } std::unique_ptr WaitTreeSynchronizationObject::make( const Kernel::KSynchronizationObject& object) { - switch (object.GetHandleType()) { - case Kernel::HandleType::ReadableEvent: + const auto type = + static_cast(object.GetTypeObj().GetClassToken()); + switch (type) { + case Kernel::KClassTokenGenerator::ObjectType::KReadableEvent: return std::make_unique(static_cast(object)); - case Kernel::HandleType::Thread: + case Kernel::KClassTokenGenerator::ObjectType::KThread: return std::make_unique(static_cast(object)); default: return std::make_unique(object); @@ -206,12 +207,13 @@ std::unique_ptr WaitTreeSynchronizationObject::ma std::vector> WaitTreeSynchronizationObject::GetChildren() const { std::vector> list; - const auto& threads = object.GetWaitingThreadsForDebugging(); + auto threads = object.GetWaitingThreadsForDebugging(); if (threads.empty()) { list.push_back(std::make_unique(tr("waited by no thread"))); } else { - list.push_back(std::make_unique(threads)); + list.push_back(std::make_unique(std::move(threads))); } + return list; } @@ -379,8 +381,8 @@ WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object) : WaitTreeSynchronizationObject(object) {} WaitTreeEvent::~WaitTreeEvent() = default; -WaitTreeThreadList::WaitTreeThreadList(const std::vector& list) - : thread_list(list) {} +WaitTreeThreadList::WaitTreeThreadList(std::vector&& list) + : thread_list(std::move(list)) {} WaitTreeThreadList::~WaitTreeThreadList() = default; QString WaitTreeThreadList::GetText() const { diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index bf8120a71..3dd4acab0 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -11,8 +11,9 @@ #include #include #include + #include "common/common_types.h" -#include "core/hle/kernel/object.h" +#include "core/hle/kernel/k_auto_object.h" class EmuThread; @@ -149,14 +150,14 @@ public: class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeThreadList(const std::vector& list); + explicit WaitTreeThreadList(std::vector&& list); ~WaitTreeThreadList() override; QString GetText() const override; std::vector> GetChildren() const override; private: - const std::vector& thread_list; + std::vector thread_list; }; class WaitTreeModel : public QAbstractItemModel { -- cgit v1.2.3 From 2a7eff57a8048933a89c1a8f8d6dced7b5d604f2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 23 Apr 2021 22:04:28 -0700 Subject: hle: kernel: Rename Process to KProcess. --- src/core/CMakeLists.txt | 4 +- src/core/arm/dynarmic/arm_dynarmic_64.cpp | 2 +- src/core/core.cpp | 14 +- src/core/core.h | 6 +- src/core/file_sys/romfs_factory.cpp | 2 +- src/core/file_sys/savedata_factory.cpp | 2 +- src/core/hle/kernel/handle_table.cpp | 2 +- src/core/hle/kernel/hle_ipc.cpp | 2 +- src/core/hle/kernel/hle_ipc.h | 2 +- src/core/hle/kernel/init/init_slab_setup.cpp | 8 +- src/core/hle/kernel/init/init_slab_setup.h | 2 +- src/core/hle/kernel/k_auto_object.h | 4 +- src/core/hle/kernel/k_auto_object_container.cpp | 2 +- src/core/hle/kernel/k_auto_object_container.h | 4 +- src/core/hle/kernel/k_class_token.h | 2 +- src/core/hle/kernel/k_condition_variable.cpp | 2 +- src/core/hle/kernel/k_event.cpp | 4 +- src/core/hle/kernel/k_event.h | 6 +- src/core/hle/kernel/k_page_table.cpp | 2 +- src/core/hle/kernel/k_process.cpp | 505 +++++++++++++++++++++ src/core/hle/kernel/k_process.h | 480 ++++++++++++++++++++ src/core/hle/kernel/k_scheduler.cpp | 16 +- src/core/hle/kernel/k_scheduler.h | 6 +- .../hle/kernel/k_scoped_resource_reservation.h | 6 +- src/core/hle/kernel/k_server_session.cpp | 2 +- src/core/hle/kernel/k_session.cpp | 2 +- src/core/hle/kernel/k_session.h | 2 +- src/core/hle/kernel/k_shared_memory.cpp | 4 +- src/core/hle/kernel/k_shared_memory.h | 8 +- src/core/hle/kernel/k_thread.cpp | 10 +- src/core/hle/kernel/k_thread.h | 16 +- src/core/hle/kernel/k_transfer_memory.cpp | 4 +- src/core/hle/kernel/k_transfer_memory.h | 6 +- src/core/hle/kernel/kernel.cpp | 26 +- src/core/hle/kernel/kernel.h | 18 +- src/core/hle/kernel/process.cpp | 505 --------------------- src/core/hle/kernel/process.h | 479 ------------------- src/core/hle/kernel/svc.cpp | 30 +- src/core/hle/service/acc/acc.cpp | 2 +- src/core/hle/service/am/am.cpp | 2 +- src/core/hle/service/am/applets/error.cpp | 2 +- .../hle/service/am/applets/general_backend.cpp | 2 +- src/core/hle/service/am/applets/web_browser.cpp | 2 +- src/core/hle/service/aoc/aoc_u.cpp | 2 +- src/core/hle/service/bcat/module.cpp | 2 +- src/core/hle/service/fatal/fatal.cpp | 2 +- src/core/hle/service/filesystem/filesystem.cpp | 2 +- src/core/hle/service/filesystem/fsp_srv.cpp | 2 +- src/core/hle/service/glue/arp.cpp | 2 +- src/core/hle/service/ldr/ldr.cpp | 8 +- src/core/hle/service/pctl/module.cpp | 2 +- src/core/hle/service/pm/pm.cpp | 15 +- src/core/hle/service/prepo/prepo.cpp | 2 +- src/core/hle/service/service.cpp | 2 +- src/core/loader/deconstructed_rom_directory.cpp | 4 +- src/core/loader/deconstructed_rom_directory.h | 2 +- src/core/loader/elf.cpp | 4 +- src/core/loader/elf.h | 2 +- src/core/loader/kip.cpp | 4 +- src/core/loader/kip.h | 2 +- src/core/loader/loader.cpp | 2 +- src/core/loader/loader.h | 4 +- src/core/loader/nax.cpp | 4 +- src/core/loader/nax.h | 2 +- src/core/loader/nca.cpp | 4 +- src/core/loader/nca.h | 2 +- src/core/loader/nro.cpp | 8 +- src/core/loader/nro.h | 6 +- src/core/loader/nso.cpp | 6 +- src/core/loader/nso.h | 6 +- src/core/loader/nsp.cpp | 4 +- src/core/loader/nsp.h | 2 +- src/core/loader/xci.cpp | 4 +- src/core/loader/xci.h | 2 +- src/core/memory.cpp | 34 +- src/core/memory.h | 18 +- src/core/memory/cheat_engine.cpp | 2 +- src/core/reporter.cpp | 2 +- src/video_core/memory_manager.cpp | 2 +- src/video_core/renderer_opengl/gl_rasterizer.cpp | 2 +- .../renderer_opengl/gl_shader_disk_cache.cpp | 2 +- src/yuzu/bootmanager.cpp | 2 +- src/yuzu/debugger/wait_tree.cpp | 2 +- src/yuzu/main.cpp | 2 +- src/yuzu_cmd/yuzu.cpp | 2 +- 85 files changed, 1197 insertions(+), 1195 deletions(-) create mode 100644 src/core/hle/kernel/k_process.cpp create mode 100644 src/core/hle/kernel/k_process.h delete mode 100644 src/core/hle/kernel/process.cpp delete mode 100644 src/core/hle/kernel/process.h (limited to 'src/yuzu/debugger') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 4e1387c7e..889a2d2f8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -197,6 +197,8 @@ add_library(core STATIC hle/kernel/k_port.cpp hle/kernel/k_port.h hle/kernel/k_priority_queue.h + hle/kernel/k_process.cpp + hle/kernel/k_process.h hle/kernel/k_readable_event.cpp hle/kernel/k_readable_event.h hle/kernel/k_resource_limit.cpp @@ -235,8 +237,6 @@ add_library(core STATIC hle/kernel/physical_core.cpp hle/kernel/physical_core.h hle/kernel/physical_memory.h - hle/kernel/process.cpp - hle/kernel/process.h hle/kernel/process_capability.cpp hle/kernel/process_capability.h hle/kernel/service_thread.cpp diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 4ff72abd8..653bb7a77 100644 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -16,8 +16,8 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" diff --git a/src/core/core.cpp b/src/core/core.cpp index 4bb96d77d..434bf3262 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -28,11 +28,11 @@ #include "core/file_sys/vfs_real.h" #include "core/hardware_interrupt_manager.h" #include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/apm/controller.h" #include "core/hle/service/filesystem/filesystem.h" @@ -233,9 +233,9 @@ struct System::Impl { } telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); - auto main_process = Kernel::Process::Create(system.Kernel()); - ASSERT(Kernel::Process::Initialize(main_process, system, "main", - Kernel::Process::ProcessType::Userland) + auto main_process = Kernel::KProcess::Create(system.Kernel()); + ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", + Kernel::KProcess::ProcessType::Userland) .IsSuccess()); main_process->Open(); const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); @@ -326,7 +326,7 @@ struct System::Impl { return app_loader->ReadTitle(out); } - void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::Process& process) { + void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) { std::vector nacp_data; FileSys::NACP nacp; if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { @@ -517,7 +517,7 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const { return impl->kernel.GlobalSchedulerContext(); } -Kernel::Process* System::CurrentProcess() { +Kernel::KProcess* System::CurrentProcess() { return impl->kernel.CurrentProcess(); } @@ -529,7 +529,7 @@ const Core::DeviceMemory& System::DeviceMemory() const { return *impl->device_memory; } -const Kernel::Process* System::CurrentProcess() const { +const Kernel::KProcess* System::CurrentProcess() const { return impl->kernel.CurrentProcess(); } diff --git a/src/core/core.h b/src/core/core.h index 16e191266..8b93ba998 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -28,7 +28,7 @@ namespace Kernel { class GlobalSchedulerContext; class KernelCore; class PhysicalCore; -class Process; +class KProcess; class KScheduler; } // namespace Kernel @@ -263,10 +263,10 @@ public: [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const; /// Provides a pointer to the current process - [[nodiscard]] Kernel::Process* CurrentProcess(); + [[nodiscard]] Kernel::KProcess* CurrentProcess(); /// Provides a constant pointer to the current process. - [[nodiscard]] const Kernel::Process* CurrentProcess() const; + [[nodiscard]] const Kernel::KProcess* CurrentProcess() const; /// Provides a reference to the core timing instance. [[nodiscard]] Timing::CoreTiming& CoreTiming(); diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index de6ab721d..aa7f3072f 100644 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs_factory.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index fa68af3a8..f973d1d21 100644 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -9,7 +9,7 @@ #include "core/core.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/vfs.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" namespace FileSys { diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index cd752da4e..16c528f5b 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp @@ -7,10 +7,10 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" namespace Kernel { diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index a11528f28..69190286d 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -16,6 +16,7 @@ #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" @@ -23,7 +24,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" #include "core/memory.h" diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 7f7ab74dd..4b92ba655 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -38,7 +38,7 @@ class Domain; class HandleTable; class HLERequestContext; class KernelCore; -class Process; +class KProcess; class KServerSession; class KThread; class KReadableEvent; diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index f8c255732..04e481a0a 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp @@ -13,6 +13,7 @@ #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" #include "core/hle/kernel/k_port.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_session.h" #include "core/hle/kernel/k_shared_memory.h" @@ -20,7 +21,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/memory_types.h" -#include "core/hle/kernel/process.h" #include "core/memory.h" namespace Kernel::Init { @@ -28,7 +28,7 @@ namespace Kernel::Init { #define SLAB_COUNT(CLASS) g_slab_resource_counts.num_##CLASS #define FOREACH_SLAB_TYPE(HANDLER, ...) \ - HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ + HANDLER(KProcess, (SLAB_COUNT(KProcess)), ##__VA_ARGS__) \ HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ HANDLER(KPort, (SLAB_COUNT(KPort)), ##__VA_ARGS__) \ @@ -48,7 +48,7 @@ enum KSlabType : u32 { #undef DEFINE_SLAB_TYPE_ENUM_MEMBER // Constexpr counts. -constexpr size_t SlabCountProcess = 80; +constexpr size_t SlabCountKProcess = 80; constexpr size_t SlabCountKThread = 800; constexpr size_t SlabCountKEvent = 700; constexpr size_t SlabCountKInterruptEvent = 100; @@ -69,7 +69,7 @@ constexpr size_t SlabCountExtraKThread = 160; // Global to hold our resource counts. KSlabResourceCounts g_slab_resource_counts = { - .num_Process = SlabCountProcess, + .num_KProcess = SlabCountKProcess, .num_KThread = SlabCountKThread, .num_KEvent = SlabCountKEvent, .num_KInterruptEvent = SlabCountKInterruptEvent, diff --git a/src/core/hle/kernel/init/init_slab_setup.h b/src/core/hle/kernel/init/init_slab_setup.h index 8876678b3..6418b97ac 100644 --- a/src/core/hle/kernel/init/init_slab_setup.h +++ b/src/core/hle/kernel/init/init_slab_setup.h @@ -15,7 +15,7 @@ class KMemoryLayout; namespace Kernel::Init { struct KSlabResourceCounts { - size_t num_Process; + size_t num_KProcess; size_t num_KThread; size_t num_KEvent; size_t num_KInterruptEvent; diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index fd6405a0e..5a180b7dc 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -15,7 +15,7 @@ namespace Kernel { class KernelCore; -class Process; +class KProcess; using Handle = u32; @@ -106,7 +106,7 @@ public: // Finalize is responsible for cleaning up resource, but does not destroy the object. virtual void Finalize() {} - virtual Process* GetOwner() const { + virtual KProcess* GetOwner() const { return nullptr; } diff --git a/src/core/hle/kernel/k_auto_object_container.cpp b/src/core/hle/kernel/k_auto_object_container.cpp index 9ba8a54c7..85d03ebe3 100644 --- a/src/core/hle/kernel/k_auto_object_container.cpp +++ b/src/core/hle/kernel/k_auto_object_container.cpp @@ -18,7 +18,7 @@ void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) { m_object_list.erase(m_object_list.iterator_to(*obj)); } -size_t KAutoObjectWithListContainer::GetOwnedCount(Process* owner) { +size_t KAutoObjectWithListContainer::GetOwnedCount(KProcess* owner) { KScopedLightLock lk(m_lock); size_t count = 0; diff --git a/src/core/hle/kernel/k_auto_object_container.h b/src/core/hle/kernel/k_auto_object_container.h index 4b599b7c3..6d1cd4862 100644 --- a/src/core/hle/kernel/k_auto_object_container.h +++ b/src/core/hle/kernel/k_auto_object_container.h @@ -16,7 +16,7 @@ namespace Kernel { class KernelCore; -class Process; +class KProcess; class KAutoObjectWithListContainer { NON_COPYABLE(KAutoObjectWithListContainer); @@ -66,7 +66,7 @@ public: void Register(KAutoObjectWithList* obj); void Unregister(KAutoObjectWithList* obj); - size_t GetOwnedCount(Process* owner); + size_t GetOwnedCount(KProcess* owner); }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h index 89b80a341..fb4307cd0 100644 --- a/src/core/hle/kernel/k_class_token.h +++ b/src/core/hle/kernel/k_class_token.h @@ -97,7 +97,7 @@ public: KServerSession, KClientPort, KClientSession, - Process, + KProcess, KResourceLimit, KLightSession, KPort, diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 72565af05..a9738f7ce 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -8,12 +8,12 @@ #include "core/core.h" #include "core/hle/kernel/k_condition_variable.h" #include "core/hle/kernel/k_linked_list.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp index fdec0c36f..986355b78 100644 --- a/src/core/hle/kernel/k_event.cpp +++ b/src/core/hle/kernel/k_event.cpp @@ -3,8 +3,8 @@ // Refer to the license.txt file included. #include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" -#include "core/hle/kernel/process.h" namespace Kernel { @@ -45,7 +45,7 @@ void KEvent::Finalize() { void KEvent::PostDestroy(uintptr_t arg) { // Release the event count resource the owner process holds. - Process* owner = reinterpret_cast(arg); + KProcess* owner = reinterpret_cast(arg); if (owner) { owner->GetResourceLimit()->Release(LimitableResource::Events, 1); owner->Close(); diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index f0b89f882..4ca869930 100644 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -13,7 +13,7 @@ namespace Kernel { class KernelCore; class KReadableEvent; class KWritableEvent; -class Process; +class KProcess; class KEvent final : public KAutoObjectWithSlabHeapAndContainer { KERNEL_AUTOOBJECT_TRAITS(KEvent, KAutoObject); @@ -36,7 +36,7 @@ public: static void PostDestroy(uintptr_t arg); - virtual Process* GetOwner() const override { + virtual KProcess* GetOwner() const override { return owner; } @@ -51,7 +51,7 @@ public: private: KReadableEvent readable_event; KWritableEvent writable_event; - Process* owner{}; + KProcess* owner{}; bool initialized{}; }; diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index 5f60b95cd..2f33cb6c1 100644 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -11,11 +11,11 @@ #include "core/hle/kernel/k_memory_block_manager.h" #include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp new file mode 100644 index 000000000..edc3b5175 --- /dev/null +++ b/src/core/hle/kernel/k_process.cpp @@ -0,0 +1,505 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include +#include +#include "common/alignment.h" +#include "common/assert.h" +#include "common/logging/log.h" +#include "common/settings.h" +#include "core/core.h" +#include "core/device_memory.h" +#include "core/file_sys/program_metadata.h" +#include "core/hle/kernel/code_set.h" +#include "core/hle/kernel/k_memory_block_manager.h" +#include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_scoped_resource_reservation.h" +#include "core/hle/kernel/k_slab_heap.h" +#include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/svc_results.h" +#include "core/hle/lock.h" +#include "core/memory.h" + +namespace Kernel { +namespace { +/** + * Sets up the primary application thread + * + * @param system The system instance to create the main thread under. + * @param owner_process The parent process for the main thread + * @param priority The priority to give the main thread + */ +void SetupMainThread(Core::System& system, KProcess& owner_process, u32 priority, VAddr stack_top) { + const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); + ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); + + KThread* thread = KThread::Create(system.Kernel()); + ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, + owner_process.GetIdealCoreId(), &owner_process) + .IsSuccess()); + + // Register 1 must be a handle to the main thread + Handle thread_handle{}; + owner_process.GetHandleTable().Add(&thread_handle, thread); + + thread->SetName("main"); + thread->GetContext32().cpu_registers[0] = 0; + thread->GetContext64().cpu_registers[0] = 0; + thread->GetContext32().cpu_registers[1] = thread_handle; + thread->GetContext64().cpu_registers[1] = thread_handle; + + auto& kernel = system.Kernel(); + // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires + { + KScopedSchedulerLock lock{kernel}; + thread->SetState(ThreadState::Runnable); + } +} +} // Anonymous namespace + +// Represents a page used for thread-local storage. +// +// Each TLS page contains slots that may be used by processes and threads. +// Every process and thread is created with a slot in some arbitrary page +// (whichever page happens to have an available slot). +class TLSPage { +public: + static constexpr std::size_t num_slot_entries = + Core::Memory::PAGE_SIZE / Core::Memory::TLS_ENTRY_SIZE; + + explicit TLSPage(VAddr address) : base_address{address} {} + + bool HasAvailableSlots() const { + return !is_slot_used.all(); + } + + VAddr GetBaseAddress() const { + return base_address; + } + + std::optional ReserveSlot() { + for (std::size_t i = 0; i < is_slot_used.size(); i++) { + if (is_slot_used[i]) { + continue; + } + + is_slot_used[i] = true; + return base_address + (i * Core::Memory::TLS_ENTRY_SIZE); + } + + return std::nullopt; + } + + void ReleaseSlot(VAddr address) { + // Ensure that all given addresses are consistent with how TLS pages + // are intended to be used when releasing slots. + ASSERT(IsWithinPage(address)); + ASSERT((address % Core::Memory::TLS_ENTRY_SIZE) == 0); + + const std::size_t index = (address - base_address) / Core::Memory::TLS_ENTRY_SIZE; + is_slot_used[index] = false; + } + +private: + bool IsWithinPage(VAddr address) const { + return base_address <= address && address < base_address + Core::Memory::PAGE_SIZE; + } + + VAddr base_address; + std::bitset is_slot_used; +}; + +ResultCode KProcess::Initialize(KProcess* process, Core::System& system, std::string name, + ProcessType type) { + auto& kernel = system.Kernel(); + + process->name = std::move(name); + + process->resource_limit = kernel.GetSystemResourceLimit(); + process->status = ProcessStatus::Created; + process->program_id = 0; + process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() + : kernel.CreateNewUserProcessID(); + process->capabilities.InitializeForMetadatalessProcess(); + process->is_initialized = true; + + std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))); + std::uniform_int_distribution distribution; + std::generate(process->random_entropy.begin(), process->random_entropy.end(), + [&] { return distribution(rng); }); + + kernel.AppendNewProcess(process); + + // Open a reference to the resource limit. + process->resource_limit->Open(); + + return RESULT_SUCCESS; +} + +KResourceLimit* KProcess::GetResourceLimit() const { + return resource_limit; +} + +void KProcess::IncrementThreadCount() { + ASSERT(num_threads >= 0); + num_created_threads++; + + if (const auto count = ++num_threads; count > peak_num_threads) { + peak_num_threads = count; + } +} + +void KProcess::DecrementThreadCount() { + ASSERT(num_threads > 0); + + if (const auto count = --num_threads; count == 0) { + UNIMPLEMENTED_MSG("Process termination is not implemented!"); + } +} + +u64 KProcess::GetTotalPhysicalMemoryAvailable() const { + const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + + page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + + main_thread_stack_size}; + if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); + capacity != pool_size) { + LOG_WARNING(Kernel, "capacity {} != application pool size {}", capacity, pool_size); + } + if (capacity < memory_usage_capacity) { + return capacity; + } + return memory_usage_capacity; +} + +u64 KProcess::GetTotalPhysicalMemoryAvailableWithoutSystemResource() const { + return GetTotalPhysicalMemoryAvailable() - GetSystemResourceSize(); +} + +u64 KProcess::GetTotalPhysicalMemoryUsed() const { + return image_size + main_thread_stack_size + page_table->GetTotalHeapSize() + + GetSystemResourceSize(); +} + +u64 KProcess::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { + return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); +} + +bool KProcess::ReleaseUserException(KThread* thread) { + KScopedSchedulerLock sl{kernel}; + + if (exception_thread == thread) { + exception_thread = nullptr; + + // Remove waiter thread. + s32 num_waiters{}; + KThread* next = thread->RemoveWaiterByKey( + std::addressof(num_waiters), + reinterpret_cast(std::addressof(exception_thread))); + if (next != nullptr) { + if (next->GetState() == ThreadState::Waiting) { + next->SetState(ThreadState::Runnable); + } else { + KScheduler::SetSchedulerUpdateNeeded(kernel); + } + } + + return true; + } else { + return false; + } +} + +void KProcess::PinCurrentThread() { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + // Get the current thread. + const s32 core_id = GetCurrentCoreId(kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); + + // Pin it. + PinThread(core_id, cur_thread); + cur_thread->Pin(); + + // An update is needed. + KScheduler::SetSchedulerUpdateNeeded(kernel); +} + +void KProcess::UnpinCurrentThread() { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + + // Get the current thread. + const s32 core_id = GetCurrentCoreId(kernel); + KThread* cur_thread = GetCurrentThreadPointer(kernel); + + // Unpin it. + cur_thread->Unpin(); + UnpinThread(core_id, cur_thread); + + // An update is needed. + KScheduler::SetSchedulerUpdateNeeded(kernel); +} + +void KProcess::RegisterThread(const KThread* thread) { + thread_list.push_back(thread); +} + +void KProcess::UnregisterThread(const KThread* thread) { + thread_list.remove(thread); +} + +ResultCode KProcess::Reset() { + // Lock the process and the scheduler. + KScopedLightLock lk(state_lock); + KScopedSchedulerLock sl{kernel}; + + // Validate that we're in a state that we can reset. + R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); + R_UNLESS(is_signaled, ResultInvalidState); + + // Clear signaled. + is_signaled = false; + return RESULT_SUCCESS; +} + +ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, + std::size_t code_size) { + program_id = metadata.GetTitleID(); + ideal_core = metadata.GetMainThreadCore(); + is_64bit_process = metadata.Is64BitProgram(); + system_resource_size = metadata.GetSystemResourceSize(); + image_size = code_size; + + KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, + code_size + system_resource_size); + if (!memory_reservation.Succeeded()) { + LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes", + code_size + system_resource_size); + return ResultLimitReached; + } + // Initialize proces address space + if (const ResultCode result{ + page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, + code_size, KMemoryManager::Pool::Application)}; + result.IsError()) { + return result; + } + + // Map process code region + if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), + code_size / PageSize, KMemoryState::Code, + KMemoryPermission::None)}; + result.IsError()) { + return result; + } + + // Initialize process capabilities + const auto& caps{metadata.GetKernelCapabilities()}; + if (const ResultCode result{ + capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)}; + result.IsError()) { + return result; + } + + // Set memory usage capacity + switch (metadata.GetAddressSpaceType()) { + case FileSys::ProgramAddressSpaceType::Is32Bit: + case FileSys::ProgramAddressSpaceType::Is36Bit: + case FileSys::ProgramAddressSpaceType::Is39Bit: + memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart(); + break; + + case FileSys::ProgramAddressSpaceType::Is32BitNoMap: + memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart() + + page_table->GetAliasRegionEnd() - page_table->GetAliasRegionStart(); + break; + + default: + UNREACHABLE(); + } + + // Create TLS region + tls_region_address = CreateTLSRegion(); + memory_reservation.Commit(); + + return handle_table.SetSize(capabilities.GetHandleTableSize()); +} + +void KProcess::Run(s32 main_thread_priority, u64 stack_size) { + AllocateMainThreadStack(stack_size); + resource_limit->Reserve(LimitableResource::Threads, 1); + resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); + + const std::size_t heap_capacity{memory_usage_capacity - main_thread_stack_size - image_size}; + ASSERT(!page_table->SetHeapCapacity(heap_capacity).IsError()); + + ChangeStatus(ProcessStatus::Running); + + SetupMainThread(kernel.System(), *this, main_thread_priority, main_thread_stack_top); +} + +void KProcess::PrepareForTermination() { + ChangeStatus(ProcessStatus::Exiting); + + const auto stop_threads = [this](const std::vector& thread_list) { + for (auto& thread : thread_list) { + if (thread->GetOwnerProcess() != this) + continue; + + if (thread == kernel.CurrentScheduler()->GetCurrentThread()) + continue; + + // TODO(Subv): When are the other running/ready threads terminated? + ASSERT_MSG(thread->GetState() == ThreadState::Waiting, + "Exiting processes with non-waiting threads is currently unimplemented"); + + thread->Exit(); + } + }; + + stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList()); + + FreeTLSRegion(tls_region_address); + tls_region_address = 0; + + if (resource_limit) { + resource_limit->Release(LimitableResource::PhysicalMemory, + main_thread_stack_size + image_size); + } + + ChangeStatus(ProcessStatus::Exited); +} + +void KProcess::Finalize() { + // Release memory to the resource limit. + if (resource_limit != nullptr) { + resource_limit->Close(); + } + + // Perform inherited finalization. + KAutoObjectWithSlabHeapAndContainer::Finalize(); +} + +/** + * Attempts to find a TLS page that contains a free slot for + * use by a thread. + * + * @returns If a page with an available slot is found, then an iterator + * pointing to the page is returned. Otherwise the end iterator + * is returned instead. + */ +static auto FindTLSPageWithAvailableSlots(std::vector& tls_pages) { + return std::find_if(tls_pages.begin(), tls_pages.end(), + [](const auto& page) { return page.HasAvailableSlots(); }); +} + +VAddr KProcess::CreateTLSRegion() { + KScopedSchedulerLock lock(kernel); + if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; + tls_page_iter != tls_pages.cend()) { + return *tls_page_iter->ReserveSlot(); + } + + Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; + ASSERT(tls_page_ptr); + + const VAddr start{page_table->GetKernelMapRegionStart()}; + const VAddr size{page_table->GetKernelMapRegionEnd() - start}; + const PAddr tls_map_addr{kernel.System().DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; + const VAddr tls_page_addr{page_table + ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize, + KMemoryState::ThreadLocal, + KMemoryPermission::ReadAndWrite, + tls_map_addr) + .ValueOr(0)}; + + ASSERT(tls_page_addr); + + std::memset(tls_page_ptr, 0, PageSize); + tls_pages.emplace_back(tls_page_addr); + + const auto reserve_result{tls_pages.back().ReserveSlot()}; + ASSERT(reserve_result.has_value()); + + return *reserve_result; +} + +void KProcess::FreeTLSRegion(VAddr tls_address) { + KScopedSchedulerLock lock(kernel); + const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); + auto iter = + std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { + return page.GetBaseAddress() == aligned_address; + }); + + // Something has gone very wrong if we're freeing a region + // with no actual page available. + ASSERT(iter != tls_pages.cend()); + + iter->ReleaseSlot(tls_address); +} + +void KProcess::LoadModule(CodeSet code_set, VAddr base_addr) { + std::lock_guard lock{HLE::g_hle_lock}; + const auto ReprotectSegment = [&](const CodeSet::Segment& segment, + KMemoryPermission permission) { + page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); + }; + + kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), + code_set.memory.size()); + + ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute); + ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read); + ReprotectSegment(code_set.DataSegment(), KMemoryPermission::ReadAndWrite); +} + +bool KProcess::IsSignaled() const { + ASSERT(kernel.GlobalSchedulerContext().IsLocked()); + return is_signaled; +} + +KProcess::KProcess(KernelCore& kernel) + : KAutoObjectWithSlabHeapAndContainer{kernel}, + page_table{std::make_unique(kernel.System())}, handle_table{kernel}, + address_arbiter{kernel.System()}, condition_var{kernel.System()}, state_lock{kernel} {} + +KProcess::~KProcess() = default; + +void KProcess::ChangeStatus(ProcessStatus new_status) { + if (status == new_status) { + return; + } + + status = new_status; + is_signaled = true; + NotifyAvailable(); +} + +ResultCode KProcess::AllocateMainThreadStack(std::size_t stack_size) { + ASSERT(stack_size); + + // The kernel always ensures that the given stack size is page aligned. + main_thread_stack_size = Common::AlignUp(stack_size, PageSize); + + const VAddr start{page_table->GetStackRegionStart()}; + const std::size_t size{page_table->GetStackRegionEnd() - start}; + + CASCADE_RESULT(main_thread_stack_top, + page_table->AllocateAndMapMemory( + main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize, + KMemoryState::Stack, KMemoryPermission::ReadAndWrite)); + + main_thread_stack_top += main_thread_stack_size; + + return RESULT_SUCCESS; +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h new file mode 100644 index 000000000..961c0d9ba --- /dev/null +++ b/src/core/hle/kernel/k_process.h @@ -0,0 +1,480 @@ +// Copyright 2015 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include "common/common_types.h" +#include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_address_arbiter.h" +#include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/k_condition_variable.h" +#include "core/hle/kernel/k_synchronization_object.h" +#include "core/hle/kernel/process_capability.h" +#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/result.h" + +namespace Core { +class System; +} + +namespace FileSys { +class ProgramMetadata; +} + +namespace Kernel { + +class KernelCore; +class KPageTable; +class KResourceLimit; +class KThread; +class TLSPage; + +struct CodeSet; + +enum class MemoryRegion : u16 { + APPLICATION = 1, + SYSTEM = 2, + BASE = 3, +}; + +/** + * Indicates the status of a Process instance. + * + * @note These match the values as used by kernel, + * so new entries should only be added if RE + * shows that a new value has been introduced. + */ +enum class ProcessStatus { + Created, + CreatedWithDebuggerAttached, + Running, + WaitingForDebuggerToAttach, + DebuggerAttached, + Exiting, + Exited, + DebugBreak, +}; + +class KProcess final + : public KAutoObjectWithSlabHeapAndContainer { + KERNEL_AUTOOBJECT_TRAITS(KProcess, KSynchronizationObject); + +public: + explicit KProcess(KernelCore& kernel); + ~KProcess() override; + + enum : u64 { + /// Lowest allowed process ID for a kernel initial process. + InitialKIPIDMin = 1, + /// Highest allowed process ID for a kernel initial process. + InitialKIPIDMax = 80, + + /// Lowest allowed process ID for a userland process. + ProcessIDMin = 81, + /// Highest allowed process ID for a userland process. + ProcessIDMax = 0xFFFFFFFFFFFFFFFF, + }; + + // Used to determine how process IDs are assigned. + enum class ProcessType { + KernelInternal, + Userland, + }; + + static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; + + static ResultCode Initialize(KProcess* process, Core::System& system, std::string name, + ProcessType type); + + /// Gets a reference to the process' page table. + KPageTable& PageTable() { + return *page_table; + } + + /// Gets const a reference to the process' page table. + const KPageTable& PageTable() const { + return *page_table; + } + + /// Gets a reference to the process' handle table. + HandleTable& GetHandleTable() { + return handle_table; + } + + /// Gets a const reference to the process' handle table. + const HandleTable& GetHandleTable() const { + return handle_table; + } + + ResultCode SignalToAddress(VAddr address) { + return condition_var.SignalToAddress(address); + } + + ResultCode WaitForAddress(Handle handle, VAddr address, u32 tag) { + return condition_var.WaitForAddress(handle, address, tag); + } + + void SignalConditionVariable(u64 cv_key, int32_t count) { + return condition_var.Signal(cv_key, count); + } + + ResultCode WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) { + return condition_var.Wait(address, cv_key, tag, ns); + } + + ResultCode SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, + s32 count) { + return address_arbiter.SignalToAddress(address, signal_type, value, count); + } + + ResultCode WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value, + s64 timeout) { + return address_arbiter.WaitForAddress(address, arb_type, value, timeout); + } + + /// Gets the address to the process' dedicated TLS region. + VAddr GetTLSRegionAddress() const { + return tls_region_address; + } + + /// Gets the current status of the process + ProcessStatus GetStatus() const { + return status; + } + + /// Gets the unique ID that identifies this particular process. + u64 GetProcessID() const { + return process_id; + } + + /// Gets the title ID corresponding to this process. + u64 GetTitleID() const { + return program_id; + } + + /// Gets the resource limit descriptor for this process + KResourceLimit* GetResourceLimit() const; + + /// Gets the ideal CPU core ID for this process + u8 GetIdealCoreId() const { + return ideal_core; + } + + /// Checks if the specified thread priority is valid. + bool CheckThreadPriority(s32 prio) const { + return ((1ULL << prio) & GetPriorityMask()) != 0; + } + + /// Gets the bitmask of allowed cores that this process' threads can run on. + u64 GetCoreMask() const { + return capabilities.GetCoreMask(); + } + + /// Gets the bitmask of allowed thread priorities. + u64 GetPriorityMask() const { + return capabilities.GetPriorityMask(); + } + + /// Gets the amount of secure memory to allocate for memory management. + u32 GetSystemResourceSize() const { + return system_resource_size; + } + + /// Gets the amount of secure memory currently in use for memory management. + u32 GetSystemResourceUsage() const { + // On hardware, this returns the amount of system resource memory that has + // been used by the kernel. This is problematic for Yuzu to emulate, because + // system resource memory is used for page tables -- and yuzu doesn't really + // have a way to calculate how much memory is required for page tables for + // the current process at any given time. + // TODO: Is this even worth implementing? Games may retrieve this value via + // an SDK function that gets used + available system resource size for debug + // or diagnostic purposes. However, it seems unlikely that a game would make + // decisions based on how much system memory is dedicated to its page tables. + // Is returning a value other than zero wise? + return 0; + } + + /// Whether this process is an AArch64 or AArch32 process. + bool Is64BitProcess() const { + return is_64bit_process; + } + + [[nodiscard]] bool IsSuspended() const { + return is_suspended; + } + + void SetSuspended(bool suspended) { + is_suspended = suspended; + } + + /// Gets the total running time of the process instance in ticks. + u64 GetCPUTimeTicks() const { + return total_process_running_time_ticks; + } + + /// Updates the total running time, adding the given ticks to it. + void UpdateCPUTimeTicks(u64 ticks) { + total_process_running_time_ticks += ticks; + } + + /// Gets the process schedule count, used for thread yelding + s64 GetScheduledCount() const { + return schedule_count; + } + + /// Increments the process schedule count, used for thread yielding. + void IncrementScheduledCount() { + ++schedule_count; + } + + void IncrementThreadCount(); + void DecrementThreadCount(); + + void SetRunningThread(s32 core, KThread* thread, u64 idle_count) { + running_threads[core] = thread; + running_thread_idle_counts[core] = idle_count; + } + + void ClearRunningThread(KThread* thread) { + for (size_t i = 0; i < running_threads.size(); ++i) { + if (running_threads[i] == thread) { + running_threads[i] = nullptr; + } + } + } + + [[nodiscard]] KThread* GetRunningThread(s32 core) const { + return running_threads[core]; + } + + bool ReleaseUserException(KThread* thread); + + [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const { + ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); + return pinned_threads[core_id]; + } + + /// Gets 8 bytes of random data for svcGetInfo RandomEntropy + u64 GetRandomEntropy(std::size_t index) const { + return random_entropy.at(index); + } + + /// Retrieves the total physical memory available to this process in bytes. + u64 GetTotalPhysicalMemoryAvailable() const; + + /// Retrieves the total physical memory available to this process in bytes, + /// without the size of the personal system resource heap added to it. + u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const; + + /// Retrieves the total physical memory used by this process in bytes. + u64 GetTotalPhysicalMemoryUsed() const; + + /// Retrieves the total physical memory used by this process in bytes, + /// without the size of the personal system resource heap added to it. + u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; + + /// Gets the list of all threads created with this process as their owner. + const std::list& GetThreadList() const { + return thread_list; + } + + /// Registers a thread as being created under this process, + /// adding it to this process' thread list. + void RegisterThread(const KThread* thread); + + /// Unregisters a thread from this process, removing it + /// from this process' thread list. + void UnregisterThread(const KThread* thread); + + /// Clears the signaled state of the process if and only if it's signaled. + /// + /// @pre The process must not be already terminated. If this is called on a + /// terminated process, then ERR_INVALID_STATE will be returned. + /// + /// @pre The process must be in a signaled state. If this is called on a + /// process instance that is not signaled, ERR_INVALID_STATE will be + /// returned. + ResultCode Reset(); + + /** + * Loads process-specifics configuration info with metadata provided + * by an executable. + * + * @param metadata The provided metadata to load process specific info from. + * + * @returns RESULT_SUCCESS if all relevant metadata was able to be + * loaded and parsed. Otherwise, an error code is returned. + */ + ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size); + + /** + * Starts the main application thread for this process. + * + * @param main_thread_priority The priority for the main thread. + * @param stack_size The stack size for the main thread in bytes. + */ + void Run(s32 main_thread_priority, u64 stack_size); + + /** + * Prepares a process for termination by stopping all of its threads + * and clearing any other resources. + */ + void PrepareForTermination(); + + void LoadModule(CodeSet code_set, VAddr base_addr); + + virtual bool IsInitialized() const override { + return is_initialized; + } + + static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + + virtual void Finalize(); + + virtual u64 GetId() const override final { + return GetProcessID(); + } + + virtual bool IsSignaled() const override; + + void PinCurrentThread(); + void UnpinCurrentThread(); + + KLightLock& GetStateLock() { + return state_lock; + } + + /////////////////////////////////////////////////////////////////////////////////////////////// + // Thread-local storage management + + // Marks the next available region as used and returns the address of the slot. + [[nodiscard]] VAddr CreateTLSRegion(); + + // Frees a used TLS slot identified by the given address + void FreeTLSRegion(VAddr tls_address); + +private: + void PinThread(s32 core_id, KThread* thread) { + ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); + ASSERT(thread != nullptr); + ASSERT(pinned_threads[core_id] == nullptr); + pinned_threads[core_id] = thread; + } + + void UnpinThread(s32 core_id, KThread* thread) { + ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); + ASSERT(thread != nullptr); + ASSERT(pinned_threads[core_id] == thread); + pinned_threads[core_id] = nullptr; + } + + /// Changes the process status. If the status is different + /// from the current process status, then this will trigger + /// a process signal. + void ChangeStatus(ProcessStatus new_status); + + /// Allocates the main thread stack for the process, given the stack size in bytes. + ResultCode AllocateMainThreadStack(std::size_t stack_size); + + /// Memory manager for this process + std::unique_ptr page_table; + + /// Current status of the process + ProcessStatus status{}; + + /// The ID of this process + u64 process_id = 0; + + /// Title ID corresponding to the process + u64 program_id = 0; + + /// Specifies additional memory to be reserved for the process's memory management by the + /// system. When this is non-zero, secure memory is allocated and used for page table allocation + /// instead of using the normal global page tables/memory block management. + u32 system_resource_size = 0; + + /// Resource limit descriptor for this process + KResourceLimit* resource_limit{}; + + /// The ideal CPU core for this process, threads are scheduled on this core by default. + u8 ideal_core = 0; + + /// The Thread Local Storage area is allocated as processes create threads, + /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part + /// holds the TLS for a specific thread. This vector contains which parts are in use for each + /// page as a bitmask. + /// This vector will grow as more pages are allocated for new threads. + std::vector tls_pages; + + /// Contains the parsed process capability descriptors. + ProcessCapabilities capabilities; + + /// Whether or not this process is AArch64, or AArch32. + /// By default, we currently assume this is true, unless otherwise + /// specified by metadata provided to the process during loading. + bool is_64bit_process = true; + + /// Total running time for the process in ticks. + u64 total_process_running_time_ticks = 0; + + /// Per-process handle table for storing created object handles in. + HandleTable handle_table; + + /// Per-process address arbiter. + KAddressArbiter address_arbiter; + + /// The per-process mutex lock instance used for handling various + /// forms of services, such as lock arbitration, and condition + /// variable related facilities. + KConditionVariable condition_var; + + /// Address indicating the location of the process' dedicated TLS region. + VAddr tls_region_address = 0; + + /// Random values for svcGetInfo RandomEntropy + std::array random_entropy{}; + + /// List of threads that are running with this process as their owner. + std::list thread_list; + + /// Address of the top of the main thread's stack + VAddr main_thread_stack_top{}; + + /// Size of the main thread's stack + std::size_t main_thread_stack_size{}; + + /// Memory usage capacity for the process + std::size_t memory_usage_capacity{}; + + /// Process total image size + std::size_t image_size{}; + + /// Schedule count of this process + s64 schedule_count{}; + + bool is_signaled{}; + bool is_suspended{}; + bool is_initialized{}; + + std::atomic num_created_threads{}; + std::atomic num_threads{}; + u16 peak_num_threads{}; + + std::array running_threads{}; + std::array running_thread_idle_counts{}; + std::array pinned_threads{}; + + KThread* exception_thread{}; + + KLightLock state_lock; +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 38c6b50fa..0115fe6d1 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -15,12 +15,12 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/cpu_manager.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/time_manager.h" namespace Kernel { @@ -71,7 +71,7 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { } if (state.should_count_idle) { if (highest_thread != nullptr) { - if (Process* process = highest_thread->GetOwnerProcess(); process != nullptr) { + if (KProcess* process = highest_thread->GetOwnerProcess(); process != nullptr) { process->SetRunningThread(core_id, highest_thread, state.idle_count); } } else { @@ -104,7 +104,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) { if (top_thread != nullptr) { // If the thread has no waiters, we need to check if the process has a thread pinned. if (top_thread->GetNumKernelWaiters() == 0) { - if (Process* parent = top_thread->GetOwnerProcess(); parent != nullptr) { + if (KProcess* parent = top_thread->GetOwnerProcess(); parent != nullptr) { if (KThread* pinned = parent->GetPinnedThread(static_cast(core_id)); pinned != nullptr && pinned != top_thread) { // We prefer our parent's pinned thread if possible. However, we also don't @@ -411,7 +411,7 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - Process& cur_process = *kernel.CurrentProcess(); + KProcess& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -450,7 +450,7 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - Process& cur_process = *kernel.CurrentProcess(); + KProcess& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -538,7 +538,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - Process& cur_process = *kernel.CurrentProcess(); + KProcess& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -724,7 +724,7 @@ void KScheduler::ScheduleImpl() { current_thread.store(next_thread); - Process* const previous_process = system.Kernel().CurrentProcess(); + KProcess* const previous_process = system.Kernel().CurrentProcess(); UpdateLastContextSwitchTime(previous_thread, previous_process); @@ -780,7 +780,7 @@ void KScheduler::SwitchToCurrent() { } } -void KScheduler::UpdateLastContextSwitchTime(KThread* thread, Process* process) { +void KScheduler::UpdateLastContextSwitchTime(KThread* thread, KProcess* process) { const u64 prev_switch_ticks = last_context_switch_time; const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks(); const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 01387b892..282c1863b 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -24,7 +24,7 @@ class System; namespace Kernel { class KernelCore; -class Process; +class KProcess; class SchedulerLock; class KThread; @@ -165,7 +165,7 @@ private: * most recent tick count retrieved. No special arithmetic is * applied to it. */ - void UpdateLastContextSwitchTime(KThread* thread, Process* process); + void UpdateLastContextSwitchTime(KThread* thread, KProcess* process); static void OnSwitch(void* this_scheduler); void SwitchToCurrent(); @@ -197,7 +197,7 @@ private: class [[nodiscard]] KScopedSchedulerLock : KScopedLock { public: - explicit KScopedSchedulerLock(KernelCore & kernel); + explicit KScopedSchedulerLock(KernelCore& kernel); ~KScopedSchedulerLock(); }; diff --git a/src/core/hle/kernel/k_scoped_resource_reservation.h b/src/core/hle/kernel/k_scoped_resource_reservation.h index b160587c5..07272075d 100644 --- a/src/core/hle/kernel/k_scoped_resource_reservation.h +++ b/src/core/hle/kernel/k_scoped_resource_reservation.h @@ -8,8 +8,8 @@ #pragma once #include "common/common_types.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" -#include "core/hle/kernel/process.h" namespace Kernel { @@ -33,10 +33,10 @@ public: } } - explicit KScopedResourceReservation(const Process* p, LimitableResource r, s64 v, s64 t) + explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v, s64 t) : KScopedResourceReservation(p->GetResourceLimit(), r, v, t) {} - explicit KScopedResourceReservation(const Process* p, LimitableResource r, s64 v = 1) + explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v = 1) : KScopedResourceReservation(p->GetResourceLimit(), r, v) {} ~KScopedResourceReservation() noexcept { diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 863f9aa5f..3bc259693 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -13,12 +13,12 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_session.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/memory.h" namespace Kernel { diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp index 6f5947ce7..5e629d446 100644 --- a/src/core/hle/kernel/k_session.cpp +++ b/src/core/hle/kernel/k_session.cpp @@ -71,7 +71,7 @@ void KSession::OnClientClosed() { void KSession::PostDestroy(uintptr_t arg) { // Release the session count resource the owner process holds. - Process* owner = reinterpret_cast(arg); + KProcess* owner = reinterpret_cast(arg); owner->GetResourceLimit()->Release(LimitableResource::Sessions, 1); owner->Close(); } diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h index f29195fa0..d50e21f3f 100644 --- a/src/core/hle/kernel/k_session.h +++ b/src/core/hle/kernel/k_session.h @@ -89,7 +89,7 @@ private: std::atomic::type> atomic_state{ static_cast::type>(State::Invalid)}; KClientPort* port{}; - Process* process{}; + KProcess* process{}; bool initialized{}; }; diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index e91bc94bd..f137a182a 100644 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -19,7 +19,7 @@ KSharedMemory::~KSharedMemory() { } ResultCode KSharedMemory::Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, - Process* owner_process_, KPageLinkedList&& page_list_, + KProcess* owner_process_, KPageLinkedList&& page_list_, KMemoryPermission owner_permission_, KMemoryPermission user_permission_, PAddr physical_address_, std::size_t size_, std::string name_) { @@ -74,7 +74,7 @@ void KSharedMemory::Finalize() { KAutoObjectWithSlabHeapAndContainer::Finalize(); } -ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size, +ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t size, KMemoryPermission permissions) { const u64 page_count{(size + PageSize - 1) / PageSize}; diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 9547546a5..2d315c916 100644 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -11,7 +11,7 @@ #include "core/device_memory.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_page_linked_list.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/slab_helpers.h" #include "core/hle/result.h" @@ -28,7 +28,7 @@ public: ~KSharedMemory() override; ResultCode Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, - Process* owner_process_, KPageLinkedList&& page_list_, + KProcess* owner_process_, KPageLinkedList&& page_list_, KMemoryPermission owner_permission_, KMemoryPermission user_permission_, PAddr physical_address_, std::size_t size_, std::string name_); @@ -39,7 +39,7 @@ public: * @param size Size of the shared memory block to map * @param permissions Memory block map permissions (specified by SVC field) */ - ResultCode Map(Process& target_process, VAddr address, std::size_t size, + ResultCode Map(KProcess& target_process, VAddr address, std::size_t size, KMemoryPermission permissions); /** @@ -69,7 +69,7 @@ public: private: Core::DeviceMemory* device_memory; - Process* owner_process{}; + KProcess* owner_process{}; KPageLinkedList page_list; KMemoryPermission owner_permission{}; KMemoryPermission user_permission{}; diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index c59f3113c..3de0157ac 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -21,13 +21,13 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_condition_variable.h" #include "core/hle/kernel/k_memory_layout.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/result.h" @@ -65,7 +65,7 @@ KThread::KThread(KernelCore& kernel) KThread::~KThread() = default; ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, - s32 virt_core, Process* owner, ThreadType type) { + s32 virt_core, KProcess* owner, ThreadType type) { // Assert parameters are valid. ASSERT((type == ThreadType::Main) || (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); @@ -209,7 +209,7 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s } ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, - VAddr user_stack_top, s32 prio, s32 core, Process* owner, + VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, ThreadType type, std::function&& init_func, void* init_func_parameter) { // Initialize the thread. @@ -242,7 +242,7 @@ ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func, uintptr_t arg, VAddr user_stack_top, - s32 prio, s32 virt_core, Process* owner) { + s32 prio, s32 virt_core, KProcess* owner) { system.Kernel().GlobalSchedulerContext().AddThread(thread); return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), @@ -250,7 +250,7 @@ ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, } void KThread::PostDestroy(uintptr_t arg) { - Process* owner = reinterpret_cast(arg & ~1ULL); + KProcess* owner = reinterpret_cast(arg & ~1ULL); const bool resource_limit_release_hint = (arg & 1); const s64 hint_value = (resource_limit_release_hint ? 0 : 1); if (owner != nullptr) { diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 5b943b18b..4145ef56c 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -37,7 +37,7 @@ namespace Kernel { class GlobalSchedulerContext; class KernelCore; -class Process; +class KProcess; class KScheduler; class KThreadQueue; @@ -105,7 +105,7 @@ class KThread final : public KAutoObjectWithSlabHeapAndContainer&& init_func, void* init_func_parameter); @@ -669,7 +669,7 @@ private: std::atomic cpu_time{}; KSynchronizationObject* synced_object{}; VAddr address_key{}; - Process* parent{}; + KProcess* parent{}; VAddr kernel_stack_top{}; u32* light_ipc_data{}; VAddr tls_address{}; diff --git a/src/core/hle/kernel/k_transfer_memory.cpp b/src/core/hle/kernel/k_transfer_memory.cpp index 09c067f95..201617d32 100644 --- a/src/core/hle/kernel/k_transfer_memory.cpp +++ b/src/core/hle/kernel/k_transfer_memory.cpp @@ -2,10 +2,10 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" namespace Kernel { @@ -37,7 +37,7 @@ void KTransferMemory::Finalize() { } void KTransferMemory::PostDestroy(uintptr_t arg) { - Process* owner = reinterpret_cast(arg); + KProcess* owner = reinterpret_cast(arg); owner->GetResourceLimit()->Release(LimitableResource::TransferMemory, 1); owner->Close(); } diff --git a/src/core/hle/kernel/k_transfer_memory.h b/src/core/hle/kernel/k_transfer_memory.h index 1e4fa9323..f56398b9c 100644 --- a/src/core/hle/kernel/k_transfer_memory.h +++ b/src/core/hle/kernel/k_transfer_memory.h @@ -19,7 +19,7 @@ class Memory; namespace Kernel { class KernelCore; -class Process; +class KProcess; class KTransferMemory final : public KAutoObjectWithSlabHeapAndContainer { @@ -43,7 +43,7 @@ public: static void PostDestroy(uintptr_t arg); - Process* GetOwner() const { + KProcess* GetOwner() const { return owner; } @@ -56,7 +56,7 @@ public: } private: - Process* owner{}; + KProcess* owner{}; VAddr address{}; Svc::MemoryPermission owner_perm{}; size_t size{}; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 409bcfaa0..718525c4c 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -31,6 +31,7 @@ #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_shared_memory.h" @@ -38,7 +39,6 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" @@ -98,8 +98,8 @@ struct KernelCore::Impl { service_threads.clear(); next_object_id = 0; - next_kernel_process_id = Process::InitialKIPIDMin; - next_user_process_id = Process::ProcessIDMin; + next_kernel_process_id = KProcess::InitialKIPIDMin; + next_user_process_id = KProcess::ProcessIDMin; next_thread_id = 1; for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { @@ -220,7 +220,7 @@ struct KernelCore::Impl { } } - void MakeCurrentProcess(Process* process) { + void MakeCurrentProcess(KProcess* process) { current_process = process; if (process == nullptr) { return; @@ -632,13 +632,13 @@ struct KernelCore::Impl { } std::atomic next_object_id{0}; - std::atomic next_kernel_process_id{Process::InitialKIPIDMin}; - std::atomic next_user_process_id{Process::ProcessIDMin}; + std::atomic next_kernel_process_id{KProcess::InitialKIPIDMin}; + std::atomic next_user_process_id{KProcess::ProcessIDMin}; std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. - std::vector process_list; - Process* current_process{}; + std::vector process_list; + KProcess* current_process{}; std::unique_ptr global_scheduler_context; Kernel::TimeManager time_manager; @@ -725,23 +725,23 @@ KScopedAutoObject KernelCore::RetrieveThreadFromGlobalHandleTable(Handl return impl->global_handle_table.GetObject(handle); } -void KernelCore::AppendNewProcess(Process* process) { +void KernelCore::AppendNewProcess(KProcess* process) { impl->process_list.push_back(process); } -void KernelCore::MakeCurrentProcess(Process* process) { +void KernelCore::MakeCurrentProcess(KProcess* process) { impl->MakeCurrentProcess(process); } -Process* KernelCore::CurrentProcess() { +KProcess* KernelCore::CurrentProcess() { return impl->current_process; } -const Process* KernelCore::CurrentProcess() const { +const KProcess* KernelCore::CurrentProcess() const { return impl->current_process; } -const std::vector& KernelCore::GetProcessList() const { +const std::vector& KernelCore::GetProcessList() const { return impl->process_list; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index de7f83423..0dd9deaeb 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -37,7 +37,7 @@ class KEvent; class KLinkedListNode; class KMemoryManager; class KPort; -class Process; +class KProcess; class KResourceLimit; class KScheduler; class KSession; @@ -101,19 +101,19 @@ public: KScopedAutoObject RetrieveThreadFromGlobalHandleTable(Handle handle) const; /// Adds the given shared pointer to an internal list of active processes. - void AppendNewProcess(Process* process); + void AppendNewProcess(KProcess* process); /// Makes the given process the new current process. - void MakeCurrentProcess(Process* process); + void MakeCurrentProcess(KProcess* process); /// Retrieves a pointer to the current process. - Process* CurrentProcess(); + KProcess* CurrentProcess(); /// Retrieves a const pointer to the current process. - const Process* CurrentProcess() const; + const KProcess* CurrentProcess() const; /// Retrieves the list of processes. - const std::vector& GetProcessList() const; + const std::vector& GetProcessList() const; /// Gets the sole instance of the global scheduler Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); @@ -274,7 +274,7 @@ public: return slab_heap_container->linked_list_node; } else if constexpr (std::is_same_v) { return slab_heap_container->port; - } else if constexpr (std::is_same_v) { + } else if constexpr (std::is_same_v) { return slab_heap_container->process; } else if constexpr (std::is_same_v) { return slab_heap_container->resource_limit; @@ -292,7 +292,7 @@ public: } private: - friend class Process; + friend class KProcess; friend class KThread; /// Creates a new object ID, incrementing the internal object ID counter. @@ -325,7 +325,7 @@ private: KSlabHeap event; KSlabHeap linked_list_node; KSlabHeap port; - KSlabHeap process; + KSlabHeap process; KSlabHeap resource_limit; KSlabHeap session; KSlabHeap shared_memory; diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp deleted file mode 100644 index 315640bea..000000000 --- a/src/core/hle/kernel/process.cpp +++ /dev/null @@ -1,505 +0,0 @@ -// Copyright 2015 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include -#include -#include -#include -#include -#include "common/alignment.h" -#include "common/assert.h" -#include "common/logging/log.h" -#include "common/settings.h" -#include "core/core.h" -#include "core/device_memory.h" -#include "core/file_sys/program_metadata.h" -#include "core/hle/kernel/code_set.h" -#include "core/hle/kernel/k_memory_block_manager.h" -#include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_resource_limit.h" -#include "core/hle/kernel/k_scheduler.h" -#include "core/hle/kernel/k_scoped_resource_reservation.h" -#include "core/hle/kernel/k_slab_heap.h" -#include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" -#include "core/hle/kernel/svc_results.h" -#include "core/hle/lock.h" -#include "core/memory.h" - -namespace Kernel { -namespace { -/** - * Sets up the primary application thread - * - * @param system The system instance to create the main thread under. - * @param owner_process The parent process for the main thread - * @param priority The priority to give the main thread - */ -void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, VAddr stack_top) { - const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); - ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); - - KThread* thread = KThread::Create(system.Kernel()); - ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, - owner_process.GetIdealCoreId(), &owner_process) - .IsSuccess()); - - // Register 1 must be a handle to the main thread - Handle thread_handle{}; - owner_process.GetHandleTable().Add(&thread_handle, thread); - - thread->SetName("main"); - thread->GetContext32().cpu_registers[0] = 0; - thread->GetContext64().cpu_registers[0] = 0; - thread->GetContext32().cpu_registers[1] = thread_handle; - thread->GetContext64().cpu_registers[1] = thread_handle; - - auto& kernel = system.Kernel(); - // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires - { - KScopedSchedulerLock lock{kernel}; - thread->SetState(ThreadState::Runnable); - } -} -} // Anonymous namespace - -// Represents a page used for thread-local storage. -// -// Each TLS page contains slots that may be used by processes and threads. -// Every process and thread is created with a slot in some arbitrary page -// (whichever page happens to have an available slot). -class TLSPage { -public: - static constexpr std::size_t num_slot_entries = - Core::Memory::PAGE_SIZE / Core::Memory::TLS_ENTRY_SIZE; - - explicit TLSPage(VAddr address) : base_address{address} {} - - bool HasAvailableSlots() const { - return !is_slot_used.all(); - } - - VAddr GetBaseAddress() const { - return base_address; - } - - std::optional ReserveSlot() { - for (std::size_t i = 0; i < is_slot_used.size(); i++) { - if (is_slot_used[i]) { - continue; - } - - is_slot_used[i] = true; - return base_address + (i * Core::Memory::TLS_ENTRY_SIZE); - } - - return std::nullopt; - } - - void ReleaseSlot(VAddr address) { - // Ensure that all given addresses are consistent with how TLS pages - // are intended to be used when releasing slots. - ASSERT(IsWithinPage(address)); - ASSERT((address % Core::Memory::TLS_ENTRY_SIZE) == 0); - - const std::size_t index = (address - base_address) / Core::Memory::TLS_ENTRY_SIZE; - is_slot_used[index] = false; - } - -private: - bool IsWithinPage(VAddr address) const { - return base_address <= address && address < base_address + Core::Memory::PAGE_SIZE; - } - - VAddr base_address; - std::bitset is_slot_used; -}; - -ResultCode Process::Initialize(Process* process, Core::System& system, std::string name, - ProcessType type) { - auto& kernel = system.Kernel(); - - process->name = std::move(name); - - process->resource_limit = kernel.GetSystemResourceLimit(); - process->status = ProcessStatus::Created; - process->program_id = 0; - process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() - : kernel.CreateNewUserProcessID(); - process->capabilities.InitializeForMetadatalessProcess(); - process->is_initialized = true; - - std::mt19937 rng(Settings::values.rng_seed.GetValue().value_or(std::time(nullptr))); - std::uniform_int_distribution distribution; - std::generate(process->random_entropy.begin(), process->random_entropy.end(), - [&] { return distribution(rng); }); - - kernel.AppendNewProcess(process); - - // Open a reference to the resource limit. - process->resource_limit->Open(); - - return RESULT_SUCCESS; -} - -KResourceLimit* Process::GetResourceLimit() const { - return resource_limit; -} - -void Process::IncrementThreadCount() { - ASSERT(num_threads >= 0); - num_created_threads++; - - if (const auto count = ++num_threads; count > peak_num_threads) { - peak_num_threads = count; - } -} - -void Process::DecrementThreadCount() { - ASSERT(num_threads > 0); - - if (const auto count = --num_threads; count == 0) { - UNIMPLEMENTED_MSG("Process termination is not implemented!"); - } -} - -u64 Process::GetTotalPhysicalMemoryAvailable() const { - const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + - page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + - main_thread_stack_size}; - if (const auto pool_size = kernel.MemoryManager().GetSize(KMemoryManager::Pool::Application); - capacity != pool_size) { - LOG_WARNING(Kernel, "capacity {} != application pool size {}", capacity, pool_size); - } - if (capacity < memory_usage_capacity) { - return capacity; - } - return memory_usage_capacity; -} - -u64 Process::GetTotalPhysicalMemoryAvailableWithoutSystemResource() const { - return GetTotalPhysicalMemoryAvailable() - GetSystemResourceSize(); -} - -u64 Process::GetTotalPhysicalMemoryUsed() const { - return image_size + main_thread_stack_size + page_table->GetTotalHeapSize() + - GetSystemResourceSize(); -} - -u64 Process::GetTotalPhysicalMemoryUsedWithoutSystemResource() const { - return GetTotalPhysicalMemoryUsed() - GetSystemResourceUsage(); -} - -bool Process::ReleaseUserException(KThread* thread) { - KScopedSchedulerLock sl{kernel}; - - if (exception_thread == thread) { - exception_thread = nullptr; - - // Remove waiter thread. - s32 num_waiters{}; - KThread* next = thread->RemoveWaiterByKey( - std::addressof(num_waiters), - reinterpret_cast(std::addressof(exception_thread))); - if (next != nullptr) { - if (next->GetState() == ThreadState::Waiting) { - next->SetState(ThreadState::Runnable); - } else { - KScheduler::SetSchedulerUpdateNeeded(kernel); - } - } - - return true; - } else { - return false; - } -} - -void Process::PinCurrentThread() { - ASSERT(kernel.GlobalSchedulerContext().IsLocked()); - - // Get the current thread. - const s32 core_id = GetCurrentCoreId(kernel); - KThread* cur_thread = GetCurrentThreadPointer(kernel); - - // Pin it. - PinThread(core_id, cur_thread); - cur_thread->Pin(); - - // An update is needed. - KScheduler::SetSchedulerUpdateNeeded(kernel); -} - -void Process::UnpinCurrentThread() { - ASSERT(kernel.GlobalSchedulerContext().IsLocked()); - - // Get the current thread. - const s32 core_id = GetCurrentCoreId(kernel); - KThread* cur_thread = GetCurrentThreadPointer(kernel); - - // Unpin it. - cur_thread->Unpin(); - UnpinThread(core_id, cur_thread); - - // An update is needed. - KScheduler::SetSchedulerUpdateNeeded(kernel); -} - -void Process::RegisterThread(const KThread* thread) { - thread_list.push_back(thread); -} - -void Process::UnregisterThread(const KThread* thread) { - thread_list.remove(thread); -} - -ResultCode Process::Reset() { - // Lock the process and the scheduler. - KScopedLightLock lk(state_lock); - KScopedSchedulerLock sl{kernel}; - - // Validate that we're in a state that we can reset. - R_UNLESS(status != ProcessStatus::Exited, ResultInvalidState); - R_UNLESS(is_signaled, ResultInvalidState); - - // Clear signaled. - is_signaled = false; - return RESULT_SUCCESS; -} - -ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, - std::size_t code_size) { - program_id = metadata.GetTitleID(); - ideal_core = metadata.GetMainThreadCore(); - is_64bit_process = metadata.Is64BitProgram(); - system_resource_size = metadata.GetSystemResourceSize(); - image_size = code_size; - - KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, - code_size + system_resource_size); - if (!memory_reservation.Succeeded()) { - LOG_ERROR(Kernel, "Could not reserve process memory requirements of size {:X} bytes", - code_size + system_resource_size); - return ResultLimitReached; - } - // Initialize proces address space - if (const ResultCode result{ - page_table->InitializeForProcess(metadata.GetAddressSpaceType(), false, 0x8000000, - code_size, KMemoryManager::Pool::Application)}; - result.IsError()) { - return result; - } - - // Map process code region - if (const ResultCode result{page_table->MapProcessCode(page_table->GetCodeRegionStart(), - code_size / PageSize, KMemoryState::Code, - KMemoryPermission::None)}; - result.IsError()) { - return result; - } - - // Initialize process capabilities - const auto& caps{metadata.GetKernelCapabilities()}; - if (const ResultCode result{ - capabilities.InitializeForUserProcess(caps.data(), caps.size(), *page_table)}; - result.IsError()) { - return result; - } - - // Set memory usage capacity - switch (metadata.GetAddressSpaceType()) { - case FileSys::ProgramAddressSpaceType::Is32Bit: - case FileSys::ProgramAddressSpaceType::Is36Bit: - case FileSys::ProgramAddressSpaceType::Is39Bit: - memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart(); - break; - - case FileSys::ProgramAddressSpaceType::Is32BitNoMap: - memory_usage_capacity = page_table->GetHeapRegionEnd() - page_table->GetHeapRegionStart() + - page_table->GetAliasRegionEnd() - page_table->GetAliasRegionStart(); - break; - - default: - UNREACHABLE(); - } - - // Create TLS region - tls_region_address = CreateTLSRegion(); - memory_reservation.Commit(); - - return handle_table.SetSize(capabilities.GetHandleTableSize()); -} - -void Process::Run(s32 main_thread_priority, u64 stack_size) { - AllocateMainThreadStack(stack_size); - resource_limit->Reserve(LimitableResource::Threads, 1); - resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); - - const std::size_t heap_capacity{memory_usage_capacity - main_thread_stack_size - image_size}; - ASSERT(!page_table->SetHeapCapacity(heap_capacity).IsError()); - - ChangeStatus(ProcessStatus::Running); - - SetupMainThread(kernel.System(), *this, main_thread_priority, main_thread_stack_top); -} - -void Process::PrepareForTermination() { - ChangeStatus(ProcessStatus::Exiting); - - const auto stop_threads = [this](const std::vector& thread_list) { - for (auto& thread : thread_list) { - if (thread->GetOwnerProcess() != this) - continue; - - if (thread == kernel.CurrentScheduler()->GetCurrentThread()) - continue; - - // TODO(Subv): When are the other running/ready threads terminated? - ASSERT_MSG(thread->GetState() == ThreadState::Waiting, - "Exiting processes with non-waiting threads is currently unimplemented"); - - thread->Exit(); - } - }; - - stop_threads(kernel.System().GlobalSchedulerContext().GetThreadList()); - - FreeTLSRegion(tls_region_address); - tls_region_address = 0; - - if (resource_limit) { - resource_limit->Release(LimitableResource::PhysicalMemory, - main_thread_stack_size + image_size); - } - - ChangeStatus(ProcessStatus::Exited); -} - -void Process::Finalize() { - // Release memory to the resource limit. - if (resource_limit != nullptr) { - resource_limit->Close(); - } - - // Perform inherited finalization. - KAutoObjectWithSlabHeapAndContainer::Finalize(); -} - -/** - * Attempts to find a TLS page that contains a free slot for - * use by a thread. - * - * @returns If a page with an available slot is found, then an iterator - * pointing to the page is returned. Otherwise the end iterator - * is returned instead. - */ -static auto FindTLSPageWithAvailableSlots(std::vector& tls_pages) { - return std::find_if(tls_pages.begin(), tls_pages.end(), - [](const auto& page) { return page.HasAvailableSlots(); }); -} - -VAddr Process::CreateTLSRegion() { - KScopedSchedulerLock lock(kernel); - if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; - tls_page_iter != tls_pages.cend()) { - return *tls_page_iter->ReserveSlot(); - } - - Page* const tls_page_ptr{kernel.GetUserSlabHeapPages().Allocate()}; - ASSERT(tls_page_ptr); - - const VAddr start{page_table->GetKernelMapRegionStart()}; - const VAddr size{page_table->GetKernelMapRegionEnd() - start}; - const PAddr tls_map_addr{kernel.System().DeviceMemory().GetPhysicalAddr(tls_page_ptr)}; - const VAddr tls_page_addr{page_table - ->AllocateAndMapMemory(1, PageSize, true, start, size / PageSize, - KMemoryState::ThreadLocal, - KMemoryPermission::ReadAndWrite, - tls_map_addr) - .ValueOr(0)}; - - ASSERT(tls_page_addr); - - std::memset(tls_page_ptr, 0, PageSize); - tls_pages.emplace_back(tls_page_addr); - - const auto reserve_result{tls_pages.back().ReserveSlot()}; - ASSERT(reserve_result.has_value()); - - return *reserve_result; -} - -void Process::FreeTLSRegion(VAddr tls_address) { - KScopedSchedulerLock lock(kernel); - const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); - auto iter = - std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { - return page.GetBaseAddress() == aligned_address; - }); - - // Something has gone very wrong if we're freeing a region - // with no actual page available. - ASSERT(iter != tls_pages.cend()); - - iter->ReleaseSlot(tls_address); -} - -void Process::LoadModule(CodeSet code_set, VAddr base_addr) { - std::lock_guard lock{HLE::g_hle_lock}; - const auto ReprotectSegment = [&](const CodeSet::Segment& segment, - KMemoryPermission permission) { - page_table->SetCodeMemoryPermission(segment.addr + base_addr, segment.size, permission); - }; - - kernel.System().Memory().WriteBlock(*this, base_addr, code_set.memory.data(), - code_set.memory.size()); - - ReprotectSegment(code_set.CodeSegment(), KMemoryPermission::ReadAndExecute); - ReprotectSegment(code_set.RODataSegment(), KMemoryPermission::Read); - ReprotectSegment(code_set.DataSegment(), KMemoryPermission::ReadAndWrite); -} - -bool Process::IsSignaled() const { - ASSERT(kernel.GlobalSchedulerContext().IsLocked()); - return is_signaled; -} - -Process::Process(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer{kernel}, - page_table{std::make_unique(kernel.System())}, handle_table{kernel}, - address_arbiter{kernel.System()}, condition_var{kernel.System()}, state_lock{kernel} {} - -Process::~Process() = default; - -void Process::ChangeStatus(ProcessStatus new_status) { - if (status == new_status) { - return; - } - - status = new_status; - is_signaled = true; - NotifyAvailable(); -} - -ResultCode Process::AllocateMainThreadStack(std::size_t stack_size) { - ASSERT(stack_size); - - // The kernel always ensures that the given stack size is page aligned. - main_thread_stack_size = Common::AlignUp(stack_size, PageSize); - - const VAddr start{page_table->GetStackRegionStart()}; - const std::size_t size{page_table->GetStackRegionEnd() - start}; - - CASCADE_RESULT(main_thread_stack_top, - page_table->AllocateAndMapMemory( - main_thread_stack_size / PageSize, PageSize, false, start, size / PageSize, - KMemoryState::Stack, KMemoryPermission::ReadAndWrite)); - - main_thread_stack_top += main_thread_stack_size; - - return RESULT_SUCCESS; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h deleted file mode 100644 index b775e1fd0..000000000 --- a/src/core/hle/kernel/process.h +++ /dev/null @@ -1,479 +0,0 @@ -// Copyright 2015 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include -#include -#include -#include -#include "common/common_types.h" -#include "core/hle/kernel/handle_table.h" -#include "core/hle/kernel/k_address_arbiter.h" -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/k_condition_variable.h" -#include "core/hle/kernel/k_synchronization_object.h" -#include "core/hle/kernel/process_capability.h" -#include "core/hle/kernel/slab_helpers.h" -#include "core/hle/result.h" - -namespace Core { -class System; -} - -namespace FileSys { -class ProgramMetadata; -} - -namespace Kernel { - -class KernelCore; -class KPageTable; -class KResourceLimit; -class KThread; -class TLSPage; - -struct CodeSet; - -enum class MemoryRegion : u16 { - APPLICATION = 1, - SYSTEM = 2, - BASE = 3, -}; - -/** - * Indicates the status of a Process instance. - * - * @note These match the values as used by kernel, - * so new entries should only be added if RE - * shows that a new value has been introduced. - */ -enum class ProcessStatus { - Created, - CreatedWithDebuggerAttached, - Running, - WaitingForDebuggerToAttach, - DebuggerAttached, - Exiting, - Exited, - DebugBreak, -}; - -class Process final : public KAutoObjectWithSlabHeapAndContainer { - KERNEL_AUTOOBJECT_TRAITS(Process, KSynchronizationObject); - -public: - explicit Process(KernelCore& kernel); - ~Process() override; - - enum : u64 { - /// Lowest allowed process ID for a kernel initial process. - InitialKIPIDMin = 1, - /// Highest allowed process ID for a kernel initial process. - InitialKIPIDMax = 80, - - /// Lowest allowed process ID for a userland process. - ProcessIDMin = 81, - /// Highest allowed process ID for a userland process. - ProcessIDMax = 0xFFFFFFFFFFFFFFFF, - }; - - // Used to determine how process IDs are assigned. - enum class ProcessType { - KernelInternal, - Userland, - }; - - static constexpr std::size_t RANDOM_ENTROPY_SIZE = 4; - - static ResultCode Initialize(Process* process, Core::System& system, std::string name, - ProcessType type); - - /// Gets a reference to the process' page table. - KPageTable& PageTable() { - return *page_table; - } - - /// Gets const a reference to the process' page table. - const KPageTable& PageTable() const { - return *page_table; - } - - /// Gets a reference to the process' handle table. - HandleTable& GetHandleTable() { - return handle_table; - } - - /// Gets a const reference to the process' handle table. - const HandleTable& GetHandleTable() const { - return handle_table; - } - - ResultCode SignalToAddress(VAddr address) { - return condition_var.SignalToAddress(address); - } - - ResultCode WaitForAddress(Handle handle, VAddr address, u32 tag) { - return condition_var.WaitForAddress(handle, address, tag); - } - - void SignalConditionVariable(u64 cv_key, int32_t count) { - return condition_var.Signal(cv_key, count); - } - - ResultCode WaitConditionVariable(VAddr address, u64 cv_key, u32 tag, s64 ns) { - return condition_var.Wait(address, cv_key, tag, ns); - } - - ResultCode SignalAddressArbiter(VAddr address, Svc::SignalType signal_type, s32 value, - s32 count) { - return address_arbiter.SignalToAddress(address, signal_type, value, count); - } - - ResultCode WaitAddressArbiter(VAddr address, Svc::ArbitrationType arb_type, s32 value, - s64 timeout) { - return address_arbiter.WaitForAddress(address, arb_type, value, timeout); - } - - /// Gets the address to the process' dedicated TLS region. - VAddr GetTLSRegionAddress() const { - return tls_region_address; - } - - /// Gets the current status of the process - ProcessStatus GetStatus() const { - return status; - } - - /// Gets the unique ID that identifies this particular process. - u64 GetProcessID() const { - return process_id; - } - - /// Gets the title ID corresponding to this process. - u64 GetTitleID() const { - return program_id; - } - - /// Gets the resource limit descriptor for this process - KResourceLimit* GetResourceLimit() const; - - /// Gets the ideal CPU core ID for this process - u8 GetIdealCoreId() const { - return ideal_core; - } - - /// Checks if the specified thread priority is valid. - bool CheckThreadPriority(s32 prio) const { - return ((1ULL << prio) & GetPriorityMask()) != 0; - } - - /// Gets the bitmask of allowed cores that this process' threads can run on. - u64 GetCoreMask() const { - return capabilities.GetCoreMask(); - } - - /// Gets the bitmask of allowed thread priorities. - u64 GetPriorityMask() const { - return capabilities.GetPriorityMask(); - } - - /// Gets the amount of secure memory to allocate for memory management. - u32 GetSystemResourceSize() const { - return system_resource_size; - } - - /// Gets the amount of secure memory currently in use for memory management. - u32 GetSystemResourceUsage() const { - // On hardware, this returns the amount of system resource memory that has - // been used by the kernel. This is problematic for Yuzu to emulate, because - // system resource memory is used for page tables -- and yuzu doesn't really - // have a way to calculate how much memory is required for page tables for - // the current process at any given time. - // TODO: Is this even worth implementing? Games may retrieve this value via - // an SDK function that gets used + available system resource size for debug - // or diagnostic purposes. However, it seems unlikely that a game would make - // decisions based on how much system memory is dedicated to its page tables. - // Is returning a value other than zero wise? - return 0; - } - - /// Whether this process is an AArch64 or AArch32 process. - bool Is64BitProcess() const { - return is_64bit_process; - } - - [[nodiscard]] bool IsSuspended() const { - return is_suspended; - } - - void SetSuspended(bool suspended) { - is_suspended = suspended; - } - - /// Gets the total running time of the process instance in ticks. - u64 GetCPUTimeTicks() const { - return total_process_running_time_ticks; - } - - /// Updates the total running time, adding the given ticks to it. - void UpdateCPUTimeTicks(u64 ticks) { - total_process_running_time_ticks += ticks; - } - - /// Gets the process schedule count, used for thread yelding - s64 GetScheduledCount() const { - return schedule_count; - } - - /// Increments the process schedule count, used for thread yielding. - void IncrementScheduledCount() { - ++schedule_count; - } - - void IncrementThreadCount(); - void DecrementThreadCount(); - - void SetRunningThread(s32 core, KThread* thread, u64 idle_count) { - running_threads[core] = thread; - running_thread_idle_counts[core] = idle_count; - } - - void ClearRunningThread(KThread* thread) { - for (size_t i = 0; i < running_threads.size(); ++i) { - if (running_threads[i] == thread) { - running_threads[i] = nullptr; - } - } - } - - [[nodiscard]] KThread* GetRunningThread(s32 core) const { - return running_threads[core]; - } - - bool ReleaseUserException(KThread* thread); - - [[nodiscard]] KThread* GetPinnedThread(s32 core_id) const { - ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); - return pinned_threads[core_id]; - } - - /// Gets 8 bytes of random data for svcGetInfo RandomEntropy - u64 GetRandomEntropy(std::size_t index) const { - return random_entropy.at(index); - } - - /// Retrieves the total physical memory available to this process in bytes. - u64 GetTotalPhysicalMemoryAvailable() const; - - /// Retrieves the total physical memory available to this process in bytes, - /// without the size of the personal system resource heap added to it. - u64 GetTotalPhysicalMemoryAvailableWithoutSystemResource() const; - - /// Retrieves the total physical memory used by this process in bytes. - u64 GetTotalPhysicalMemoryUsed() const; - - /// Retrieves the total physical memory used by this process in bytes, - /// without the size of the personal system resource heap added to it. - u64 GetTotalPhysicalMemoryUsedWithoutSystemResource() const; - - /// Gets the list of all threads created with this process as their owner. - const std::list& GetThreadList() const { - return thread_list; - } - - /// Registers a thread as being created under this process, - /// adding it to this process' thread list. - void RegisterThread(const KThread* thread); - - /// Unregisters a thread from this process, removing it - /// from this process' thread list. - void UnregisterThread(const KThread* thread); - - /// Clears the signaled state of the process if and only if it's signaled. - /// - /// @pre The process must not be already terminated. If this is called on a - /// terminated process, then ERR_INVALID_STATE will be returned. - /// - /// @pre The process must be in a signaled state. If this is called on a - /// process instance that is not signaled, ERR_INVALID_STATE will be - /// returned. - ResultCode Reset(); - - /** - * Loads process-specifics configuration info with metadata provided - * by an executable. - * - * @param metadata The provided metadata to load process specific info from. - * - * @returns RESULT_SUCCESS if all relevant metadata was able to be - * loaded and parsed. Otherwise, an error code is returned. - */ - ResultCode LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std::size_t code_size); - - /** - * Starts the main application thread for this process. - * - * @param main_thread_priority The priority for the main thread. - * @param stack_size The stack size for the main thread in bytes. - */ - void Run(s32 main_thread_priority, u64 stack_size); - - /** - * Prepares a process for termination by stopping all of its threads - * and clearing any other resources. - */ - void PrepareForTermination(); - - void LoadModule(CodeSet code_set, VAddr base_addr); - - virtual bool IsInitialized() const override { - return is_initialized; - } - - static void PostDestroy([[maybe_unused]] uintptr_t arg) {} - - virtual void Finalize(); - - virtual u64 GetId() const override final { - return GetProcessID(); - } - - virtual bool IsSignaled() const override; - - void PinCurrentThread(); - void UnpinCurrentThread(); - - KLightLock& GetStateLock() { - return state_lock; - } - - /////////////////////////////////////////////////////////////////////////////////////////////// - // Thread-local storage management - - // Marks the next available region as used and returns the address of the slot. - [[nodiscard]] VAddr CreateTLSRegion(); - - // Frees a used TLS slot identified by the given address - void FreeTLSRegion(VAddr tls_address); - -private: - void PinThread(s32 core_id, KThread* thread) { - ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); - ASSERT(thread != nullptr); - ASSERT(pinned_threads[core_id] == nullptr); - pinned_threads[core_id] = thread; - } - - void UnpinThread(s32 core_id, KThread* thread) { - ASSERT(0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); - ASSERT(thread != nullptr); - ASSERT(pinned_threads[core_id] == thread); - pinned_threads[core_id] = nullptr; - } - - /// Changes the process status. If the status is different - /// from the current process status, then this will trigger - /// a process signal. - void ChangeStatus(ProcessStatus new_status); - - /// Allocates the main thread stack for the process, given the stack size in bytes. - ResultCode AllocateMainThreadStack(std::size_t stack_size); - - /// Memory manager for this process - std::unique_ptr page_table; - - /// Current status of the process - ProcessStatus status{}; - - /// The ID of this process - u64 process_id = 0; - - /// Title ID corresponding to the process - u64 program_id = 0; - - /// Specifies additional memory to be reserved for the process's memory management by the - /// system. When this is non-zero, secure memory is allocated and used for page table allocation - /// instead of using the normal global page tables/memory block management. - u32 system_resource_size = 0; - - /// Resource limit descriptor for this process - KResourceLimit* resource_limit{}; - - /// The ideal CPU core for this process, threads are scheduled on this core by default. - u8 ideal_core = 0; - - /// The Thread Local Storage area is allocated as processes create threads, - /// each TLS area is 0x200 bytes, so one page (0x1000) is split up in 8 parts, and each part - /// holds the TLS for a specific thread. This vector contains which parts are in use for each - /// page as a bitmask. - /// This vector will grow as more pages are allocated for new threads. - std::vector tls_pages; - - /// Contains the parsed process capability descriptors. - ProcessCapabilities capabilities; - - /// Whether or not this process is AArch64, or AArch32. - /// By default, we currently assume this is true, unless otherwise - /// specified by metadata provided to the process during loading. - bool is_64bit_process = true; - - /// Total running time for the process in ticks. - u64 total_process_running_time_ticks = 0; - - /// Per-process handle table for storing created object handles in. - HandleTable handle_table; - - /// Per-process address arbiter. - KAddressArbiter address_arbiter; - - /// The per-process mutex lock instance used for handling various - /// forms of services, such as lock arbitration, and condition - /// variable related facilities. - KConditionVariable condition_var; - - /// Address indicating the location of the process' dedicated TLS region. - VAddr tls_region_address = 0; - - /// Random values for svcGetInfo RandomEntropy - std::array random_entropy{}; - - /// List of threads that are running with this process as their owner. - std::list thread_list; - - /// Address of the top of the main thread's stack - VAddr main_thread_stack_top{}; - - /// Size of the main thread's stack - std::size_t main_thread_stack_size{}; - - /// Memory usage capacity for the process - std::size_t memory_usage_capacity{}; - - /// Process total image size - std::size_t image_size{}; - - /// Schedule count of this process - s64 schedule_count{}; - - bool is_signaled{}; - bool is_suspended{}; - bool is_initialized{}; - - std::atomic num_created_threads{}; - std::atomic num_threads{}; - u16 peak_num_threads{}; - - std::array running_threads{}; - std::array running_thread_idle_counts{}; - std::array pinned_threads{}; - - KThread* exception_thread{}; - - KLightLock state_lock; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index ef8fa98a9..725f16ea4 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -30,6 +30,7 @@ #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" @@ -42,7 +43,6 @@ #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_types.h" @@ -402,8 +402,8 @@ static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle R_UNLESS(obj.IsNotNull(), ResultInvalidHandle); // Get the process from the object. - Process* process = nullptr; - if (Process* p = obj->DynamicCast(); p != nullptr) { + KProcess* process = nullptr; + if (KProcess* p = obj->DynamicCast(); p != nullptr) { // The object is a process, so we can use it directly. process = p; } else if (KThread* t = obj->DynamicCast(); t != nullptr) { @@ -733,7 +733,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle } const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(handle); + KScopedAutoObject process = handle_table.GetObject(handle); if (process.IsNull()) { LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}", info_id, info_sub_id, handle); @@ -838,7 +838,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidCombination; } - Process* const current_process = system.Kernel().CurrentProcess(); + KProcess* const current_process = system.Kernel().CurrentProcess(); HandleTable& handle_table = current_process->GetHandleTable(); const auto resource_limit = current_process->GetResourceLimit(); if (!resource_limit) { @@ -861,9 +861,9 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidHandle; } - if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { + if (info_sub_id >= KProcess::RANDOM_ENTROPY_SIZE) { LOG_ERROR(Kernel_SVC, "Entropy size is out of range, expected {} but got {}", - Process::RANDOM_ENTROPY_SIZE, info_sub_id); + KProcess::RANDOM_ENTROPY_SIZE, info_sub_id); return ResultInvalidCombination; } @@ -955,7 +955,7 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) return ResultInvalidMemoryRegion; } - Process* const current_process{system.Kernel().CurrentProcess()}; + KProcess* const current_process{system.Kernel().CurrentProcess()}; auto& page_table{current_process->PageTable()}; if (current_process->GetSystemResourceSize() == 0) { @@ -1009,7 +1009,7 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size return ResultInvalidMemoryRegion; } - Process* const current_process{system.Kernel().CurrentProcess()}; + KProcess* const current_process{system.Kernel().CurrentProcess()}; auto& page_table{current_process->PageTable()}; if (current_process->GetSystemResourceSize() == 0) { @@ -1153,7 +1153,7 @@ static ResultCode GetThreadPriority32(Core::System& system, u32* out_priority, H /// Sets the priority for the specified thread static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { // Get the current process. - Process& process = *system.Kernel().CurrentProcess(); + KProcess& process = *system.Kernel().CurrentProcess(); // Validate the priority. R_UNLESS(HighestThreadPriority <= priority && priority <= LowestThreadPriority, @@ -1264,7 +1264,7 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add std::lock_guard lock{HLE::g_hle_lock}; LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); + KScopedAutoObject process = handle_table.GetObject(process_handle); if (process.IsNull()) { LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", process_handle); @@ -1346,7 +1346,7 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand } const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); + KScopedAutoObject process = handle_table.GetObject(process_handle); if (process.IsNull()) { LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", process_handle); @@ -1414,7 +1414,7 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha } const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); + KScopedAutoObject process = handle_table.GetObject(process_handle); if (process.IsNull()) { LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", process_handle); @@ -1830,7 +1830,7 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { // Try to reset as process. { - KScopedAutoObject process = handle_table.GetObject(handle); + KScopedAutoObject process = handle_table.GetObject(handle); if (process.IsNotNull()) { return process->Reset(); } @@ -2077,7 +2077,7 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ }; const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); + KScopedAutoObject process = handle_table.GetObject(process_handle); if (process.IsNull()) { LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", process_handle); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 5450dcf0f..49c09a570 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -16,8 +16,8 @@ #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc_aa.h" #include "core/hle/service/acc/acc_su.h" diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 47d194119..e8b82db00 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -15,11 +15,11 @@ #include "core/file_sys/savedata_factory.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index 0dd6ec68e..08348b180 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -9,7 +9,7 @@ #include "common/string_util.h" #include "core/core.h" #include "core/frontend/applets/error.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/error.h" #include "core/reporter.h" diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index b7483261e..e95499edd 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -9,7 +9,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/frontend/applets/general_frontend.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/general_backend.h" diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index 2404921fd..e5f4a4485 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -17,7 +17,7 @@ #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs_vector.h" #include "core/frontend/applets/web_browser.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/web_browser.h" diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 7d7a8c0ad..1863260f1 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -16,9 +16,9 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/aoc/aoc_u.h" #include "core/loader/loader.h" diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 05635a2a5..0206cbb6a 100644 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp @@ -12,9 +12,9 @@ #include "core/core.h" #include "core/file_sys/vfs.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_writable_event.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat.h" #include "core/hle/service/bcat/module.h" diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 13147472e..432abde76 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -12,7 +12,7 @@ #include "common/swap.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/fatal/fatal.h" #include "core/hle/service/fatal/fatal_p.h" #include "core/hle/service/fatal/fatal_u.h" diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 67b2b3102..67baaee9b 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -21,7 +21,7 @@ #include "core/file_sys/sdmc_factory.h" #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_offset.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_ldr.h" #include "core/hle/service/filesystem/fsp_pr.h" diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 7dc487e48..92ea27074 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -25,7 +25,7 @@ #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_srv.h" #include "core/reporter.h" diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index 7b1c6677c..6ad62ee5a 100644 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp @@ -9,8 +9,8 @@ #include "core/file_sys/control_metadata.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/glue/arp.h" #include "core/hle/service/glue/errors.h" #include "core/hle/service/glue/manager.h" diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index c8bc60ad1..563916f29 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -12,8 +12,8 @@ #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_system_control.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/service/ldr/ldr.h" #include "core/hle/service/service.h" @@ -321,7 +321,7 @@ public: return addr; } - ResultVal MapProcessCodeMemory(Kernel::Process* process, VAddr baseAddress, + ResultVal MapProcessCodeMemory(Kernel::KProcess* process, VAddr baseAddress, u64 size) const { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { auto& page_table{process->PageTable()}; @@ -342,7 +342,7 @@ public: return ERROR_INSUFFICIENT_ADDRESS_SPACE; } - ResultVal MapNro(Kernel::Process* process, VAddr nro_addr, std::size_t nro_size, + ResultVal MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, VAddr bss_addr, std::size_t bss_size, std::size_t size) const { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { auto& page_table{process->PageTable()}; @@ -378,7 +378,7 @@ public: return ERROR_INSUFFICIENT_ADDRESS_SPACE; } - ResultCode LoadNro(Kernel::Process* process, const NROHeader& nro_header, VAddr nro_addr, + ResultCode LoadNro(Kernel::KProcess* process, const NROHeader& nro_header, VAddr nro_addr, VAddr start) const { const VAddr text_start{start + nro_header.segment_headers[TEXT_INDEX].memory_offset}; const VAddr ro_start{start + nro_header.segment_headers[RO_INDEX].memory_offset}; diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp index 9bebe6088..1c3d81143 100644 --- a/src/core/hle/service/pctl/module.cpp +++ b/src/core/hle/service/pctl/module.cpp @@ -7,7 +7,7 @@ #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/pctl/module.h" #include "core/hle/service/pctl/pctl.h" diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index 3a00849e1..f4715935d 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp @@ -4,8 +4,8 @@ #include "core/core.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/service.h" @@ -17,8 +17,9 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1}; constexpr u64 NO_PROCESS_FOUND_PID{0}; -std::optional SearchProcessList(const std::vector& process_list, - std::function predicate) { +std::optional SearchProcessList( + const std::vector& process_list, + std::function predicate) { const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); if (iter == process_list.end()) { @@ -29,9 +30,9 @@ std::optional SearchProcessList(const std::vector& process_list) { + const std::vector& process_list) { const auto process = SearchProcessList(process_list, [](const auto& process) { - return process->GetProcessID() == Kernel::Process::ProcessIDMin; + return process->GetProcessID() == Kernel::KProcess::ProcessIDMin; }); IPC::ResponseBuilder rb{ctx, 4}; @@ -124,7 +125,7 @@ private: class Info final : public ServiceFramework { public: - explicit Info(Core::System& system_, const std::vector& process_list_) + explicit Info(Core::System& system_, const std::vector& process_list_) : ServiceFramework{system_, "pm:info"}, process_list{process_list_} { static const FunctionInfo functions[] = { {0, &Info::GetTitleId, "GetTitleId"}, @@ -154,7 +155,7 @@ private: rb.Push((*process)->GetTitleID()); } - const std::vector& process_list; + const std::vector& process_list; }; class Shell final : public ServiceFramework { diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 449e8d63b..c914f8145 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -6,7 +6,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/prepo/prepo.h" #include "core/hle/service/service.h" diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 42e464024..00e683c2f 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -12,10 +12,10 @@ #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_server_port.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/am/am.h" #include "core/hle/service/aoc/aoc_u.h" diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index fed47ecda..42f023258 100644 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -13,8 +13,8 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/romfs_factory.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nso.h" @@ -88,7 +88,7 @@ FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::Virtua } AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirectory::Load( - Kernel::Process& process, Core::System& system) { + Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index 22a4ec5a6..a49a8b001 100644 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -44,7 +44,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_dir) override; ResultStatus ReadIcon(std::vector& out_buffer) override; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index 627c18c7e..c062a4259 100644 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -11,7 +11,7 @@ #include "common/logging/log.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/loader/elf.h" #include "core/memory.h" @@ -386,7 +386,7 @@ FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& elf_file) { return FileType::Error; } -AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::Process& process, +AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::KProcess& process, [[maybe_unused]] Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 2b86c0b49..890299a20 100644 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -32,7 +32,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; }; } // namespace Loader diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 9b447da2a..3ae9e6e0e 100644 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -7,7 +7,7 @@ #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/loader/kip.h" #include "core/memory.h" @@ -42,7 +42,7 @@ FileType AppLoader_KIP::GetFileType() const { : FileType::Error; } -AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process, +AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, [[maybe_unused]] Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; diff --git a/src/core/loader/kip.h b/src/core/loader/kip.h index 2fe636f01..5f914b4a8 100644 --- a/src/core/loader/kip.h +++ b/src/core/loader/kip.h @@ -32,7 +32,7 @@ public: FileType GetFileType() const override; - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; private: std::unique_ptr kip; diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index e4f5fd40c..11b2d0837 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -11,7 +11,7 @@ #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/elf.h" #include "core/loader/kip.h" diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index bf6db1ab1..9eac11dec 100644 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -25,7 +25,7 @@ class NACP; namespace Kernel { struct AddressMapping; -class Process; +class KProcess; } // namespace Kernel namespace Loader { @@ -165,7 +165,7 @@ public: * * @return The status result of the operation. */ - virtual LoadResult Load(Kernel::Process& process, Core::System& system) = 0; + virtual LoadResult Load(Kernel::KProcess& process, Core::System& system) = 0; /** * Get the code (typically .code section) of the application diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index f53c3a72c..aceb66414 100644 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -6,7 +6,7 @@ #include "core/file_sys/content_archive.h" #include "core/file_sys/romfs.h" #include "core/file_sys/xts_archive.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/loader/nax.h" #include "core/loader/nca.h" @@ -41,7 +41,7 @@ FileType AppLoader_NAX::GetFileType() const { return IdentifyTypeImpl(*nax); } -AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, Core::System& system) { +AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index 68427c1cf..b3a50894f 100644 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -37,7 +37,7 @@ public: FileType GetFileType() const override; - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 47e7a77a9..418cbf61b 100644 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -9,7 +9,7 @@ #include "core/core.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/romfs_factory.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" @@ -32,7 +32,7 @@ FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& nca_file) { return FileType::Error; } -AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process, Core::System& system) { +AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index c9792f390..f2ff080bb 100644 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -39,7 +39,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index 0597cfa60..ef54fa574 100644 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -17,8 +17,8 @@ #include "core/file_sys/vfs_offset.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/nro.h" #include "core/loader/nso.h" @@ -130,7 +130,7 @@ static constexpr u32 PageAlignSize(u32 size) { return static_cast((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK); } -static bool LoadNroImpl(Kernel::Process& process, const std::vector& data) { +static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) { if (data.size() < sizeof(NroHeader)) { return {}; } @@ -199,11 +199,11 @@ static bool LoadNroImpl(Kernel::Process& process, const std::vector& data) { return true; } -bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file) { +bool AppLoader_NRO::LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file) { return LoadNroImpl(process, nro_file.ReadAllBytes()); } -AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process, Core::System& system) { +AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index 20bbaeb0e..fd453b402 100644 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -19,7 +19,7 @@ class NACP; } namespace Kernel { -class Process; +class KProcess; } namespace Loader { @@ -43,7 +43,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadIcon(std::vector& buffer) override; ResultStatus ReadProgramId(u64& out_program_id) override; @@ -53,7 +53,7 @@ public: bool IsRomFSUpdatable() const override; private: - bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file); + bool LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file); std::vector icon_data; std::unique_ptr nacp; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index f671afe02..df59412cf 100644 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -17,8 +17,8 @@ #include "core/file_sys/patch_manager.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/process.h" #include "core/loader/nso.h" #include "core/memory.h" @@ -71,7 +71,7 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) { return FileType::NSO; } -std::optional AppLoader_NSO::LoadModule(Kernel::Process& process, Core::System& system, +std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional pm) { @@ -162,7 +162,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::Process& process, Core::S return load_base + image_size; } -AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process, Core::System& system) { +AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index 195149b55..f7b61bc2d 100644 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -17,7 +17,7 @@ class System; } namespace Kernel { -class Process; +class KProcess; } namespace Loader { @@ -86,12 +86,12 @@ public: return IdentifyType(file); } - static std::optional LoadModule(Kernel::Process& process, Core::System& system, + static std::optional LoadModule(Kernel::KProcess& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional pm = {}); - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadNSOModules(Modules& out_modules) override; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index d7e590f1c..d815a7cd3 100644 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" @@ -79,7 +79,7 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& nsp_file) { return FileType::Error; } -AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process, Core::System& system) { +AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 1660f1b94..644c0ff58 100644 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -45,7 +45,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 0125ddf33..635d6ae15 100644 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/nca.h" #include "core/loader/xci.h" @@ -56,7 +56,7 @@ FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& xci_file) { return FileType::Error; } -AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process, Core::System& system) { +AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::KProcess& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 7ea8179af..708155c30 100644 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -45,7 +45,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::Process& process, Core::System& system) override; + LoadResult Load(Kernel::KProcess& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index ee4599063..b4c56e1c1 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -17,8 +17,8 @@ #include "core/core.h" #include "core/device_memory.h" #include "core/hle/kernel/k_page_table.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/physical_memory.h" -#include "core/hle/kernel/process.h" #include "core/memory.h" #include "video_core/gpu.h" @@ -30,7 +30,7 @@ namespace Core::Memory { struct Memory::Impl { explicit Impl(Core::System& system_) : system{system_} {} - void SetCurrentPageTable(Kernel::Process& process, u32 core_id) { + void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { current_page_table = &process.PageTable().PageTableImpl(); const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); @@ -50,7 +50,7 @@ struct Memory::Impl { MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped); } - bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { + bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const { const auto& page_table = process.PageTable().PageTableImpl(); const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType(); return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory; @@ -194,7 +194,7 @@ struct Memory::Impl { return string; } - void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, + void ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); @@ -239,7 +239,7 @@ struct Memory::Impl { } } - void ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, + void ReadBlockUnsafe(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); @@ -291,7 +291,7 @@ struct Memory::Impl { ReadBlockUnsafe(*system.CurrentProcess(), src_addr, dest_buffer, size); } - void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, + void WriteBlock(const Kernel::KProcess& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -334,7 +334,7 @@ struct Memory::Impl { } } - void WriteBlockUnsafe(const Kernel::Process& process, const VAddr dest_addr, + void WriteBlockUnsafe(const Kernel::KProcess& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -384,7 +384,7 @@ struct Memory::Impl { WriteBlockUnsafe(*system.CurrentProcess(), dest_addr, src_buffer, size); } - void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { + void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; @@ -429,7 +429,7 @@ struct Memory::Impl { ZeroBlock(*system.CurrentProcess(), dest_addr, size); } - void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, + void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -741,7 +741,7 @@ void Memory::Reset() { impl = std::make_unique(system); } -void Memory::SetCurrentPageTable(Kernel::Process& process, u32 core_id) { +void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { impl->SetCurrentPageTable(process, core_id); } @@ -753,7 +753,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { impl->UnmapRegion(page_table, base, size); } -bool Memory::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { +bool Memory::IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const { return impl->IsValidVirtualAddress(process, vaddr); } @@ -829,7 +829,7 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { return impl->ReadCString(vaddr, max_length); } -void Memory::ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, +void Memory::ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { impl->ReadBlock(process, src_addr, dest_buffer, size); } @@ -838,7 +838,7 @@ void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_ impl->ReadBlock(src_addr, dest_buffer, size); } -void Memory::ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, +void Memory::ReadBlockUnsafe(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { impl->ReadBlockUnsafe(process, src_addr, dest_buffer, size); } @@ -847,7 +847,7 @@ void Memory::ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std: impl->ReadBlockUnsafe(src_addr, dest_buffer, size); } -void Memory::WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, +void Memory::WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, std::size_t size) { impl->WriteBlock(process, dest_addr, src_buffer, size); } @@ -856,7 +856,7 @@ void Memory::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std impl->WriteBlock(dest_addr, src_buffer, size); } -void Memory::WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr, +void Memory::WriteBlockUnsafe(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, std::size_t size) { impl->WriteBlockUnsafe(process, dest_addr, src_buffer, size); } @@ -866,7 +866,7 @@ void Memory::WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, impl->WriteBlockUnsafe(dest_addr, src_buffer, size); } -void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) { +void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { impl->ZeroBlock(process, dest_addr, size); } @@ -874,7 +874,7 @@ void Memory::ZeroBlock(VAddr dest_addr, std::size_t size) { impl->ZeroBlock(dest_addr, size); } -void Memory::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, +void Memory::CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, const std::size_t size) { impl->CopyBlock(process, dest_addr, src_addr, size); } diff --git a/src/core/memory.h b/src/core/memory.h index 9a706a9ac..345fd870d 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -19,7 +19,7 @@ class System; namespace Kernel { class PhysicalMemory; -class Process; +class KProcess; } // namespace Kernel namespace Core::Memory { @@ -68,7 +68,7 @@ public: * * @param process The process to use the page table of. */ - void SetCurrentPageTable(Kernel::Process& process, u32 core_id); + void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id); /** * Maps an allocated buffer onto a region of the emulated process address space. @@ -99,7 +99,7 @@ public: * * @returns True if the given virtual address is valid, false otherwise. */ - bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr) const; + bool IsValidVirtualAddress(const Kernel::KProcess& process, VAddr vaddr) const; /** * Checks whether or not the supplied address is a valid virtual @@ -333,7 +333,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * process' address space. */ - void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, + void ReadBlock(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer, std::size_t size); /** @@ -354,7 +354,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * process' address space. */ - void ReadBlockUnsafe(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, + void ReadBlockUnsafe(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer, std::size_t size); /** @@ -414,7 +414,7 @@ public: * and will mark that region as invalidated to caches that the active * graphics backend may be maintaining over the course of execution. */ - void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, + void WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, std::size_t size); /** @@ -434,7 +434,7 @@ public: * will be ignored and an error will be logged. * */ - void WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, + void WriteBlockUnsafe(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, std::size_t size); /** @@ -486,7 +486,7 @@ public: * @post The range [dest_addr, size) within the process' address space is * filled with zeroes. */ - void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size); + void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); /** * Fills the specified address range within the current process' address space with zeroes. @@ -511,7 +511,7 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * same data within the range [src_addr, size). */ - void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, + void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, std::size_t size); /** diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 7643b7846..0f5ef7954 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -11,7 +11,7 @@ #include "core/core_timing_util.h" #include "core/hardware_properties.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/sm/sm.h" diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 311d4dda8..896add892 100644 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -19,7 +19,7 @@ #include "core/core.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/result.h" #include "core/memory.h" #include "core/reporter.h" diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 4eb71efbd..eb58ac6b6 100644 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -7,7 +7,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/memory.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index 0863904e9..a5dbb9adf 100644 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -19,7 +19,7 @@ #include "common/scope_exit.h" #include "common/settings.h" #include "core/core.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/memory.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index 97fb11ac6..dbcb751cb 100644 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -15,7 +15,7 @@ #include "common/settings.h" #include "common/zstd_compression.h" #include "core/core.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "video_core/engines/shader_type.h" #include "video_core/renderer_opengl/gl_shader_cache.h" #include "video_core/renderer_opengl/gl_shader_disk_cache.h" diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 7ff9491f4..86495803e 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -32,7 +32,7 @@ #include "common/settings.h" #include "core/core.h" #include "core/frontend/framebuffer_layout.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/mouse/mouse_input.h" diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index 3ac4a9e2b..f040b4c08 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -14,11 +14,11 @@ #include "core/core.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_class_token.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_types.h" #include "core/memory.h" diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 00d4cfe67..9e72acbf7 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -92,7 +92,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/file_sys/romfs.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/nfp/nfp.h" diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index 4871ac3bb..e2812ca61 100644 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -27,7 +27,7 @@ #include "core/crypto/key_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/vfs_real.h" -#include "core/hle/kernel/process.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" #include "core/telemetry_session.h" -- cgit v1.2.3 From 4b03e6e776e6421c2b2c290b0822b9e5a8556a4c Mon Sep 17 00:00:00 2001 From: bunnei Date: Sat, 24 Apr 2021 02:40:31 -0700 Subject: hle: kernel: Migrate to KHandleTable. --- src/core/CMakeLists.txt | 4 +- src/core/hle/kernel/handle_table.cpp | 125 --------- src/core/hle/kernel/handle_table.h | 212 -------------- src/core/hle/kernel/hle_ipc.cpp | 6 +- src/core/hle/kernel/hle_ipc.h | 7 +- src/core/hle/kernel/k_auto_object.h | 2 - src/core/hle/kernel/k_condition_variable.cpp | 2 +- src/core/hle/kernel/k_handle_table.cpp | 135 +++++++++ src/core/hle/kernel/k_handle_table.h | 309 +++++++++++++++++++++ src/core/hle/kernel/k_process.cpp | 2 +- src/core/hle/kernel/k_process.h | 8 +- .../hle/kernel/k_scoped_scheduler_lock_and_sleep.h | 4 +- src/core/hle/kernel/k_server_session.cpp | 2 +- src/core/hle/kernel/k_thread.cpp | 2 +- src/core/hle/kernel/kernel.cpp | 20 +- src/core/hle/kernel/kernel.h | 7 +- src/core/hle/kernel/process_capability.cpp | 4 +- src/core/hle/kernel/svc.cpp | 8 +- src/core/hle/kernel/svc_common.h | 15 + src/core/hle/kernel/time_manager.cpp | 1 - src/yuzu/debugger/wait_tree.cpp | 4 +- src/yuzu/debugger/wait_tree.h | 5 +- 22 files changed, 503 insertions(+), 381 deletions(-) delete mode 100644 src/core/hle/kernel/handle_table.cpp delete mode 100644 src/core/hle/kernel/handle_table.h create mode 100644 src/core/hle/kernel/k_handle_table.cpp create mode 100644 src/core/hle/kernel/k_handle_table.h (limited to 'src/yuzu/debugger') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 889a2d2f8..83da30418 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -149,8 +149,6 @@ add_library(core STATIC hle/kernel/svc_results.h hle/kernel/global_scheduler_context.cpp hle/kernel/global_scheduler_context.h - hle/kernel/handle_table.cpp - hle/kernel/handle_table.h hle/kernel/hle_ipc.cpp hle/kernel/hle_ipc.h hle/kernel/init/init_slab_setup.cpp @@ -174,6 +172,8 @@ add_library(core STATIC hle/kernel/k_condition_variable.h hle/kernel/k_event.cpp hle/kernel/k_event.h + hle/kernel/k_handle_table.cpp + hle/kernel/k_handle_table.h hle/kernel/k_light_condition_variable.h hle/kernel/k_light_lock.cpp hle/kernel/k_light_lock.h diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp deleted file mode 100644 index 16c528f5b..000000000 --- a/src/core/hle/kernel/handle_table.cpp +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include -#include "common/assert.h" -#include "common/logging/log.h" -#include "core/core.h" -#include "core/hle/kernel/handle_table.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/k_scheduler.h" -#include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/svc_results.h" - -namespace Kernel { -namespace { -constexpr u16 GetSlot(Handle handle) { - return static_cast(handle >> 15); -} - -constexpr u16 GetGeneration(Handle handle) { - return static_cast(handle & 0x7FFF); -} -} // Anonymous namespace - -HandleTable::HandleTable(KernelCore& kernel) : kernel{kernel} { - Clear(); -} - -HandleTable::~HandleTable() = default; - -ResultCode HandleTable::SetSize(s32 handle_table_size) { - if (static_cast(handle_table_size) > MAX_COUNT) { - LOG_ERROR(Kernel, "Handle table size {} is greater than {}", handle_table_size, MAX_COUNT); - return ResultOutOfMemory; - } - - // Values less than or equal to zero indicate to use the maximum allowable - // size for the handle table in the actual kernel, so we ignore the given - // value in that case, since we assume this by default unless this function - // is called. - if (handle_table_size > 0) { - table_size = static_cast(handle_table_size); - } - - return RESULT_SUCCESS; -} - -ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { - ASSERT(obj != nullptr); - - const u16 slot = next_free_slot; - if (slot >= table_size) { - LOG_ERROR(Kernel, "Unable to allocate Handle, too many slots in use."); - return ResultOutOfHandles; - } - next_free_slot = generations[slot]; - - const u16 generation = next_generation++; - - // Overflow count so it fits in the 15 bits dedicated to the generation in the handle. - // Horizon OS uses zero to represent an invalid handle, so skip to 1. - if (next_generation >= (1 << 15)) { - next_generation = 1; - } - - generations[slot] = generation; - objects[slot] = obj; - obj->Open(); - - *out_handle = generation | (slot << 15); - - return RESULT_SUCCESS; -} - -ResultVal HandleTable::Duplicate(Handle handle) { - auto object = GetObject(handle); - if (object.IsNull()) { - LOG_ERROR(Kernel, "Tried to duplicate invalid handle: {:08X}", handle); - return ResultInvalidHandle; - } - - Handle out_handle{}; - R_TRY(Add(&out_handle, object.GetPointerUnsafe())); - - return MakeResult(out_handle); -} - -bool HandleTable::Remove(Handle handle) { - if (!IsValid(handle)) { - LOG_ERROR(Kernel, "Handle is not valid! handle={:08X}", handle); - return {}; - } - - const u16 slot = GetSlot(handle); - - if (objects[slot]) { - objects[slot]->Close(); - } - - objects[slot] = nullptr; - - generations[slot] = next_free_slot; - next_free_slot = slot; - - return true; -} - -bool HandleTable::IsValid(Handle handle) const { - const std::size_t slot = GetSlot(handle); - const u16 generation = GetGeneration(handle); - const bool is_object_valid = (objects[slot] != nullptr); - return slot < table_size && is_object_valid && generations[slot] == generation; -} - -void HandleTable::Clear() { - for (u16 i = 0; i < table_size; ++i) { - generations[i] = static_cast(i + 1); - objects[i] = nullptr; - } - next_free_slot = 0; -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h deleted file mode 100644 index 791e303d1..000000000 --- a/src/core/hle/kernel/handle_table.h +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -#include -#include -#include - -#include "common/common_types.h" -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/k_spin_lock.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/result.h" - -namespace Kernel { - -class KernelCore; - -enum KernelHandle : Handle { - InvalidHandle = 0, - CurrentThread = 0xFFFF8000, - CurrentProcess = 0xFFFF8001, -}; - -/** - * This class allows the creation of Handles, which are references to objects that can be tested - * for validity and looked up. Here they are used to pass references to kernel objects to/from the - * emulated process. it has been designed so that it follows the same handle format and has - * approximately the same restrictions as the handle manager in the CTR-OS. - * - * Handles contain two sub-fields: a slot index (bits 31:15) and a generation value (bits 14:0). - * The slot index is used to index into the arrays in this class to access the data corresponding - * to the Handle. - * - * To prevent accidental use of a freed Handle whose slot has already been reused, a global counter - * is kept and incremented every time a Handle is created. This is the Handle's "generation". The - * value of the counter is stored into the Handle as well as in the handle table (in the - * "generations" array). When looking up a handle, the Handle's generation must match with the - * value stored on the class, otherwise the Handle is considered invalid. - * - * To find free slots when allocating a Handle without needing to scan the entire object array, the - * generations field of unallocated slots is re-purposed as a linked list of indices to free slots. - * When a Handle is created, an index is popped off the list and used for the new Handle. When it - * is destroyed, it is again pushed onto the list to be re-used by the next allocation. It is - * likely that this allocation strategy differs from the one used in CTR-OS, but this hasn't been - * verified and isn't likely to cause any problems. - */ -class HandleTable final : NonCopyable { -public: - /// This is the maximum limit of handles allowed per process in Horizon - static constexpr std::size_t MAX_COUNT = 1024; - - explicit HandleTable(KernelCore& kernel); - ~HandleTable(); - - /** - * Sets the number of handles that may be in use at one time - * for this handle table. - * - * @param handle_table_size The desired size to limit the handle table to. - * - * @returns an error code indicating if initialization was successful. - * If initialization was not successful, then ERR_OUT_OF_MEMORY - * will be returned. - * - * @pre handle_table_size must be within the range [0, 1024] - */ - ResultCode SetSize(s32 handle_table_size); - - /** - * Returns a new handle that points to the same object as the passed in handle. - * @return The duplicated Handle or one of the following errors: - * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. - * - Any errors returned by `Create()`. - */ - ResultVal Duplicate(Handle handle); - - /** - * Closes a handle, removing it from the table and decreasing the object's ref-count. - * @return `RESULT_SUCCESS` or one of the following errors: - * - `ERR_INVALID_HANDLE`: an invalid handle was passed in. - */ - bool Remove(Handle handle); - - /// Checks if a handle is valid and points to an existing object. - bool IsValid(Handle handle) const; - - template - KAutoObject* GetObjectImpl(Handle handle) const { - if (!IsValid(handle)) { - return nullptr; - } - - auto* obj = objects[static_cast(handle >> 15)]; - return obj->DynamicCast(); - } - - template - KScopedAutoObject GetObject(Handle handle) const { - if (handle == CurrentThread) { - return kernel.CurrentScheduler()->GetCurrentThread()->DynamicCast(); - } else if (handle == CurrentProcess) { - return kernel.CurrentProcess()->DynamicCast(); - } - - if (!IsValid(handle)) { - return nullptr; - } - - auto* obj = objects[static_cast(handle >> 15)]; - return obj->DynamicCast(); - } - - template - KScopedAutoObject GetObjectWithoutPseudoHandle(Handle handle) const { - if (!IsValid(handle)) { - return nullptr; - } - auto* obj = objects[static_cast(handle >> 15)]; - return obj->DynamicCast(); - } - - /// Closes all handles held in this table. - void Clear(); - - // NEW IMPL - - template - ResultCode Add(Handle* out_handle, T* obj) { - static_assert(std::is_base_of::value); - return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); - } - - ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); - - template - bool GetMultipleObjects(T** out, const Handle* handles, size_t num_handles) const { - // Try to convert and open all the handles. - size_t num_opened; - { - // Lock the table. - KScopedSpinLock lk(lock); - for (num_opened = 0; num_opened < num_handles; num_opened++) { - // Get the current handle. - const auto cur_handle = handles[num_opened]; - - // Get the object for the current handle. - KAutoObject* cur_object = this->GetObjectImpl(cur_handle); - if (cur_object == nullptr) { - break; - } - - // Cast the current object to the desired type. - T* cur_t = cur_object->DynamicCast(); - if (cur_t == nullptr) { - break; - } - - // Open a reference to the current object. - cur_t->Open(); - out[num_opened] = cur_t; - } - } - - // If we converted every object, succeed. - if (num_opened == num_handles) { - return true; - } - - // If we didn't convert entry object, close the ones we opened. - for (size_t i = 0; i < num_opened; i++) { - out[i]->Close(); - } - - return false; - } - -private: - /// Stores the Object referenced by the handle or null if the slot is empty. - std::array objects{}; - - /** - * The value of `next_generation` when the handle was created, used to check for validity. For - * empty slots, contains the index of the next free slot in the list. - */ - std::array generations; - - /** - * The limited size of the handle table. This can be specified by process - * capabilities in order to restrict the overall number of handles that - * can be created in a process instance - */ - u16 table_size = static_cast(MAX_COUNT); - - /** - * Global counter of the number of created handles. Stored in `generations` when a handle is - * created, and wraps around to 1 when it hits 0x8000. - */ - u16 next_generation = 1; - - /// Head of the free slots linked list. - u16 next_free_slot = 0; - - mutable KSpinLock lock; - - /// Underlying kernel instance that this handle table operates under. - KernelCore& kernel; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 69190286d..b505d20a6 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -14,8 +14,8 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" @@ -50,7 +50,7 @@ HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& HLERequestContext::~HLERequestContext() = default; -void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, +void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, bool incoming) { IPC::RequestParser rp(src_cmdbuf); command_header = rp.PopRaw(); @@ -163,7 +163,7 @@ void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_ rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. } -ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, +ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf) { ParseCommandBuffer(handle_table, src_cmdbuf, true); if (command_header->type == IPC::CommandType::Close) { diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 4b92ba655..fa031c121 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -17,6 +17,7 @@ #include "common/swap.h" #include "core/hle/ipc.h" #include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/svc_common.h" union ResultCode; @@ -35,9 +36,9 @@ class ServiceFrameworkBase; namespace Kernel { class Domain; -class HandleTable; class HLERequestContext; class KernelCore; +class KHandleTable; class KProcess; class KServerSession; class KThread; @@ -121,7 +122,7 @@ public: } /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, + ResultCode PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf); /// Writes data from this context back to the requesting process/thread. @@ -267,7 +268,7 @@ public: private: friend class IPC::ResponseBuilder; - void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); + void ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); std::array cmd_buf; Kernel::KServerSession* server_session{}; diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index 5a180b7dc..32aaf9fc5 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -17,8 +17,6 @@ namespace Kernel { class KernelCore; class KProcess; -using Handle = u32; - #define KERNEL_AUTOOBJECT_TRAITS(CLASS, BASE_CLASS) \ NON_COPYABLE(CLASS); \ NON_MOVEABLE(CLASS); \ diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index a9738f7ce..f51cf3e7b 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -179,7 +179,7 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) { KThread* thread_to_close = nullptr; if (can_access) { - if (prev_tag == InvalidHandle) { + if (prev_tag == Svc::InvalidHandle) { // If nobody held the lock previously, we're all good. thread->SetSyncedObject(nullptr, RESULT_SUCCESS); thread->Wakeup(); diff --git a/src/core/hle/kernel/k_handle_table.cpp b/src/core/hle/kernel/k_handle_table.cpp new file mode 100644 index 000000000..0378447f6 --- /dev/null +++ b/src/core/hle/kernel/k_handle_table.cpp @@ -0,0 +1,135 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/kernel/k_handle_table.h" + +namespace Kernel { + +KHandleTable::KHandleTable(KernelCore& kernel_) : kernel{kernel_} {} +KHandleTable ::~KHandleTable() = default; + +ResultCode KHandleTable::Finalize() { + // Get the table and clear our record of it. + u16 saved_table_size = 0; + { + KScopedSpinLock lk(m_lock); + + std::swap(m_table_size, saved_table_size); + } + + // Close and free all entries. + for (size_t i = 0; i < saved_table_size; i++) { + if (KAutoObject* obj = m_objects[i]; obj != nullptr) { + obj->Close(); + } + } + + return RESULT_SUCCESS; +} + +bool KHandleTable::Remove(Handle handle) { + // Don't allow removal of a pseudo-handle. + if (Svc::IsPseudoHandle(handle)) { + return false; + } + + // Handles must not have reserved bits set. + const auto handle_pack = HandlePack(handle); + if (handle_pack.reserved != 0) { + return false; + } + + // Find the object and free the entry. + KAutoObject* obj = nullptr; + { + KScopedSpinLock lk(m_lock); + + if (this->IsValidHandle(handle)) { + const auto index = handle_pack.index; + + obj = m_objects[index]; + this->FreeEntry(index); + } else { + return false; + } + } + + // Close the object. + obj->Close(); + return true; +} + +ResultCode KHandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) { + KScopedSpinLock lk(m_lock); + + // Never exceed our capacity. + R_UNLESS(m_count < m_table_size, ResultOutOfHandles); + + // Allocate entry, set output handle. + { + const auto linear_id = this->AllocateLinearId(); + const auto index = this->AllocateEntry(); + + m_entry_infos[index].info = {.linear_id = linear_id, .type = type}; + m_objects[index] = obj; + + obj->Open(); + + *out_handle = EncodeHandle(static_cast(index), linear_id); + } + + return RESULT_SUCCESS; +} + +ResultCode KHandleTable::Reserve(Handle* out_handle) { + KScopedSpinLock lk(m_lock); + + // Never exceed our capacity. + R_UNLESS(m_count < m_table_size, ResultOutOfHandles); + + *out_handle = EncodeHandle(static_cast(this->AllocateEntry()), this->AllocateLinearId()); + return RESULT_SUCCESS; +} + +void KHandleTable::Unreserve(Handle handle) { + KScopedSpinLock lk(m_lock); + + // Unpack the handle. + const auto handle_pack = HandlePack(handle); + const auto index = handle_pack.index; + const auto linear_id = handle_pack.linear_id; + const auto reserved = handle_pack.reserved; + ASSERT(reserved == 0); + ASSERT(linear_id != 0); + + if (index < m_table_size) { + // NOTE: This code does not check the linear id. + ASSERT(m_objects[index] == nullptr); + this->FreeEntry(index); + } +} + +void KHandleTable::Register(Handle handle, KAutoObject* obj, u16 type) { + KScopedSpinLock lk(m_lock); + + // Unpack the handle. + const auto handle_pack = HandlePack(handle); + const auto index = handle_pack.index; + const auto linear_id = handle_pack.linear_id; + const auto reserved = handle_pack.reserved; + ASSERT(reserved == 0); + ASSERT(linear_id != 0); + + if (index < m_table_size) { + // Set the entry. + ASSERT(m_objects[index] == nullptr); + + m_entry_infos[index].info = {.linear_id = static_cast(linear_id), .type = type}; + m_objects[index] = obj; + + obj->Open(); + } +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_handle_table.h b/src/core/hle/kernel/k_handle_table.h new file mode 100644 index 000000000..e38ad0fd9 --- /dev/null +++ b/src/core/hle/kernel/k_handle_table.h @@ -0,0 +1,309 @@ +// Copyright 2021 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/assert.h" +#include "common/bit_field.h" +#include "common/bit_util.h" +#include "common/common_types.h" +#include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/k_spin_lock.h" +#include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/svc_common.h" +#include "core/hle/kernel/svc_results.h" +#include "core/hle/result.h" + +namespace Kernel { + +class KernelCore; + +class KHandleTable { + NON_COPYABLE(KHandleTable); + NON_MOVEABLE(KHandleTable); + +public: + static constexpr size_t MaxTableSize = 1024; + +private: + union HandlePack { + u32 raw; + BitField<0, 15, u32> index; + BitField<15, 15, u32> linear_id; + BitField<30, 2, u32> reserved; + }; + + static constexpr u16 MinLinearId = 1; + static constexpr u16 MaxLinearId = 0x7FFF; + + static constexpr Handle EncodeHandle(u16 index, u16 linear_id) { + HandlePack handle{}; + handle.index.Assign(index); + handle.linear_id.Assign(linear_id); + handle.reserved.Assign(0); + return handle.raw; + } + + union EntryInfo { + struct { + u16 linear_id; + u16 type; + } info; + s32 next_free_index; + + constexpr u16 GetLinearId() const { + return info.linear_id; + } + constexpr u16 GetType() const { + return info.type; + } + constexpr s32 GetNextFreeIndex() const { + return next_free_index; + } + }; + +private: + std::array m_entry_infos{}; + std::array m_objects{}; + s32 m_free_head_index{-1}; + u16 m_table_size{}; + u16 m_max_count{}; + u16 m_next_linear_id{MinLinearId}; + u16 m_count{}; + mutable KSpinLock m_lock; + +public: + explicit KHandleTable(KernelCore& kernel_); + ~KHandleTable(); + + constexpr ResultCode Initialize(s32 size) { + R_UNLESS(size <= static_cast(MaxTableSize), ResultOutOfMemory); + + // Initialize all fields. + m_max_count = 0; + m_table_size = static_cast((size <= 0) ? MaxTableSize : size); + m_next_linear_id = MinLinearId; + m_count = 0; + m_free_head_index = -1; + + // Free all entries. + for (s32 i = 0; i < static_cast(m_table_size); ++i) { + m_objects[i] = nullptr; + m_entry_infos[i].next_free_index = i - 1; + m_free_head_index = i; + } + + return RESULT_SUCCESS; + } + + constexpr size_t GetTableSize() const { + return m_table_size; + } + constexpr size_t GetCount() const { + return m_count; + } + constexpr size_t GetMaxCount() const { + return m_max_count; + } + + ResultCode Finalize(); + bool Remove(Handle handle); + + template + KScopedAutoObject GetObjectWithoutPseudoHandle(Handle handle) const { + // Lock and look up in table. + KScopedSpinLock lk(m_lock); + + if constexpr (std::is_same::value) { + return this->GetObjectImpl(handle); + } else { + if (auto* obj = this->GetObjectImpl(handle); obj != nullptr) { + return obj->DynamicCast(); + } else { + return nullptr; + } + } + } + + template + KScopedAutoObject GetObject(Handle handle) const { + // Handle pseudo-handles. + if constexpr (std::derived_from) { + if (handle == Svc::PseudoHandle::CurrentProcess) { + auto* const cur_process = kernel.CurrentProcess(); + ASSERT(cur_process != nullptr); + return cur_process; + } + } else if constexpr (std::derived_from) { + if (handle == Svc::PseudoHandle::CurrentThread) { + auto* const cur_thread = GetCurrentThreadPointer(kernel); + ASSERT(cur_thread != nullptr); + return cur_thread; + } + } + + return this->template GetObjectWithoutPseudoHandle(handle); + } + + ResultCode Reserve(Handle* out_handle); + void Unreserve(Handle handle); + + template + ResultCode Add(Handle* out_handle, T* obj) { + static_assert(std::is_base_of::value); + return this->Add(out_handle, obj, obj->GetTypeObj().GetClassToken()); + } + + template + void Register(Handle handle, T* obj) { + static_assert(std::is_base_of::value); + return this->Register(handle, obj, obj->GetTypeObj().GetClassToken()); + } + + template + bool GetMultipleObjects(T** out, const Handle* handles, size_t num_handles) const { + // Try to convert and open all the handles. + size_t num_opened; + { + // Lock the table. + KScopedSpinLock lk(m_lock); + for (num_opened = 0; num_opened < num_handles; num_opened++) { + // Get the current handle. + const auto cur_handle = handles[num_opened]; + + // Get the object for the current handle. + KAutoObject* cur_object = this->GetObjectImpl(cur_handle); + if (cur_object == nullptr) { + break; + } + + // Cast the current object to the desired type. + T* cur_t = cur_object->DynamicCast(); + if (cur_t == nullptr) { + break; + } + + // Open a reference to the current object. + cur_t->Open(); + out[num_opened] = cur_t; + } + } + + // If we converted every object, succeed. + if (num_opened == num_handles) { + return true; + } + + // If we didn't convert entry object, close the ones we opened. + for (size_t i = 0; i < num_opened; i++) { + out[i]->Close(); + } + + return false; + } + +private: + ResultCode Add(Handle* out_handle, KAutoObject* obj, u16 type); + void Register(Handle handle, KAutoObject* obj, u16 type); + + constexpr s32 AllocateEntry() { + ASSERT(m_count < m_table_size); + + const auto index = m_free_head_index; + + m_free_head_index = m_entry_infos[index].GetNextFreeIndex(); + + m_max_count = std::max(m_max_count, ++m_count); + + return index; + } + + constexpr void FreeEntry(s32 index) { + ASSERT(m_count > 0); + + m_objects[index] = nullptr; + m_entry_infos[index].next_free_index = m_free_head_index; + + m_free_head_index = index; + + --m_count; + } + + constexpr u16 AllocateLinearId() { + const u16 id = m_next_linear_id++; + if (m_next_linear_id > MaxLinearId) { + m_next_linear_id = MinLinearId; + } + return id; + } + + constexpr bool IsValidHandle(Handle handle) const { + // Unpack the handle. + const auto handle_pack = HandlePack(handle); + const auto raw_value = handle_pack.raw; + const auto index = handle_pack.index; + const auto linear_id = handle_pack.linear_id; + const auto reserved = handle_pack.reserved; + ASSERT(reserved == 0); + + // Validate our indexing information. + if (raw_value == 0) { + return false; + } + if (linear_id == 0) { + return false; + } + if (index >= m_table_size) { + return false; + } + + // Check that there's an object, and our serial id is correct. + if (m_objects[index] == nullptr) { + return false; + } + if (m_entry_infos[index].GetLinearId() != linear_id) { + return false; + } + + return true; + } + + constexpr KAutoObject* GetObjectImpl(Handle handle) const { + // Handles must not have reserved bits set. + const auto handle_pack = HandlePack(handle); + if (handle_pack.reserved != 0) { + return nullptr; + } + + if (this->IsValidHandle(handle)) { + return m_objects[handle_pack.index]; + } else { + return nullptr; + } + } + + constexpr KAutoObject* GetObjectByIndexImpl(Handle* out_handle, size_t index) const { + + // Index must be in bounds. + if (index >= m_table_size) { + return nullptr; + } + + // Ensure entry has an object. + if (KAutoObject* obj = m_objects[index]; obj != nullptr) { + *out_handle = EncodeHandle(static_cast(index), m_entry_infos[index].GetLinearId()); + return obj; + } else { + return nullptr; + } + } + +private: + KernelCore& kernel; +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index e542b1f07..174318180 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -354,7 +354,7 @@ ResultCode KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, tls_region_address = CreateTLSRegion(); memory_reservation.Commit(); - return handle_table.SetSize(capabilities.GetHandleTableSize()); + return handle_table.Initialize(capabilities.GetHandleTableSize()); } void KProcess::Run(s32 main_thread_priority, u64 stack_size) { diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 5c54c6360..62ab26b05 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -11,10 +11,10 @@ #include #include #include "common/common_types.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_condition_variable.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/slab_helpers.h" @@ -104,12 +104,12 @@ public: } /// Gets a reference to the process' handle table. - HandleTable& GetHandleTable() { + KHandleTable& GetHandleTable() { return handle_table; } /// Gets a const reference to the process' handle table. - const HandleTable& GetHandleTable() const { + const KHandleTable& GetHandleTable() const { return handle_table; } @@ -429,7 +429,7 @@ private: u64 total_process_running_time_ticks = 0; /// Per-process handle table for storing created object handles in. - HandleTable handle_table; + KHandleTable handle_table; /// Per-process address arbiter. KAddressArbiter address_arbiter; diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h index ebecf0c77..1bfbbcfe2 100644 --- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h @@ -8,7 +8,7 @@ #pragma once #include "common/common_types.h" -#include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/time_manager.h" @@ -17,7 +17,7 @@ namespace Kernel { class [[nodiscard]] KScopedSchedulerLockAndSleep { public: - explicit KScopedSchedulerLockAndSleep(KernelCore & kernel, KThread * t, s64 timeout) + explicit KScopedSchedulerLockAndSleep(KernelCore& kernel, KThread* t, s64 timeout) : kernel(kernel), thread(t), timeout_tick(timeout) { // Lock the scheduler. kernel.GlobalSchedulerContext().scheduler_lock.Lock(); diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 3bc259693..c8acaa453 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -10,9 +10,9 @@ #include "common/logging/log.h" #include "core/core_timing.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_server_session.h" diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 3de0157ac..ef6dfeeca 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -18,8 +18,8 @@ #include "core/core.h" #include "core/cpu_manager.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_condition_variable.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index f64e07081..825fab694 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -26,9 +26,9 @@ #include "core/cpu_manager.h" #include "core/device_memory.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/init/init_slab_setup.h" #include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" #include "core/hle/kernel/k_process.h" @@ -52,8 +52,7 @@ namespace Kernel { struct KernelCore::Impl { explicit Impl(Core::System& system, KernelCore& kernel) - : time_manager{system}, global_handle_table{kernel}, - object_list_container{kernel}, system{system} {} + : time_manager{system}, object_list_container{kernel}, system{system} {} void SetMulticore(bool is_multicore) { this->is_multicore = is_multicore; @@ -61,6 +60,7 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique(kernel); + global_handle_table = std::make_unique(kernel); service_thread_manager = std::make_unique(1, "yuzu:ServiceThreadManager"); @@ -118,7 +118,7 @@ struct KernelCore::Impl { current_process = nullptr; } - global_handle_table.Clear(); + global_handle_table.reset(); preemption_event = nullptr; @@ -648,7 +648,7 @@ struct KernelCore::Impl { // This is the kernel's handle table or supervisor handle table which // stores all the objects in place. - HandleTable global_handle_table; + std::unique_ptr global_handle_table; KAutoObjectWithListContainer object_list_container; @@ -722,7 +722,7 @@ KResourceLimit* KernelCore::GetSystemResourceLimit() { } KScopedAutoObject KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { - return impl->global_handle_table.GetObject(handle); + return impl->global_handle_table->GetObject(handle); } void KernelCore::AppendNewProcess(KProcess* process) { @@ -876,12 +876,12 @@ u64 KernelCore::CreateNewUserProcessID() { return impl->next_user_process_id++; } -Kernel::HandleTable& KernelCore::GlobalHandleTable() { - return impl->global_handle_table; +KHandleTable& KernelCore::GlobalHandleTable() { + return *impl->global_handle_table; } -const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { - return impl->global_handle_table; +const KHandleTable& KernelCore::GlobalHandleTable() const { + return *impl->global_handle_table; } void KernelCore::RegisterCoreThread(std::size_t core_id) { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 0dd9deaeb..7c46aa997 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -14,6 +14,7 @@ #include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_slab_heap.h" #include "core/hle/kernel/memory_types.h" +#include "core/hle/kernel/svc_common.h" namespace Core { class CPUInterruptHandler; @@ -30,10 +31,10 @@ namespace Kernel { class KClientPort; class GlobalSchedulerContext; -class HandleTable; class KAutoObjectWithListContainer; class KClientSession; class KEvent; +class KHandleTable; class KLinkedListNode; class KMemoryManager; class KPort; @@ -308,10 +309,10 @@ private: u64 CreateNewThreadID(); /// Provides a reference to the global handle table. - Kernel::HandleTable& GlobalHandleTable(); + KHandleTable& GlobalHandleTable(); /// Provides a const reference to the global handle table. - const Kernel::HandleTable& GlobalHandleTable() const; + const KHandleTable& GlobalHandleTable() const; struct Impl; std::unique_ptr impl; diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 4ccac0b06..fcb8b1ea5 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp @@ -6,7 +6,7 @@ #include "common/bit_util.h" #include "common/logging/log.h" -#include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_page_table.h" #include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/svc_results.h" @@ -99,7 +99,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() { interrupt_capabilities.set(); // Allow using the maximum possible amount of handles - handle_table_size = static_cast(HandleTable::MAX_COUNT); + handle_table_size = static_cast(KHandleTable::MaxTableSize); // Allow all debugging capabilities. is_debuggable = true; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 156c565b0..d3293a1fe 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -21,12 +21,12 @@ #include "core/core_timing.h" #include "core/core_timing_util.h" #include "core/cpu_manager.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_condition_variable.h" #include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_page_table.h" @@ -839,10 +839,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle } KProcess* const current_process = system.Kernel().CurrentProcess(); - HandleTable& handle_table = current_process->GetHandleTable(); + KHandleTable& handle_table = current_process->GetHandleTable(); const auto resource_limit = current_process->GetResourceLimit(); if (!resource_limit) { - *result = KernelHandle::InvalidHandle; + *result = Svc::InvalidHandle; // Yes, the kernel considers this a successful operation. return RESULT_SUCCESS; } @@ -1993,7 +1993,7 @@ static ResultCode SignalEvent(Core::System& system, Handle event_handle) { LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); // Get the current handle table. - const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); // Get the writable event. KScopedAutoObject writable_event = handle_table.GetObject(event_handle); diff --git a/src/core/hle/kernel/svc_common.h b/src/core/hle/kernel/svc_common.h index 4af049551..8a8f347b5 100644 --- a/src/core/hle/kernel/svc_common.h +++ b/src/core/hle/kernel/svc_common.h @@ -6,9 +6,24 @@ #include "common/common_types.h" +namespace Kernel { +using Handle = u32; +} + namespace Kernel::Svc { constexpr s32 ArgumentHandleCountMax = 0x40; constexpr u32 HandleWaitMask{1u << 30}; +constexpr inline Handle InvalidHandle = Handle(0); + +enum PseudoHandle : Handle { + CurrentThread = 0xFFFF8000, + CurrentProcess = 0xFFFF8001, +}; + +constexpr bool IsPseudoHandle(const Handle& handle) { + return handle == PseudoHandle::CurrentProcess || handle == PseudoHandle::CurrentThread; +} + } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index 59ebfc51f..ae9b4be2f 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -6,7 +6,6 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/core_timing_util.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index f040b4c08..bdfda6c54 100644 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -12,8 +12,8 @@ #include "common/assert.h" #include "core/arm/arm_interface.h" #include "core/core.h" -#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_class_token.h" +#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" @@ -115,7 +115,7 @@ QString WaitTreeText::GetText() const { return text; } -WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table) +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table) : mutex_address(mutex_address) { mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); owner_handle = static_cast(mutex_value & Kernel::Svc::HandleWaitMask); diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index 3dd4acab0..d450345df 100644 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -14,11 +14,12 @@ #include "common/common_types.h" #include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/svc_common.h" class EmuThread; namespace Kernel { -class HandleTable; +class KHandleTable; class KReadableEvent; class KSynchronizationObject; class KThread; @@ -74,7 +75,7 @@ public: class WaitTreeMutexInfo : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table); + explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table); ~WaitTreeMutexInfo() override; QString GetText() const override; -- cgit v1.2.3