From 89edbe8aa20d278d6f2c5ab735163f0d96ff88d2 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Apr 2021 22:42:23 -0700 Subject: hle: kernel: Refactor several threads/events/sharedmemory to use slab heaps. --- 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 +-- 6 files changed, 41 insertions(+), 51 deletions(-) (limited to 'src/core/hle/kernel') 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. -- cgit v1.2.3