From f93d939426be2ebe0f334b157f3dad70f52ad418 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 31 Mar 2021 21:12:33 -0700 Subject: hle: kernel: Add initial impl. of KSlabAllocated. --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/slab_helpers.h | 152 +++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+) create mode 100644 src/core/hle/kernel/slab_helpers.h diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 3cc5b7fbc..f5e06045f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -234,6 +234,7 @@ add_library(core STATIC hle/kernel/service_thread.h hle/kernel/session.cpp hle/kernel/session.h + hle/kernel/slab_helpers.h hle/kernel/svc.cpp hle/kernel/svc.h hle/kernel/svc_common.h diff --git a/src/core/hle/kernel/slab_helpers.h b/src/core/hle/kernel/slab_helpers.h new file mode 100644 index 000000000..d95095da3 --- /dev/null +++ b/src/core/hle/kernel/slab_helpers.h @@ -0,0 +1,152 @@ +// Copyright 2021 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +#include "common/assert.h" +#include "common/common_funcs.h" +#include "common/common_types.h" +#include "common/intrusive_red_black_tree.h" +#include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/k_auto_object_container.h" +#include "core/hle/kernel/k_light_lock.h" +#include "core/hle/kernel/k_slab_heap.h" + +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)); + } + +public: + static void InitializeSlabHeap(void* memory, size_t memory_size) { + s_slab_heap.Initialize(memory, memory_size); + } + + static Derived* Allocate() { + return s_slab_heap.Allocate(); + } + + static void Free(Derived* obj) { + s_slab_heap.Free(obj); + } + + static size_t GetObjectSize() { + return s_slab_heap.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() { + return s_slab_heap.GetNumRemaining(); + } +}; + +template +class KAutoObjectWithSlabHeapAndContainer : public Base { + static_assert(std::is_base_of::value); + +private: + static inline KSlabHeap s_slab_heap; + static inline KAutoObjectWithListContainer s_container; + +private: + static Derived* Allocate() { + return s_slab_heap.Allocate(); + } + + static void Free(Derived* obj) { + s_slab_heap.Free(obj); + } + +public: + class ListAccessor : public KAutoObjectWithListContainer::ListAccessor { + public: + ListAccessor() : KAutoObjectWithListContainer::ListAccessor(s_container) {} + ~ListAccessor() = default; + }; + +public: + constexpr KAutoObjectWithSlabHeapAndContainer() : Base() {} + virtual ~KAutoObjectWithSlabHeapAndContainer() {} + + virtual void Destroy() override { + const bool is_initialized = this->IsInitialized(); + uintptr_t arg = 0; + if (is_initialized) { + s_container.Unregister(this); + arg = this->GetPostDestroyArgument(); + this->Finalize(); + } + Free(static_cast(this)); + if (is_initialized) { + Derived::PostDestroy(arg); + } + } + + virtual bool IsInitialized() const { + return true; + } + virtual uintptr_t GetPostDestroyArgument() const { + return 0; + } + + size_t GetSlabIndex() const { + return s_slab_heap.GetObjectIndex(static_cast(this)); + } + +public: + static void InitializeSlabHeap(void* memory, size_t memory_size) { + s_slab_heap.Initialize(memory, memory_size); + s_container.Initialize(); + } + + static Derived* Create() { + Derived* obj = Allocate(); + if (AMS_LIKELY(obj != nullptr)) { + KAutoObject::Create(obj); + } + return obj; + } + + static void Register(Derived* obj) { + return s_container.Register(obj); + } + + static size_t GetObjectSize() { + return s_slab_heap.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() { + return s_slab_heap.GetNumRemaining(); + } +}; + +} // namespace Kernel -- cgit v1.2.3