forked from suyu/suyu
hle: kernel: Move slab heap management to KernelCore.
This commit is contained in:
parent
ab704acab8
commit
b6156e735c
7 changed files with 112 additions and 70 deletions
|
@ -185,8 +185,8 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) {
|
||||||
thread->Wakeup();
|
thread->Wakeup();
|
||||||
} else {
|
} else {
|
||||||
// Get the previous owner.
|
// Get the previous owner.
|
||||||
KThread* owner_thread =
|
KThread* owner_thread = kernel.CurrentProcess()
|
||||||
kernel.CurrentProcess()->GetHandleTable()
|
->GetHandleTable()
|
||||||
.GetObjectWithoutPseudoHandle<KThread>(
|
.GetObjectWithoutPseudoHandle<KThread>(
|
||||||
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
|
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
|
||||||
.ReleasePointerUnsafe();
|
.ReleasePointerUnsafe();
|
||||||
|
@ -214,7 +214,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
|
||||||
// Prepare for signaling.
|
// Prepare for signaling.
|
||||||
constexpr int MaxThreads = 16;
|
constexpr int MaxThreads = 16;
|
||||||
|
|
||||||
KLinkedList<KThread> thread_list;
|
KLinkedList<KThread> thread_list{kernel};
|
||||||
std::array<KThread*, MaxThreads> thread_array;
|
std::array<KThread*, MaxThreads> thread_array;
|
||||||
s32 num_to_close{};
|
s32 num_to_close{};
|
||||||
|
|
||||||
|
@ -254,7 +254,8 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close threads in the list.
|
// 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();
|
(*it).Close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,10 @@ void KEvent::Initialize(std::string&& name_) {
|
||||||
// writable events are closed this object will be destroyed.
|
// writable events are closed this object will be destroyed.
|
||||||
Open();
|
Open();
|
||||||
|
|
||||||
|
//// Create our sub events.
|
||||||
|
//KAutoObject::Create(readable_event.get());
|
||||||
|
//KAutoObject::Create(writable_event.get());
|
||||||
|
|
||||||
// Create our sub events.
|
// Create our sub events.
|
||||||
readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable");
|
readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable");
|
||||||
writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable");
|
writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable");
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
|
class KernelCore;
|
||||||
|
|
||||||
class KLinkedListNode : public boost::intrusive::list_base_hook<>,
|
class KLinkedListNode : public boost::intrusive::list_base_hook<>,
|
||||||
public KSlabAllocated<KLinkedListNode> {
|
public KSlabAllocated<KLinkedListNode> {
|
||||||
private:
|
private:
|
||||||
|
@ -118,11 +120,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr KLinkedList() : BaseList() {}
|
constexpr KLinkedList(KernelCore& kernel_) : BaseList(), kernel{kernel_} {}
|
||||||
|
|
||||||
~KLinkedList() {
|
~KLinkedList() {
|
||||||
// Erase all elements.
|
// 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.
|
// Ensure we succeeded.
|
||||||
|
@ -199,7 +201,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator insert(const_iterator pos, reference ref) {
|
iterator insert(const_iterator pos, reference ref) {
|
||||||
KLinkedListNode* node = KLinkedListNode::Allocate();
|
KLinkedListNode* node = KLinkedListNode::Allocate(kernel);
|
||||||
ASSERT(node != nullptr);
|
ASSERT(node != nullptr);
|
||||||
node->Initialize(std::addressof(ref));
|
node->Initialize(std::addressof(ref));
|
||||||
return iterator(BaseList::insert(pos.m_base_it, *node));
|
return iterator(BaseList::insert(pos.m_base_it, *node));
|
||||||
|
@ -221,13 +223,16 @@ public:
|
||||||
this->erase(this->begin());
|
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);
|
KLinkedListNode* freed_node = std::addressof(*pos.m_base_it);
|
||||||
iterator ret = iterator(BaseList::erase(pos.m_base_it));
|
iterator ret = iterator(BaseList::erase(pos.m_base_it));
|
||||||
KLinkedListNode::Free(freed_node);
|
KLinkedListNode::Free(kernel, freed_node);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
KernelCore& kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -617,7 +617,9 @@ KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core
|
||||||
state.highest_priority_thread = nullptr;
|
state.highest_priority_thread = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
KScheduler::~KScheduler() = default;
|
KScheduler::~KScheduler() {
|
||||||
|
idle_thread->Close();
|
||||||
|
}
|
||||||
|
|
||||||
KThread* KScheduler::GetCurrentThread() const {
|
KThread* KScheduler::GetCurrentThread() const {
|
||||||
if (auto result = current_thread.load(); result) {
|
if (auto result = current_thread.load(); result) {
|
||||||
|
|
|
@ -97,6 +97,7 @@ public:
|
||||||
void FreeImpl(void* obj) {
|
void FreeImpl(void* obj) {
|
||||||
// Don't allow freeing an object that wasn't allocated from this heap
|
// Don't allow freeing an object that wasn't allocated from this heap
|
||||||
ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
|
ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
|
||||||
|
|
||||||
impl.Free(obj);
|
impl.Free(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,9 +11,10 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "core/arm/cpu_interrupt_handler.h"
|
#include "core/arm/cpu_interrupt_handler.h"
|
||||||
#include "core/hardware_properties.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/memory_types.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/k_auto_object.h"
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
class CPUInterruptHandler;
|
class CPUInterruptHandler;
|
||||||
|
@ -32,6 +33,8 @@ class ClientPort;
|
||||||
class GlobalSchedulerContext;
|
class GlobalSchedulerContext;
|
||||||
class HandleTable;
|
class HandleTable;
|
||||||
class KAutoObjectWithListContainer;
|
class KAutoObjectWithListContainer;
|
||||||
|
class KEvent;
|
||||||
|
class KLinkedListNode;
|
||||||
class KMemoryManager;
|
class KMemoryManager;
|
||||||
class KResourceLimit;
|
class KResourceLimit;
|
||||||
class KScheduler;
|
class KScheduler;
|
||||||
|
@ -231,9 +234,10 @@ public:
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an HLE service thread, which are used to execute service routines asynchronously.
|
* 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
|
* While these are allocated per ServerSession, these need to be owned and managed outside
|
||||||
* ServerSession to avoid a circular dependency.
|
* of ServerSession to avoid a circular dependency.
|
||||||
* @param name String name for the ServerSession creating this thread, used for debug purposes.
|
* @param name String name for the ServerSession creating this thread, used for debug
|
||||||
|
* purposes.
|
||||||
* @returns The a weak pointer newly created service thread.
|
* @returns The a weak pointer newly created service thread.
|
||||||
*/
|
*/
|
||||||
std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name);
|
std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name);
|
||||||
|
@ -252,6 +256,22 @@ public:
|
||||||
Core::System& System();
|
Core::System& System();
|
||||||
const Core::System& System() const;
|
const Core::System& System() const;
|
||||||
|
|
||||||
|
/// Gets the slab heap for the specified kernel object type.
|
||||||
|
template <typename T>
|
||||||
|
KSlabHeap<T>& SlabHeap() {
|
||||||
|
if constexpr (std::is_same_v<T, Process>) {
|
||||||
|
return slab_heap_Process;
|
||||||
|
} else if constexpr (std::is_same_v<T, KThread>) {
|
||||||
|
return slab_heap_KThread;
|
||||||
|
} else if constexpr (std::is_same_v<T, KEvent>) {
|
||||||
|
return slab_heap_KEvent;
|
||||||
|
} else if constexpr (std::is_same_v<T, KSharedMemory>) {
|
||||||
|
return slab_heap_KSharedMemory;
|
||||||
|
} else if constexpr (std::is_same_v<T, KLinkedListNode>) {
|
||||||
|
return slab_heap_KLinkedListNode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class Object;
|
friend class Object;
|
||||||
friend class Process;
|
friend class Process;
|
||||||
|
@ -277,7 +297,15 @@ private:
|
||||||
|
|
||||||
struct Impl;
|
struct Impl;
|
||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
|
|
||||||
bool exception_exited{};
|
bool exception_exited{};
|
||||||
|
|
||||||
|
private:
|
||||||
|
KSlabHeap<Process> slab_heap_Process;
|
||||||
|
KSlabHeap<KThread> slab_heap_KThread;
|
||||||
|
KSlabHeap<KEvent> slab_heap_KEvent;
|
||||||
|
KSlabHeap<KSharedMemory> slab_heap_KSharedMemory;
|
||||||
|
KSlabHeap<KLinkedListNode> slab_heap_KLinkedListNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -20,44 +20,44 @@ namespace Kernel {
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
class KSlabAllocated {
|
class KSlabAllocated {
|
||||||
private:
|
|
||||||
static inline KSlabHeap<Derived> s_slab_heap;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr KSlabAllocated() = default;
|
constexpr KSlabAllocated() = default;
|
||||||
|
|
||||||
size_t GetSlabIndex() const {
|
size_t GetSlabIndex(KernelCore& kernel) const {
|
||||||
return s_slab_heap.GetIndex(static_cast<const Derived*>(this));
|
return kernel.SlabHeap<Derived>().GetIndex(static_cast<const Derived*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void InitializeSlabHeap(void* memory, size_t memory_size) {
|
static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
|
||||||
s_slab_heap.Initialize(memory, memory_size);
|
kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Derived* Allocate() {
|
static Derived* Allocate(KernelCore& kernel) {
|
||||||
return s_slab_heap.Allocate();
|
return kernel.SlabHeap<Derived>().Allocate();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Free(Derived* obj) {
|
static void Free(KernelCore& kernel, Derived* obj) {
|
||||||
s_slab_heap.Free(obj);
|
kernel.SlabHeap<Derived>().Free(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetObjectSize() {
|
static size_t GetObjectSize(KernelCore& kernel) {
|
||||||
return s_slab_heap.GetObjectSize();
|
return kernel.SlabHeap<Derived>().GetObjectSize();
|
||||||
}
|
|
||||||
static size_t GetSlabHeapSize() {
|
|
||||||
return s_slab_heap.GetSlabHeapSize();
|
|
||||||
}
|
|
||||||
static size_t GetPeakIndex() {
|
|
||||||
return s_slab_heap.GetPeakIndex();
|
|
||||||
}
|
|
||||||
static uintptr_t GetSlabHeapAddress() {
|
|
||||||
return s_slab_heap.GetSlabHeapAddress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetNumRemaining() {
|
static size_t GetSlabHeapSize(KernelCore& kernel) {
|
||||||
return s_slab_heap.GetNumRemaining();
|
return kernel.SlabHeap<Derived>().GetSlabHeapSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t GetPeakIndex(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetPeakIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t GetNumRemaining(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetNumRemaining();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -66,43 +66,38 @@ class KAutoObjectWithSlabHeapAndContainer : public Base {
|
||||||
static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
|
static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline KSlabHeap<Derived> s_slab_heap;
|
static Derived* Allocate(KernelCore& kernel) {
|
||||||
KernelCore& m_kernel;
|
return kernel.SlabHeap<Derived>().Allocate();
|
||||||
|
|
||||||
private:
|
|
||||||
static Derived* Allocate() {
|
|
||||||
return s_slab_heap.Allocate();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Derived* AllocateWithKernel(KernelCore& kernel) {
|
static Derived* AllocateWithKernel(KernelCore& kernel) {
|
||||||
return s_slab_heap.AllocateWithKernel(kernel);
|
return kernel.SlabHeap<Derived>().AllocateWithKernel(kernel);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Free(Derived* obj) {
|
static void Free(KernelCore& kernel, Derived* obj) {
|
||||||
s_slab_heap.Free(obj);
|
kernel.SlabHeap<Derived>().Free(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
class ListAccessor : public KAutoObjectWithListContainer::ListAccessor {
|
class ListAccessor : public KAutoObjectWithListContainer::ListAccessor {
|
||||||
public:
|
public:
|
||||||
ListAccessor()
|
ListAccessor() : KAutoObjectWithListContainer::ListAccessor(kernel.ObjectListContainer()) {}
|
||||||
: KAutoObjectWithListContainer::ListAccessor(m_kernel.ObjectListContainer()) {}
|
|
||||||
~ListAccessor() = default;
|
~ListAccessor() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel) : Base(kernel), m_kernel(kernel) {}
|
KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {}
|
||||||
virtual ~KAutoObjectWithSlabHeapAndContainer() {}
|
virtual ~KAutoObjectWithSlabHeapAndContainer() {}
|
||||||
|
|
||||||
virtual void Destroy() override {
|
virtual void Destroy() override {
|
||||||
const bool is_initialized = this->IsInitialized();
|
const bool is_initialized = this->IsInitialized();
|
||||||
uintptr_t arg = 0;
|
uintptr_t arg = 0;
|
||||||
if (is_initialized) {
|
if (is_initialized) {
|
||||||
m_kernel.ObjectListContainer().Unregister(this);
|
kernel.ObjectListContainer().Unregister(this);
|
||||||
arg = this->GetPostDestroyArgument();
|
arg = this->GetPostDestroyArgument();
|
||||||
this->Finalize();
|
this->Finalize();
|
||||||
}
|
}
|
||||||
Free(static_cast<Derived*>(this));
|
Free(kernel, static_cast<Derived*>(this));
|
||||||
if (is_initialized) {
|
if (is_initialized) {
|
||||||
Derived::PostDestroy(arg);
|
Derived::PostDestroy(arg);
|
||||||
}
|
}
|
||||||
|
@ -116,12 +111,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GetSlabIndex() const {
|
size_t GetSlabIndex() const {
|
||||||
return s_slab_heap.GetObjectIndex(static_cast<const Derived*>(this));
|
return SlabHeap<Derived>(kernel).GetObjectIndex(static_cast<const Derived*>(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
|
static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
|
||||||
s_slab_heap.Initialize(memory, memory_size);
|
kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
|
||||||
kernel.ObjectListContainer().Initialize();
|
kernel.ObjectListContainer().Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,22 +140,28 @@ public:
|
||||||
return kernel.ObjectListContainer().Register(obj);
|
return kernel.ObjectListContainer().Register(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetObjectSize() {
|
static size_t GetObjectSize(KernelCore& kernel) {
|
||||||
return s_slab_heap.GetObjectSize();
|
return kernel.SlabHeap<Derived>().GetObjectSize();
|
||||||
}
|
|
||||||
static size_t GetSlabHeapSize() {
|
|
||||||
return s_slab_heap.GetSlabHeapSize();
|
|
||||||
}
|
|
||||||
static size_t GetPeakIndex() {
|
|
||||||
return s_slab_heap.GetPeakIndex();
|
|
||||||
}
|
|
||||||
static uintptr_t GetSlabHeapAddress() {
|
|
||||||
return s_slab_heap.GetSlabHeapAddress();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t GetNumRemaining() {
|
static size_t GetSlabHeapSize(KernelCore& kernel) {
|
||||||
return s_slab_heap.GetNumRemaining();
|
return kernel.SlabHeap<Derived>().GetSlabHeapSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static size_t GetPeakIndex(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetPeakIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t GetNumRemaining(KernelCore& kernel) {
|
||||||
|
return kernel.SlabHeap<Derived>().GetNumRemaining();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
KernelCore& kernel;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
Loading…
Reference in a new issue