From b6156e735cd78d4b7863491ae6bdc63e44404b73 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 9 Apr 2021 22:10:14 -0700 Subject: hle: kernel: Move slab heap management to KernelCore. --- src/core/hle/kernel/k_condition_variable.cpp | 15 +++-- src/core/hle/kernel/k_event.cpp | 4 ++ src/core/hle/kernel/k_linked_list.h | 15 +++-- src/core/hle/kernel/k_scheduler.cpp | 4 +- src/core/hle/kernel/k_slab_heap.h | 1 + src/core/hle/kernel/kernel.h | 36 +++++++++-- src/core/hle/kernel/slab_helpers.h | 95 ++++++++++++++-------------- 7 files changed, 106 insertions(+), 64 deletions(-) diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index 930f78974..72565af05 100644 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -185,11 +185,11 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) { thread->Wakeup(); } else { // Get the previous owner. - KThread* owner_thread = - kernel.CurrentProcess()->GetHandleTable() - .GetObjectWithoutPseudoHandle( - static_cast(prev_tag & ~Svc::HandleWaitMask)) - .ReleasePointerUnsafe(); + KThread* owner_thread = kernel.CurrentProcess() + ->GetHandleTable() + .GetObjectWithoutPseudoHandle( + static_cast(prev_tag & ~Svc::HandleWaitMask)) + .ReleasePointerUnsafe(); if (owner_thread) { // Add the thread as a waiter on the owner. @@ -214,7 +214,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { // Prepare for signaling. constexpr int MaxThreads = 16; - KLinkedList thread_list; + KLinkedList thread_list{kernel}; std::array thread_array; s32 num_to_close{}; @@ -254,7 +254,8 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { } // Close threads in the list. - for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) { + for (auto it = thread_list.begin(); it != thread_list.end(); + it = thread_list.erase(kernel, it)) { (*it).Close(); } } diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp index bc4a79cc8..4020e5325 100644 --- a/src/core/hle/kernel/k_event.cpp +++ b/src/core/hle/kernel/k_event.cpp @@ -21,6 +21,10 @@ void KEvent::Initialize(std::string&& name_) { // writable events are closed this object will be destroyed. Open(); + //// Create our sub events. + //KAutoObject::Create(readable_event.get()); + //KAutoObject::Create(writable_event.get()); + // Create our sub events. readable_event = std::make_shared(kernel, name_ + ":Readable"); writable_event = std::make_shared(kernel, name_ + ":Writable"); diff --git a/src/core/hle/kernel/k_linked_list.h b/src/core/hle/kernel/k_linked_list.h index 8362b6eda..8218bac8d 100644 --- a/src/core/hle/kernel/k_linked_list.h +++ b/src/core/hle/kernel/k_linked_list.h @@ -11,6 +11,8 @@ namespace Kernel { +class KernelCore; + class KLinkedListNode : public boost::intrusive::list_base_hook<>, public KSlabAllocated { private: @@ -118,11 +120,11 @@ public: }; public: - constexpr KLinkedList() : BaseList() {} + constexpr KLinkedList(KernelCore& kernel_) : BaseList(), kernel{kernel_} {} ~KLinkedList() { // Erase all elements. - for (auto it = this->begin(); it != this->end(); it = this->erase(it)) { + for (auto it = this->begin(); it != this->end(); it = this->erase(kernel, it)) { } // Ensure we succeeded. @@ -199,7 +201,7 @@ public: } iterator insert(const_iterator pos, reference ref) { - KLinkedListNode* node = KLinkedListNode::Allocate(); + KLinkedListNode* node = KLinkedListNode::Allocate(kernel); ASSERT(node != nullptr); node->Initialize(std::addressof(ref)); return iterator(BaseList::insert(pos.m_base_it, *node)); @@ -221,13 +223,16 @@ public: this->erase(this->begin()); } - iterator erase(const iterator pos) { + iterator erase(KernelCore& kernel, const iterator pos) { KLinkedListNode* freed_node = std::addressof(*pos.m_base_it); iterator ret = iterator(BaseList::erase(pos.m_base_it)); - KLinkedListNode::Free(freed_node); + KLinkedListNode::Free(kernel, freed_node); return ret; } + +private: + KernelCore& kernel; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 09382f7dd..1feda9303 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -617,7 +617,9 @@ KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core state.highest_priority_thread = nullptr; } -KScheduler::~KScheduler() = default; +KScheduler::~KScheduler() { + idle_thread->Close(); +} KThread* KScheduler::GetCurrentThread() const { if (auto result = current_thread.load(); result) { diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h index a3948cd27..5ce9a1d7c 100644 --- a/src/core/hle/kernel/k_slab_heap.h +++ b/src/core/hle/kernel/k_slab_heap.h @@ -97,6 +97,7 @@ public: void FreeImpl(void* obj) { // Don't allow freeing an object that wasn't allocated from this heap ASSERT(Contains(reinterpret_cast(obj))); + impl.Free(obj); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index b78602f46..855bb590a 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,9 +11,10 @@ #include #include "core/arm/cpu_interrupt_handler.h" #include "core/hardware_properties.h" +#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" -#include "core/hle/kernel/k_auto_object.h" namespace Core { class CPUInterruptHandler; @@ -32,6 +33,8 @@ class ClientPort; class GlobalSchedulerContext; class HandleTable; class KAutoObjectWithListContainer; +class KEvent; +class KLinkedListNode; class KMemoryManager; class KResourceLimit; class KScheduler; @@ -231,9 +234,10 @@ public: /** * Creates an HLE service thread, which are used to execute service routines asynchronously. - * While these are allocated per ServerSession, these need to be owned and managed outside of - * ServerSession to avoid a circular dependency. - * @param name String name for the ServerSession creating this thread, used for debug purposes. + * While these are allocated per ServerSession, these need to be owned and managed outside + * of ServerSession to avoid a circular dependency. + * @param name String name for the ServerSession creating this thread, used for debug + * purposes. * @returns The a weak pointer newly created service thread. */ std::weak_ptr CreateServiceThread(const std::string& name); @@ -252,6 +256,22 @@ public: Core::System& System(); const Core::System& System() const; + /// Gets the slab heap for the specified kernel object type. + template + KSlabHeap& SlabHeap() { + if constexpr (std::is_same_v) { + return slab_heap_Process; + } else if constexpr (std::is_same_v) { + return slab_heap_KThread; + } else if constexpr (std::is_same_v) { + return slab_heap_KEvent; + } else if constexpr (std::is_same_v) { + return slab_heap_KSharedMemory; + } else if constexpr (std::is_same_v) { + return slab_heap_KLinkedListNode; + } + } + private: friend class Object; friend class Process; @@ -277,7 +297,15 @@ private: struct Impl; std::unique_ptr impl; + bool exception_exited{}; + +private: + KSlabHeap slab_heap_Process; + KSlabHeap slab_heap_KThread; + KSlabHeap slab_heap_KEvent; + KSlabHeap slab_heap_KSharedMemory; + KSlabHeap slab_heap_KLinkedListNode; }; } // namespace Kernel diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h index ae9d097da..4f23ddabf 100644 --- a/src/core/hle/kernel/slab_helpers.h +++ b/src/core/hle/kernel/slab_helpers.h @@ -20,44 +20,44 @@ namespace Kernel { template class KSlabAllocated { -private: - static inline KSlabHeap s_slab_heap; - public: constexpr KSlabAllocated() = default; - size_t GetSlabIndex() const { - return s_slab_heap.GetIndex(static_cast(this)); + size_t GetSlabIndex(KernelCore& kernel) const { + return kernel.SlabHeap().GetIndex(static_cast(this)); } public: - static void InitializeSlabHeap(void* memory, size_t memory_size) { - s_slab_heap.Initialize(memory, memory_size); + static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) { + kernel.SlabHeap().Initialize(memory, memory_size); } - static Derived* Allocate() { - return s_slab_heap.Allocate(); + static Derived* Allocate(KernelCore& kernel) { + return kernel.SlabHeap().Allocate(); } - static void Free(Derived* obj) { - s_slab_heap.Free(obj); + static void Free(KernelCore& kernel, Derived* obj) { + kernel.SlabHeap().Free(obj); } - static size_t GetObjectSize() { - return s_slab_heap.GetObjectSize(); + static size_t GetObjectSize(KernelCore& kernel) { + return kernel.SlabHeap().GetObjectSize(); } - static size_t GetSlabHeapSize() { - return s_slab_heap.GetSlabHeapSize(); + + static size_t GetSlabHeapSize(KernelCore& kernel) { + return kernel.SlabHeap().GetSlabHeapSize(); } - static size_t GetPeakIndex() { - return s_slab_heap.GetPeakIndex(); + + static size_t GetPeakIndex(KernelCore& kernel) { + return kernel.SlabHeap().GetPeakIndex(); } - static uintptr_t GetSlabHeapAddress() { - return s_slab_heap.GetSlabHeapAddress(); + + static uintptr_t GetSlabHeapAddress(KernelCore& kernel) { + return kernel.SlabHeap().GetSlabHeapAddress(); } - static size_t GetNumRemaining() { - return s_slab_heap.GetNumRemaining(); + static size_t GetNumRemaining(KernelCore& kernel) { + return kernel.SlabHeap().GetNumRemaining(); } }; @@ -66,43 +66,38 @@ class KAutoObjectWithSlabHeapAndContainer : public Base { static_assert(std::is_base_of::value); private: - static inline KSlabHeap s_slab_heap; - KernelCore& m_kernel; - -private: - static Derived* Allocate() { - return s_slab_heap.Allocate(); + static Derived* Allocate(KernelCore& kernel) { + return kernel.SlabHeap().Allocate(); } static Derived* AllocateWithKernel(KernelCore& kernel) { - return s_slab_heap.AllocateWithKernel(kernel); + return kernel.SlabHeap().AllocateWithKernel(kernel); } - static void Free(Derived* obj) { - s_slab_heap.Free(obj); + static void Free(KernelCore& kernel, Derived* obj) { + kernel.SlabHeap().Free(obj); } public: class ListAccessor : public KAutoObjectWithListContainer::ListAccessor { public: - ListAccessor() - : KAutoObjectWithListContainer::ListAccessor(m_kernel.ObjectListContainer()) {} + ListAccessor() : KAutoObjectWithListContainer::ListAccessor(kernel.ObjectListContainer()) {} ~ListAccessor() = default; }; public: - KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel) : Base(kernel), m_kernel(kernel) {} + KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {} virtual ~KAutoObjectWithSlabHeapAndContainer() {} virtual void Destroy() override { const bool is_initialized = this->IsInitialized(); uintptr_t arg = 0; if (is_initialized) { - m_kernel.ObjectListContainer().Unregister(this); + kernel.ObjectListContainer().Unregister(this); arg = this->GetPostDestroyArgument(); this->Finalize(); } - Free(static_cast(this)); + Free(kernel, static_cast(this)); if (is_initialized) { Derived::PostDestroy(arg); } @@ -116,12 +111,12 @@ public: } size_t GetSlabIndex() const { - return s_slab_heap.GetObjectIndex(static_cast(this)); + return SlabHeap(kernel).GetObjectIndex(static_cast(this)); } public: static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) { - s_slab_heap.Initialize(memory, memory_size); + kernel.SlabHeap().Initialize(memory, memory_size); kernel.ObjectListContainer().Initialize(); } @@ -145,22 +140,28 @@ public: return kernel.ObjectListContainer().Register(obj); } - static size_t GetObjectSize() { - return s_slab_heap.GetObjectSize(); + static size_t GetObjectSize(KernelCore& kernel) { + return kernel.SlabHeap().GetObjectSize(); } - static size_t GetSlabHeapSize() { - return s_slab_heap.GetSlabHeapSize(); + + static size_t GetSlabHeapSize(KernelCore& kernel) { + return kernel.SlabHeap().GetSlabHeapSize(); } - static size_t GetPeakIndex() { - return s_slab_heap.GetPeakIndex(); + + static size_t GetPeakIndex(KernelCore& kernel) { + return kernel.SlabHeap().GetPeakIndex(); } - static uintptr_t GetSlabHeapAddress() { - return s_slab_heap.GetSlabHeapAddress(); + + static uintptr_t GetSlabHeapAddress(KernelCore& kernel) { + return kernel.SlabHeap().GetSlabHeapAddress(); } - static size_t GetNumRemaining() { - return s_slab_heap.GetNumRemaining(); + static size_t GetNumRemaining(KernelCore& kernel) { + return kernel.SlabHeap().GetNumRemaining(); } + +protected: + KernelCore& kernel; }; } // namespace Kernel -- cgit v1.2.3