From 89edbe8aa20d278d6f2c5ab735163f0d96ff88d2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Apr 2021 22:42:23 -0700 Subject: [PATCH] hle: kernel: Refactor several threads/events/sharedmemory to use slab heaps. --- src/core/core.cpp | 2 +- src/core/hle/kernel/k_scheduler.cpp | 16 +++--- src/core/hle/kernel/k_scheduler.h | 4 +- src/core/hle/kernel/kernel.cpp | 50 +++++++++---------- src/core/hle/kernel/process.cpp | 2 +- src/core/hle/kernel/slab_helpers.h | 16 +----- src/core/hle/kernel/svc.cpp | 4 +- src/core/hle/service/hid/controllers/npad.cpp | 8 ++- src/core/hle/service/hid/controllers/npad.h | 5 +- src/core/hle/service/nvdrv/nvdrv.cpp | 3 +- src/core/hle/service/nvdrv/nvdrv.h | 2 +- 11 files changed, 53 insertions(+), 59 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index f050a8d4b..b5bc903cd 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -233,7 +233,7 @@ struct System::Impl { } telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); - auto main_process = Kernel::Process::CreateWithKernel(system.Kernel()); + auto main_process = Kernel::Process::Create(system.Kernel()); ASSERT(Kernel::Process::Initialize(main_process, system, "main", Kernel::Process::ProcessType::Userland) .IsSuccess()); diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 1feda9303..38c6b50fa 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -618,14 +618,17 @@ KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core } KScheduler::~KScheduler() { - idle_thread->Close(); + if (idle_thread) { + idle_thread->Close(); + idle_thread = nullptr; + } } KThread* KScheduler::GetCurrentThread() const { if (auto result = current_thread.load(); result) { return result; } - return idle_thread.get(); + return idle_thread; } u64 KScheduler::GetLastContextSwitchTicks() const { @@ -710,7 +713,7 @@ void KScheduler::ScheduleImpl() { // We never want to schedule a null thread, so use the idle thread if we don't have a next. if (next_thread == nullptr) { - next_thread = idle_thread.get(); + next_thread = idle_thread; } // If we're not actually switching thread, there's nothing to do. @@ -771,7 +774,7 @@ void KScheduler::SwitchToCurrent() { break; } } - auto thread = next_thread ? next_thread : idle_thread.get(); + auto thread = next_thread ? next_thread : idle_thread; Common::Fiber::YieldTo(switch_fiber, *thread->GetHostContext()); } while (!is_switch_pending()); } @@ -794,9 +797,8 @@ void KScheduler::UpdateLastContextSwitchTime(KThread* thread, Process* process) } void KScheduler::Initialize() { - idle_thread = std::make_unique(system.Kernel()); - KAutoObject::Create(idle_thread.get()); - ASSERT(KThread::InitializeIdleThread(system, idle_thread.get(), core_id).IsSuccess()); + idle_thread = KThread::Create(system.Kernel()); + ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); } diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 8cb5f6f36..01387b892 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -51,7 +51,7 @@ public: /// Returns true if the scheduler is idle [[nodiscard]] bool IsIdle() const { - return GetCurrentThread() == idle_thread.get(); + return GetCurrentThread() == idle_thread; } /// Gets the timestamp for the last context switch in ticks. @@ -173,7 +173,7 @@ private: KThread* prev_thread{}; std::atomic current_thread{}; - std::unique_ptr idle_thread; + KThread* idle_thread{}; std::shared_ptr switch_fiber{}; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 43bce1863..1b7ba39f4 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -102,15 +102,21 @@ struct KernelCore::Impl { next_user_process_id = Process::ProcessIDMin; next_thread_id = 1; - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - if (suspend_threads[i]) { - suspend_threads[i]->Close(); + for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + if (suspend_threads[core_id]) { + suspend_threads[core_id]->Close(); + suspend_threads[core_id] = nullptr; } + + schedulers[core_id].reset(); } cores.clear(); - current_process = nullptr; + if (current_process) { + current_process->Close(); + current_process = nullptr; + } global_handle_table.Clear(); @@ -195,10 +201,9 @@ struct KernelCore::Impl { void InitializeSuspendThreads() { for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - suspend_threads[core_id] = std::make_unique(system.Kernel()); - KAutoObject::Create(suspend_threads[core_id].get()); - ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id].get(), {}, - {}, core_id) + suspend_threads[core_id] = KThread::Create(system.Kernel()); + ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, + core_id) .IsSuccess()); suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); } @@ -577,15 +582,10 @@ struct KernelCore::Impl { const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; - hid_shared_mem = std::make_unique(system.Kernel()); - font_shared_mem = std::make_unique(system.Kernel()); - irs_shared_mem = std::make_unique(system.Kernel()); - time_shared_mem = std::make_unique(system.Kernel()); - - KAutoObject::Create(hid_shared_mem.get()); - KAutoObject::Create(font_shared_mem.get()); - KAutoObject::Create(irs_shared_mem.get()); - KAutoObject::Create(time_shared_mem.get()); + hid_shared_mem = KSharedMemory::Create(system.Kernel()); + font_shared_mem = KSharedMemory::Create(system.Kernel()); + irs_shared_mem = KSharedMemory::Create(system.Kernel()); + time_shared_mem = KSharedMemory::Create(system.Kernel()); hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize}, KMemoryPermission::None, @@ -656,10 +656,10 @@ struct KernelCore::Impl { std::unique_ptr> user_slab_heap_pages; // Shared memory for services - std::unique_ptr hid_shared_mem; - std::unique_ptr font_shared_mem; - std::unique_ptr irs_shared_mem; - std::unique_ptr time_shared_mem; + Kernel::KSharedMemory* hid_shared_mem{}; + Kernel::KSharedMemory* font_shared_mem{}; + Kernel::KSharedMemory* irs_shared_mem{}; + Kernel::KSharedMemory* time_shared_mem{}; // Threads used for services std::unordered_set> service_threads; @@ -668,7 +668,7 @@ struct KernelCore::Impl { // the release of itself std::unique_ptr service_thread_manager; - std::array, Core::Hardware::NUM_CPU_CORES> suspend_threads; + std::array suspend_threads; std::array interrupts{}; std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -938,9 +938,9 @@ void KernelCore::Suspend(bool in_suspention) { { KScopedSchedulerLock lock(*this); const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; - for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { - impl->suspend_threads[i]->SetState(state); - impl->suspend_threads[i]->SetWaitReasonForDebugging( + for (s32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { + impl->suspend_threads[core_id]->SetState(state); + impl->suspend_threads[core_id]->SetWaitReasonForDebugging( ThreadWaitReasonForDebugging::Suspended); } } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index fe4558648..8088c634f 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -41,7 +41,7 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, const VAddr entry_point = owner_process.PageTable().GetCodeRegionStart(); ASSERT(owner_process.GetResourceLimit()->Reserve(LimitableResource::Threads, 1)); - KThread* thread = KThread::CreateWithKernel(system.Kernel()); + KThread* thread = KThread::Create(system.Kernel()); ASSERT(KThread::InitializeUserThread(system, thread, entry_point, 0, stack_top, priority, owner_process.GetIdealCoreId(), &owner_process) .IsSuccess()); diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h index 4f23ddabf..66954b6b2 100644 --- a/src/core/hle/kernel/slab_helpers.h +++ b/src/core/hle/kernel/slab_helpers.h @@ -67,10 +67,6 @@ class KAutoObjectWithSlabHeapAndContainer : public Base { private: static Derived* Allocate(KernelCore& kernel) { - return kernel.SlabHeap().Allocate(); - } - - static Derived* AllocateWithKernel(KernelCore& kernel) { return kernel.SlabHeap().AllocateWithKernel(kernel); } @@ -120,16 +116,8 @@ public: kernel.ObjectListContainer().Initialize(); } - static Derived* Create() { - Derived* obj = Allocate(); - if (obj != nullptr) { - KAutoObject::Create(obj); - } - return obj; - } - - static Derived* CreateWithKernel(KernelCore& kernel) { - Derived* obj = AllocateWithKernel(kernel); + static Derived* Create(KernelCore& kernel) { + Derived* obj = Allocate(kernel); if (obj != nullptr) { KAutoObject::Create(obj); } diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b143a51c7..8050359be 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -1431,7 +1431,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e } // Create the thread. - KThread* thread = KThread::CreateWithKernel(kernel); + KThread* thread = KThread::Create(kernel); if (!thread) { LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached."); return ResultOutOfResource; @@ -1953,7 +1953,7 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); // Create a new event. - KEvent* event = KEvent::CreateWithKernel(kernel); + KEvent* event = KEvent::Create(kernel); R_UNLESS(event != nullptr, ResultOutOfResource); // Initialize the event. diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 753875d6e..77768ca7d 100644 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -253,8 +253,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { void Controller_NPad::OnInit() { auto& kernel = system.Kernel(); for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { - styleset_changed_events[i] = std::make_unique(kernel); - Kernel::KAutoObject::Create(styleset_changed_events[i].get()); + styleset_changed_events[i] = Kernel::KEvent::Create(kernel); styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i)); } @@ -341,6 +340,11 @@ void Controller_NPad::OnRelease() { VibrateControllerAtIndex(npad_idx, device_idx, {}); } } + + for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { + styleset_changed_events[i]->Close(); + styleset_changed_events[i] = nullptr; + } } void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index 515cf7c37..b3de272b6 100644 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -573,8 +573,9 @@ private: NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; // Each controller should have their own styleset changed event - std::array, 10> styleset_changed_events; - std::array, 10> last_vibration_timepoints; + std::array styleset_changed_events{}; + std::array, 10> + last_vibration_timepoints{}; std::array, 10> latest_vibration_values{}; bool permit_vibration_session_enabled{false}; std::array, 10> vibration_devices_mounted{}; diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 64bdb0722..2fbf61cd6 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -42,8 +42,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { auto& kernel = system.Kernel(); for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.events[i].event = std::make_unique(kernel); - Kernel::KAutoObject::Create(events_interface.events[i].event.get()); + events_interface.events[i].event = Kernel::KEvent::Create(kernel); events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i)); events_interface.status[i] = EventState::Free; events_interface.registered[i] = false; diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index 76f77cbb1..ea5dbbdf9 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -35,7 +35,7 @@ class nvdevice; /// Represents an Nvidia event struct NvEvent { - std::unique_ptr event; + Kernel::KEvent* event{}; Fence fence{}; };