ソースを参照

hle: kernel: Migrate KProcess to KAutoObject.

bunnei 5 年 前
コミット
7ccbdd4d8d

+ 6 - 3
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<u32>(load_result));
         }
         AddGlueRegistrationForProcess(*app_loader, *main_process);
-        kernel.MakeCurrentProcess(main_process.get());
+        kernel.MakeCurrentProcess(main_process);
         kernel.InitializeCores();
 
         // Initialize cheat engine

+ 5 - 5
src/core/hle/kernel/handle_table.cpp

@@ -100,7 +100,7 @@ ResultCode HandleTable::Add(Handle* out_handle, KAutoObject* obj, u16 type) {
 }
 
 ResultVal<Handle> HandleTable::Duplicate(Handle handle) {
-    std::shared_ptr<Object> object = GetGeneric(handle);
+    std::shared_ptr<Object> 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<Object> 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() {

+ 2 - 2
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<Object> 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 <class T>
-    std::shared_ptr<T> Get(Handle handle) const {
+    T* Get(Handle handle) const {
         return DynamicObjectCast<T>(GetGeneric(handle));
     }
 

+ 6 - 3
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,

+ 1 - 1
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;

+ 2 - 3
src/core/hle/kernel/k_synchronization_object.h

@@ -53,10 +53,9 @@ private:
 
 // Specialization of DynamicObjectCast for KSynchronizationObjects
 template <>
-inline std::shared_ptr<KSynchronizationObject> DynamicObjectCast<KSynchronizationObject>(
-    std::shared_ptr<Object> object) {
+inline KSynchronizationObject* DynamicObjectCast<KSynchronizationObject>(Object* object) {
     if (object != nullptr && object->IsWaitable()) {
-        return std::static_pointer_cast<KSynchronizationObject>(object);
+        return reinterpret_cast<KSynchronizationObject*>(object);
     }
     return nullptr;
 }

+ 4 - 4
src/core/hle/kernel/kernel.cpp

@@ -614,7 +614,7 @@ struct KernelCore::Impl {
     std::atomic<u64> next_thread_id{1};
 
     // Lists all processes that exist in the current session.
-    std::vector<std::shared_ptr<Process>> process_list;
+    std::vector<Process*> process_list;
     Process* current_process = nullptr;
     std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
     Kernel::TimeManager time_manager;
@@ -699,8 +699,8 @@ KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handl
     return impl->global_handle_table.GetObject<KThread>(handle);
 }
 
-void KernelCore::AppendNewProcess(std::shared_ptr<Process> 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<std::shared_ptr<Process>>& KernelCore::GetProcessList() const {
+const std::vector<Process*>& KernelCore::GetProcessList() const {
     return impl->process_list;
 }
 

+ 2 - 2
src/core/hle/kernel/kernel.h

@@ -91,7 +91,7 @@ public:
     KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
 
     /// Adds the given shared pointer to an internal list of active processes.
-    void AppendNewProcess(std::shared_ptr<Process> 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<std::shared_ptr<Process>>& GetProcessList() const;
+    const std::vector<Process*>& GetProcessList() const;
 
     /// Gets the sole instance of the global scheduler
     Kernel::GlobalSchedulerContext& GlobalSchedulerContext();

+ 2 - 2
src/core/hle/kernel/object.h

@@ -86,9 +86,9 @@ std::shared_ptr<T> SharedFrom(T* raw) {
  * @return Derived pointer to the object, or `nullptr` if `object` isn't of type T.
  */
 template <typename T>
-inline std::shared_ptr<T> DynamicObjectCast(std::shared_ptr<Object> object) {
+inline T* DynamicObjectCast(Object* object) {
     if (object != nullptr && object->GetHandleType() == T::HANDLE_TYPE) {
-        return std::static_pointer_cast<T>(object);
+        return reinterpret_cast<T*>(object);
     }
     return nullptr;
 }

+ 18 - 13
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<num_slot_entries> is_slot_used;
 };
 
-std::shared_ptr<Process> 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> process = std::make_shared<Process>(system);
     process->name = std::move(name);
 
     process->resource_limit = kernel.GetSystemResourceLimit();
@@ -127,6 +129,7 @@ std::shared_ptr<Process> 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<u64> distribution;
@@ -134,7 +137,8 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name,
                   [&] { return distribution(rng); });
 
     kernel.AppendNewProcess(process);
-    return process;
+
+    return RESULT_SUCCESS;
 }
 
 std::shared_ptr<KResourceLimit> 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<TLSPage>& 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<KPageTable>(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<KPageTable>(kernel.System())}, handle_table{kernel},
+      address_arbiter{kernel.System()}, condition_var{kernel.System()}, state_lock{kernel} {}
 
 Process::~Process() = default;
 

+ 23 - 9
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<Process, KSynchronizationObject> {
+    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<Process> 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<s32> num_created_threads{};
     std::atomic<u16> num_threads{};
@@ -474,9 +491,6 @@ private:
     KThread* exception_thread{};
 
     KLightLock state_lock;
-
-    /// System context
-    Core::System& system;
 };
 
 } // namespace Kernel

+ 3 - 3
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<ClientSession> session = handle_table.Get<ClientSession>(handle);
+    auto session = handle_table.Get<ClientSession>(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<KSynchronizationObject>(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> process = handle_table.Get<Process>(process_handle);
+    auto process = handle_table.Get<Process>(process_handle);
     if (!process) {
         LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}",
                   process_handle);

+ 5 - 7
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<std::shared_ptr<Kernel::Process>> SearchProcessList(
-    const std::vector<std::shared_ptr<Kernel::Process>>& process_list,
-    std::function<bool(const std::shared_ptr<Kernel::Process>&)> predicate) {
+std::optional<Kernel::Process*> SearchProcessList(const std::vector<Kernel::Process*>& process_list,
+                                                  std::function<bool(Kernel::Process*)> 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<std::shared_ptr<Kernel::Process>> SearchProcessList(
 }
 
 void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
-                              const std::vector<std::shared_ptr<Kernel::Process>>& process_list) {
+                              const std::vector<Kernel::Process*>& 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<Info> {
 public:
-    explicit Info(Core::System& system_,
-                  const std::vector<std::shared_ptr<Kernel::Process>>& process_list_)
+    explicit Info(Core::System& system_, const std::vector<Kernel::Process*>& 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<std::shared_ptr<Kernel::Process>>& process_list;
+    const std::vector<Kernel::Process*>& process_list;
 };
 
 class Shell final : public ServiceFramework<Shell> {

+ 1 - 1
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<Kernel::Handle>(mutex_value & Kernel::Svc::HandleWaitMask);
-    owner = handle_table.Get<Kernel::KThread>(owner_handle);
+    owner = SharedFrom(handle_table.Get<Kernel::KThread>(owner_handle));
 }
 
 WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;