summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/core/CMakeLists.txt1
-rw-r--r--src/core/hle/kernel/slab_helpers.h152
2 files changed, 153 insertions, 0 deletions
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
234 hle/kernel/service_thread.h 234 hle/kernel/service_thread.h
235 hle/kernel/session.cpp 235 hle/kernel/session.cpp
236 hle/kernel/session.h 236 hle/kernel/session.h
237 hle/kernel/slab_helpers.h
237 hle/kernel/svc.cpp 238 hle/kernel/svc.cpp
238 hle/kernel/svc.h 239 hle/kernel/svc.h
239 hle/kernel/svc_common.h 240 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 @@
1// Copyright 2021 yuzu Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <atomic>
8
9#include "common/assert.h"
10#include "common/common_funcs.h"
11#include "common/common_types.h"
12#include "common/intrusive_red_black_tree.h"
13#include "core/hle/kernel/k_auto_object.h"
14#include "core/hle/kernel/k_auto_object_container.h"
15#include "core/hle/kernel/k_light_lock.h"
16#include "core/hle/kernel/k_slab_heap.h"
17
18namespace Kernel {
19
20template <class Derived>
21class KSlabAllocated {
22private:
23 static inline KSlabHeap<Derived> s_slab_heap;
24
25public:
26 constexpr KSlabAllocated() = default;
27
28 size_t GetSlabIndex() const {
29 return s_slab_heap.GetIndex(static_cast<const Derived*>(this));
30 }
31
32public:
33 static void InitializeSlabHeap(void* memory, size_t memory_size) {
34 s_slab_heap.Initialize(memory, memory_size);
35 }
36
37 static Derived* Allocate() {
38 return s_slab_heap.Allocate();
39 }
40
41 static void Free(Derived* obj) {
42 s_slab_heap.Free(obj);
43 }
44
45 static size_t GetObjectSize() {
46 return s_slab_heap.GetObjectSize();
47 }
48 static size_t GetSlabHeapSize() {
49 return s_slab_heap.GetSlabHeapSize();
50 }
51 static size_t GetPeakIndex() {
52 return s_slab_heap.GetPeakIndex();
53 }
54 static uintptr_t GetSlabHeapAddress() {
55 return s_slab_heap.GetSlabHeapAddress();
56 }
57
58 static size_t GetNumRemaining() {
59 return s_slab_heap.GetNumRemaining();
60 }
61};
62
63template <typename Derived, typename Base>
64class KAutoObjectWithSlabHeapAndContainer : public Base {
65 static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
66
67private:
68 static inline KSlabHeap<Derived> s_slab_heap;
69 static inline KAutoObjectWithListContainer s_container;
70
71private:
72 static Derived* Allocate() {
73 return s_slab_heap.Allocate();
74 }
75
76 static void Free(Derived* obj) {
77 s_slab_heap.Free(obj);
78 }
79
80public:
81 class ListAccessor : public KAutoObjectWithListContainer::ListAccessor {
82 public:
83 ListAccessor() : KAutoObjectWithListContainer::ListAccessor(s_container) {}
84 ~ListAccessor() = default;
85 };
86
87public:
88 constexpr KAutoObjectWithSlabHeapAndContainer() : Base() {}
89 virtual ~KAutoObjectWithSlabHeapAndContainer() {}
90
91 virtual void Destroy() override {
92 const bool is_initialized = this->IsInitialized();
93 uintptr_t arg = 0;
94 if (is_initialized) {
95 s_container.Unregister(this);
96 arg = this->GetPostDestroyArgument();
97 this->Finalize();
98 }
99 Free(static_cast<Derived*>(this));
100 if (is_initialized) {
101 Derived::PostDestroy(arg);
102 }
103 }
104
105 virtual bool IsInitialized() const {
106 return true;
107 }
108 virtual uintptr_t GetPostDestroyArgument() const {
109 return 0;
110 }
111
112 size_t GetSlabIndex() const {
113 return s_slab_heap.GetObjectIndex(static_cast<const Derived*>(this));
114 }
115
116public:
117 static void InitializeSlabHeap(void* memory, size_t memory_size) {
118 s_slab_heap.Initialize(memory, memory_size);
119 s_container.Initialize();
120 }
121
122 static Derived* Create() {
123 Derived* obj = Allocate();
124 if (AMS_LIKELY(obj != nullptr)) {
125 KAutoObject::Create(obj);
126 }
127 return obj;
128 }
129
130 static void Register(Derived* obj) {
131 return s_container.Register(obj);
132 }
133
134 static size_t GetObjectSize() {
135 return s_slab_heap.GetObjectSize();
136 }
137 static size_t GetSlabHeapSize() {
138 return s_slab_heap.GetSlabHeapSize();
139 }
140 static size_t GetPeakIndex() {
141 return s_slab_heap.GetPeakIndex();
142 }
143 static uintptr_t GetSlabHeapAddress() {
144 return s_slab_heap.GetSlabHeapAddress();
145 }
146
147 static size_t GetNumRemaining() {
148 return s_slab_heap.GetNumRemaining();
149 }
150};
151
152} // namespace Kernel