summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2021-04-09 22:10:14 -0700
committerGravatar bunnei2021-05-05 16:40:51 -0700
commitb6156e735cd78d4b7863491ae6bdc63e44404b73 (patch)
treee1ec7753ea7c86223135e2f51b1b1f649af48b90 /src
parenthle: kernel: Ensure all kernel objects with KAutoObject are properly created. (diff)
downloadyuzu-b6156e735cd78d4b7863491ae6bdc63e44404b73.tar.gz
yuzu-b6156e735cd78d4b7863491ae6bdc63e44404b73.tar.xz
yuzu-b6156e735cd78d4b7863491ae6bdc63e44404b73.zip
hle: kernel: Move slab heap management to KernelCore.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/k_condition_variable.cpp15
-rw-r--r--src/core/hle/kernel/k_event.cpp4
-rw-r--r--src/core/hle/kernel/k_linked_list.h15
-rw-r--r--src/core/hle/kernel/k_scheduler.cpp4
-rw-r--r--src/core/hle/kernel/k_slab_heap.h1
-rw-r--r--src/core/hle/kernel/kernel.h36
-rw-r--r--src/core/hle/kernel/slab_helpers.h95
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) {
185 thread->Wakeup(); 185 thread->Wakeup();
186 } else { 186 } else {
187 // Get the previous owner. 187 // Get the previous owner.
188 KThread* owner_thread = 188 KThread* owner_thread = kernel.CurrentProcess()
189 kernel.CurrentProcess()->GetHandleTable() 189 ->GetHandleTable()
190 .GetObjectWithoutPseudoHandle<KThread>( 190 .GetObjectWithoutPseudoHandle<KThread>(
191 static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask)) 191 static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
192 .ReleasePointerUnsafe(); 192 .ReleasePointerUnsafe();
193 193
194 if (owner_thread) { 194 if (owner_thread) {
195 // Add the thread as a waiter on the owner. 195 // Add the thread as a waiter on the owner.
@@ -214,7 +214,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
214 // Prepare for signaling. 214 // Prepare for signaling.
215 constexpr int MaxThreads = 16; 215 constexpr int MaxThreads = 16;
216 216
217 KLinkedList<KThread> thread_list; 217 KLinkedList<KThread> thread_list{kernel};
218 std::array<KThread*, MaxThreads> thread_array; 218 std::array<KThread*, MaxThreads> thread_array;
219 s32 num_to_close{}; 219 s32 num_to_close{};
220 220
@@ -254,7 +254,8 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
254 } 254 }
255 255
256 // Close threads in the list. 256 // Close threads in the list.
257 for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) { 257 for (auto it = thread_list.begin(); it != thread_list.end();
258 it = thread_list.erase(kernel, it)) {
258 (*it).Close(); 259 (*it).Close();
259 } 260 }
260} 261}
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_) {
21 // writable events are closed this object will be destroyed. 21 // writable events are closed this object will be destroyed.
22 Open(); 22 Open();
23 23
24 //// Create our sub events.
25 //KAutoObject::Create(readable_event.get());
26 //KAutoObject::Create(writable_event.get());
27
24 // Create our sub events. 28 // Create our sub events.
25 readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable"); 29 readable_event = std::make_shared<KReadableEvent>(kernel, name_ + ":Readable");
26 writable_event = std::make_shared<KWritableEvent>(kernel, name_ + ":Writable"); 30 writable_event = std::make_shared<KWritableEvent>(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 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14class KernelCore;
15
14class KLinkedListNode : public boost::intrusive::list_base_hook<>, 16class KLinkedListNode : public boost::intrusive::list_base_hook<>,
15 public KSlabAllocated<KLinkedListNode> { 17 public KSlabAllocated<KLinkedListNode> {
16private: 18private:
@@ -118,11 +120,11 @@ public:
118 }; 120 };
119 121
120public: 122public:
121 constexpr KLinkedList() : BaseList() {} 123 constexpr KLinkedList(KernelCore& kernel_) : BaseList(), kernel{kernel_} {}
122 124
123 ~KLinkedList() { 125 ~KLinkedList() {
124 // Erase all elements. 126 // Erase all elements.
125 for (auto it = this->begin(); it != this->end(); it = this->erase(it)) { 127 for (auto it = this->begin(); it != this->end(); it = this->erase(kernel, it)) {
126 } 128 }
127 129
128 // Ensure we succeeded. 130 // Ensure we succeeded.
@@ -199,7 +201,7 @@ public:
199 } 201 }
200 202
201 iterator insert(const_iterator pos, reference ref) { 203 iterator insert(const_iterator pos, reference ref) {
202 KLinkedListNode* node = KLinkedListNode::Allocate(); 204 KLinkedListNode* node = KLinkedListNode::Allocate(kernel);
203 ASSERT(node != nullptr); 205 ASSERT(node != nullptr);
204 node->Initialize(std::addressof(ref)); 206 node->Initialize(std::addressof(ref));
205 return iterator(BaseList::insert(pos.m_base_it, *node)); 207 return iterator(BaseList::insert(pos.m_base_it, *node));
@@ -221,13 +223,16 @@ public:
221 this->erase(this->begin()); 223 this->erase(this->begin());
222 } 224 }
223 225
224 iterator erase(const iterator pos) { 226 iterator erase(KernelCore& kernel, const iterator pos) {
225 KLinkedListNode* freed_node = std::addressof(*pos.m_base_it); 227 KLinkedListNode* freed_node = std::addressof(*pos.m_base_it);
226 iterator ret = iterator(BaseList::erase(pos.m_base_it)); 228 iterator ret = iterator(BaseList::erase(pos.m_base_it));
227 KLinkedListNode::Free(freed_node); 229 KLinkedListNode::Free(kernel, freed_node);
228 230
229 return ret; 231 return ret;
230 } 232 }
233
234private:
235 KernelCore& kernel;
231}; 236};
232 237
233} // namespace Kernel 238} // 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
617 state.highest_priority_thread = nullptr; 617 state.highest_priority_thread = nullptr;
618} 618}
619 619
620KScheduler::~KScheduler() = default; 620KScheduler::~KScheduler() {
621 idle_thread->Close();
622}
621 623
622KThread* KScheduler::GetCurrentThread() const { 624KThread* KScheduler::GetCurrentThread() const {
623 if (auto result = current_thread.load(); result) { 625 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:
97 void FreeImpl(void* obj) { 97 void FreeImpl(void* obj) {
98 // Don't allow freeing an object that wasn't allocated from this heap 98 // Don't allow freeing an object that wasn't allocated from this heap
99 ASSERT(Contains(reinterpret_cast<uintptr_t>(obj))); 99 ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
100
100 impl.Free(obj); 101 impl.Free(obj);
101 } 102 }
102 103
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 @@
11#include <vector> 11#include <vector>
12#include "core/arm/cpu_interrupt_handler.h" 12#include "core/arm/cpu_interrupt_handler.h"
13#include "core/hardware_properties.h" 13#include "core/hardware_properties.h"
14#include "core/hle/kernel/k_auto_object.h"
15#include "core/hle/kernel/k_slab_heap.h"
14#include "core/hle/kernel/memory_types.h" 16#include "core/hle/kernel/memory_types.h"
15#include "core/hle/kernel/object.h" 17#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/k_auto_object.h"
17 18
18namespace Core { 19namespace Core {
19class CPUInterruptHandler; 20class CPUInterruptHandler;
@@ -32,6 +33,8 @@ class ClientPort;
32class GlobalSchedulerContext; 33class GlobalSchedulerContext;
33class HandleTable; 34class HandleTable;
34class KAutoObjectWithListContainer; 35class KAutoObjectWithListContainer;
36class KEvent;
37class KLinkedListNode;
35class KMemoryManager; 38class KMemoryManager;
36class KResourceLimit; 39class KResourceLimit;
37class KScheduler; 40class KScheduler;
@@ -231,9 +234,10 @@ public:
231 234
232 /** 235 /**
233 * Creates an HLE service thread, which are used to execute service routines asynchronously. 236 * Creates an HLE service thread, which are used to execute service routines asynchronously.
234 * While these are allocated per ServerSession, these need to be owned and managed outside of 237 * While these are allocated per ServerSession, these need to be owned and managed outside
235 * ServerSession to avoid a circular dependency. 238 * of ServerSession to avoid a circular dependency.
236 * @param name String name for the ServerSession creating this thread, used for debug purposes. 239 * @param name String name for the ServerSession creating this thread, used for debug
240 * purposes.
237 * @returns The a weak pointer newly created service thread. 241 * @returns The a weak pointer newly created service thread.
238 */ 242 */
239 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name); 243 std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name);
@@ -252,6 +256,22 @@ public:
252 Core::System& System(); 256 Core::System& System();
253 const Core::System& System() const; 257 const Core::System& System() const;
254 258
259 /// Gets the slab heap for the specified kernel object type.
260 template <typename T>
261 KSlabHeap<T>& SlabHeap() {
262 if constexpr (std::is_same_v<T, Process>) {
263 return slab_heap_Process;
264 } else if constexpr (std::is_same_v<T, KThread>) {
265 return slab_heap_KThread;
266 } else if constexpr (std::is_same_v<T, KEvent>) {
267 return slab_heap_KEvent;
268 } else if constexpr (std::is_same_v<T, KSharedMemory>) {
269 return slab_heap_KSharedMemory;
270 } else if constexpr (std::is_same_v<T, KLinkedListNode>) {
271 return slab_heap_KLinkedListNode;
272 }
273 }
274
255private: 275private:
256 friend class Object; 276 friend class Object;
257 friend class Process; 277 friend class Process;
@@ -277,7 +297,15 @@ private:
277 297
278 struct Impl; 298 struct Impl;
279 std::unique_ptr<Impl> impl; 299 std::unique_ptr<Impl> impl;
300
280 bool exception_exited{}; 301 bool exception_exited{};
302
303private:
304 KSlabHeap<Process> slab_heap_Process;
305 KSlabHeap<KThread> slab_heap_KThread;
306 KSlabHeap<KEvent> slab_heap_KEvent;
307 KSlabHeap<KSharedMemory> slab_heap_KSharedMemory;
308 KSlabHeap<KLinkedListNode> slab_heap_KLinkedListNode;
281}; 309};
282 310
283} // namespace Kernel 311} // 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 {
20 20
21template <class Derived> 21template <class Derived>
22class KSlabAllocated { 22class KSlabAllocated {
23private:
24 static inline KSlabHeap<Derived> s_slab_heap;
25
26public: 23public:
27 constexpr KSlabAllocated() = default; 24 constexpr KSlabAllocated() = default;
28 25
29 size_t GetSlabIndex() const { 26 size_t GetSlabIndex(KernelCore& kernel) const {
30 return s_slab_heap.GetIndex(static_cast<const Derived*>(this)); 27 return kernel.SlabHeap<Derived>().GetIndex(static_cast<const Derived*>(this));
31 } 28 }
32 29
33public: 30public:
34 static void InitializeSlabHeap(void* memory, size_t memory_size) { 31 static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
35 s_slab_heap.Initialize(memory, memory_size); 32 kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
36 } 33 }
37 34
38 static Derived* Allocate() { 35 static Derived* Allocate(KernelCore& kernel) {
39 return s_slab_heap.Allocate(); 36 return kernel.SlabHeap<Derived>().Allocate();
40 } 37 }
41 38
42 static void Free(Derived* obj) { 39 static void Free(KernelCore& kernel, Derived* obj) {
43 s_slab_heap.Free(obj); 40 kernel.SlabHeap<Derived>().Free(obj);
44 } 41 }
45 42
46 static size_t GetObjectSize() { 43 static size_t GetObjectSize(KernelCore& kernel) {
47 return s_slab_heap.GetObjectSize(); 44 return kernel.SlabHeap<Derived>().GetObjectSize();
48 } 45 }
49 static size_t GetSlabHeapSize() { 46
50 return s_slab_heap.GetSlabHeapSize(); 47 static size_t GetSlabHeapSize(KernelCore& kernel) {
48 return kernel.SlabHeap<Derived>().GetSlabHeapSize();
51 } 49 }
52 static size_t GetPeakIndex() { 50
53 return s_slab_heap.GetPeakIndex(); 51 static size_t GetPeakIndex(KernelCore& kernel) {
52 return kernel.SlabHeap<Derived>().GetPeakIndex();
54 } 53 }
55 static uintptr_t GetSlabHeapAddress() { 54
56 return s_slab_heap.GetSlabHeapAddress(); 55 static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
56 return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
57 } 57 }
58 58
59 static size_t GetNumRemaining() { 59 static size_t GetNumRemaining(KernelCore& kernel) {
60 return s_slab_heap.GetNumRemaining(); 60 return kernel.SlabHeap<Derived>().GetNumRemaining();
61 } 61 }
62}; 62};
63 63
@@ -66,43 +66,38 @@ class KAutoObjectWithSlabHeapAndContainer : public Base {
66 static_assert(std::is_base_of<KAutoObjectWithList, Base>::value); 66 static_assert(std::is_base_of<KAutoObjectWithList, Base>::value);
67 67
68private: 68private:
69 static inline KSlabHeap<Derived> s_slab_heap; 69 static Derived* Allocate(KernelCore& kernel) {
70 KernelCore& m_kernel; 70 return kernel.SlabHeap<Derived>().Allocate();
71
72private:
73 static Derived* Allocate() {
74 return s_slab_heap.Allocate();
75 } 71 }
76 72
77 static Derived* AllocateWithKernel(KernelCore& kernel) { 73 static Derived* AllocateWithKernel(KernelCore& kernel) {
78 return s_slab_heap.AllocateWithKernel(kernel); 74 return kernel.SlabHeap<Derived>().AllocateWithKernel(kernel);
79 } 75 }
80 76
81 static void Free(Derived* obj) { 77 static void Free(KernelCore& kernel, Derived* obj) {
82 s_slab_heap.Free(obj); 78 kernel.SlabHeap<Derived>().Free(obj);
83 } 79 }
84 80
85public: 81public:
86 class ListAccessor : public KAutoObjectWithListContainer::ListAccessor { 82 class ListAccessor : public KAutoObjectWithListContainer::ListAccessor {
87 public: 83 public:
88 ListAccessor() 84 ListAccessor() : KAutoObjectWithListContainer::ListAccessor(kernel.ObjectListContainer()) {}
89 : KAutoObjectWithListContainer::ListAccessor(m_kernel.ObjectListContainer()) {}
90 ~ListAccessor() = default; 85 ~ListAccessor() = default;
91 }; 86 };
92 87
93public: 88public:
94 KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel) : Base(kernel), m_kernel(kernel) {} 89 KAutoObjectWithSlabHeapAndContainer(KernelCore& kernel_) : Base(kernel_), kernel(kernel_) {}
95 virtual ~KAutoObjectWithSlabHeapAndContainer() {} 90 virtual ~KAutoObjectWithSlabHeapAndContainer() {}
96 91
97 virtual void Destroy() override { 92 virtual void Destroy() override {
98 const bool is_initialized = this->IsInitialized(); 93 const bool is_initialized = this->IsInitialized();
99 uintptr_t arg = 0; 94 uintptr_t arg = 0;
100 if (is_initialized) { 95 if (is_initialized) {
101 m_kernel.ObjectListContainer().Unregister(this); 96 kernel.ObjectListContainer().Unregister(this);
102 arg = this->GetPostDestroyArgument(); 97 arg = this->GetPostDestroyArgument();
103 this->Finalize(); 98 this->Finalize();
104 } 99 }
105 Free(static_cast<Derived*>(this)); 100 Free(kernel, static_cast<Derived*>(this));
106 if (is_initialized) { 101 if (is_initialized) {
107 Derived::PostDestroy(arg); 102 Derived::PostDestroy(arg);
108 } 103 }
@@ -116,12 +111,12 @@ public:
116 } 111 }
117 112
118 size_t GetSlabIndex() const { 113 size_t GetSlabIndex() const {
119 return s_slab_heap.GetObjectIndex(static_cast<const Derived*>(this)); 114 return SlabHeap<Derived>(kernel).GetObjectIndex(static_cast<const Derived*>(this));
120 } 115 }
121 116
122public: 117public:
123 static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) { 118 static void InitializeSlabHeap(KernelCore& kernel, void* memory, size_t memory_size) {
124 s_slab_heap.Initialize(memory, memory_size); 119 kernel.SlabHeap<Derived>().Initialize(memory, memory_size);
125 kernel.ObjectListContainer().Initialize(); 120 kernel.ObjectListContainer().Initialize();
126 } 121 }
127 122
@@ -145,22 +140,28 @@ public:
145 return kernel.ObjectListContainer().Register(obj); 140 return kernel.ObjectListContainer().Register(obj);
146 } 141 }
147 142
148 static size_t GetObjectSize() { 143 static size_t GetObjectSize(KernelCore& kernel) {
149 return s_slab_heap.GetObjectSize(); 144 return kernel.SlabHeap<Derived>().GetObjectSize();
150 } 145 }
151 static size_t GetSlabHeapSize() { 146
152 return s_slab_heap.GetSlabHeapSize(); 147 static size_t GetSlabHeapSize(KernelCore& kernel) {
148 return kernel.SlabHeap<Derived>().GetSlabHeapSize();
153 } 149 }
154 static size_t GetPeakIndex() { 150
155 return s_slab_heap.GetPeakIndex(); 151 static size_t GetPeakIndex(KernelCore& kernel) {
152 return kernel.SlabHeap<Derived>().GetPeakIndex();
156 } 153 }
157 static uintptr_t GetSlabHeapAddress() { 154
158 return s_slab_heap.GetSlabHeapAddress(); 155 static uintptr_t GetSlabHeapAddress(KernelCore& kernel) {
156 return kernel.SlabHeap<Derived>().GetSlabHeapAddress();
159 } 157 }
160 158
161 static size_t GetNumRemaining() { 159 static size_t GetNumRemaining(KernelCore& kernel) {
162 return s_slab_heap.GetNumRemaining(); 160 return kernel.SlabHeap<Derived>().GetNumRemaining();
163 } 161 }
162
163protected:
164 KernelCore& kernel;
164}; 165};
165 166
166} // namespace Kernel 167} // namespace Kernel