summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2021-05-21 03:15:59 +0200
committerbunnei <bunneidev@gmail.com>2021-05-21 06:41:52 +0200
commitb4fc2e52a2d51f8958b77fbe4fb76c854cd4593b (patch)
tree64efafb1dfba8ba239d84d35fd78a584a6f4cb3a
parentRevert "WORKAROUND: Do not use slab heap while we track down issues with resource management." (diff)
downloadyuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar.gz
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar.bz2
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar.lz
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar.xz
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.tar.zst
yuzu-b4fc2e52a2d51f8958b77fbe4fb76c854cd4593b.zip
-rw-r--r--src/core/hle/kernel/init/init_slab_setup.cpp10
-rw-r--r--src/core/hle/kernel/k_slab_heap.h154
-rw-r--r--src/core/memory.cpp21
-rw-r--r--src/core/memory.h9
4 files changed, 20 insertions, 174 deletions
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp
index 69ae405e6..10edede17 100644
--- a/src/core/hle/kernel/init/init_slab_setup.cpp
+++ b/src/core/hle/kernel/init/init_slab_setup.cpp
@@ -70,14 +70,22 @@ constexpr size_t SlabCountExtraKThread = 160;
template <typename T>
VAddr InitializeSlabHeap(Core::System& system, KMemoryLayout& memory_layout, VAddr address,
size_t num_objects) {
+ // TODO(bunnei): This is just a place holder. We should initialize the appropriate KSlabHeap for
+ // kernel object type T with the backing kernel memory pointer once we emulate kernel memory.
+
const size_t size = Common::AlignUp(sizeof(T) * num_objects, alignof(void*));
VAddr start = Common::AlignUp(address, alignof(T));
+ // This is intentionally empty. Once KSlabHeap is fully implemented, we can replace this with
+ // the pointer to emulated memory to pass along. Until then, KSlabHeap will just allocate/free
+ // host memory.
+ void* backing_kernel_memory{};
+
if (size > 0) {
const KMemoryRegion* region = memory_layout.FindVirtual(start + size - 1);
ASSERT(region != nullptr);
ASSERT(region->IsDerivedFrom(KMemoryRegionType_KernelSlab));
- T::InitializeSlabHeap(system.Kernel(), system.Memory().GetKernelBuffer(start, size), size);
+ T::InitializeSlabHeap(system.Kernel(), backing_kernel_memory, size);
}
return start + size;
diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h
index 5ce9a1d7c..81d472a3e 100644
--- a/src/core/hle/kernel/k_slab_heap.h
+++ b/src/core/hle/kernel/k_slab_heap.h
@@ -4,165 +4,33 @@
#pragma once
-#include <atomic>
-
-#include "common/assert.h"
-#include "common/common_types.h"
-
namespace Kernel {
-namespace impl {
-
-class KSlabHeapImpl final : NonCopyable {
-public:
- struct Node {
- Node* next{};
- };
-
- constexpr KSlabHeapImpl() = default;
-
- void Initialize(std::size_t size) {
- ASSERT(head == nullptr);
- obj_size = size;
- }
-
- constexpr std::size_t GetObjectSize() const {
- return obj_size;
- }
-
- Node* GetHead() const {
- return head;
- }
-
- void* Allocate() {
- Node* ret = head.load();
-
- do {
- if (ret == nullptr) {
- break;
- }
- } while (!head.compare_exchange_weak(ret, ret->next));
-
- return ret;
- }
-
- void Free(void* obj) {
- Node* node = static_cast<Node*>(obj);
-
- Node* cur_head = head.load();
- do {
- node->next = cur_head;
- } while (!head.compare_exchange_weak(cur_head, node));
- }
-
-private:
- std::atomic<Node*> head{};
- std::size_t obj_size{};
-};
-
-} // namespace impl
-
-class KSlabHeapBase : NonCopyable {
-public:
- constexpr KSlabHeapBase() = default;
-
- constexpr bool Contains(uintptr_t addr) const {
- return start <= addr && addr < end;
- }
-
- constexpr std::size_t GetSlabHeapSize() const {
- return (end - start) / GetObjectSize();
- }
-
- constexpr std::size_t GetObjectSize() const {
- return impl.GetObjectSize();
- }
+class KernelCore;
- constexpr uintptr_t GetSlabHeapAddress() const {
- return start;
- }
-
- std::size_t GetObjectIndexImpl(const void* obj) const {
- return (reinterpret_cast<uintptr_t>(obj) - start) / GetObjectSize();
- }
-
- std::size_t GetPeakIndex() const {
- return GetObjectIndexImpl(reinterpret_cast<const void*>(peak));
- }
-
- void* AllocateImpl() {
- return impl.Allocate();
- }
-
- void FreeImpl(void* obj) {
- // Don't allow freeing an object that wasn't allocated from this heap
- ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
-
- impl.Free(obj);
- }
-
- void InitializeImpl(std::size_t obj_size, void* memory, std::size_t memory_size) {
- // Ensure we don't initialize a slab using null memory
- ASSERT(memory != nullptr);
-
- // Initialize the base allocator
- impl.Initialize(obj_size);
-
- // Set our tracking variables
- const std::size_t num_obj = (memory_size / obj_size);
- start = reinterpret_cast<uintptr_t>(memory);
- end = start + num_obj * obj_size;
- peak = start;
-
- // Free the objects
- u8* cur = reinterpret_cast<u8*>(end);
-
- for (std::size_t i{}; i < num_obj; i++) {
- cur -= obj_size;
- impl.Free(cur);
- }
- }
-
-private:
- using Impl = impl::KSlabHeapImpl;
-
- Impl impl;
- uintptr_t peak{};
- uintptr_t start{};
- uintptr_t end{};
-};
+/// This is a placeholder class to manage slab heaps for kernel objects. For now, we just allocate
+/// these with new/delete, but this can be re-implemented later to allocate these in emulated
+/// memory.
template <typename T>
-class KSlabHeap final : public KSlabHeapBase {
+class KSlabHeap final : NonCopyable {
public:
- constexpr KSlabHeap() : KSlabHeapBase() {}
+ KSlabHeap() = default;
- void Initialize(void* memory, std::size_t memory_size) {
- InitializeImpl(sizeof(T), memory, memory_size);
+ void Initialize([[maybe_unused]] void* memory, [[maybe_unused]] std::size_t memory_size) {
+ // Placeholder that should initialize the backing slab heap implementation.
}
T* Allocate() {
- T* obj = static_cast<T*>(AllocateImpl());
- if (obj != nullptr) {
- new (obj) T();
- }
- return obj;
+ return new T();
}
T* AllocateWithKernel(KernelCore& kernel) {
- T* obj = static_cast<T*>(AllocateImpl());
- if (obj != nullptr) {
- new (obj) T(kernel);
- }
- return obj;
+ return new T(kernel);
}
void Free(T* obj) {
- FreeImpl(obj);
- }
-
- constexpr std::size_t GetObjectIndex(const T* obj) const {
- return GetObjectIndexImpl(obj);
+ delete obj;
}
};
diff --git a/src/core/memory.cpp b/src/core/memory.cpp
index b4c56e1c1..bf2ef7816 100644
--- a/src/core/memory.cpp
+++ b/src/core/memory.cpp
@@ -82,22 +82,6 @@ struct Memory::Impl {
return nullptr;
}
- u8* GetKernelBuffer(VAddr start_vaddr, size_t size) {
- // TODO(bunnei): This is just a workaround until we have kernel memory layout mapped &
- // managed. Until then, we use this to allocate and access kernel memory regions.
-
- auto search = kernel_memory_regions.find(start_vaddr);
- if (search != kernel_memory_regions.end()) {
- return search->second.get();
- }
-
- std::unique_ptr<u8[]> new_memory_region{new u8[size]};
- u8* raw_ptr = new_memory_region.get();
- kernel_memory_regions[start_vaddr] = std::move(new_memory_region);
-
- return raw_ptr;
- }
-
u8 Read8(const VAddr addr) {
return Read<u8>(addr);
}
@@ -727,7 +711,6 @@ struct Memory::Impl {
}
Common::PageTable* current_page_table = nullptr;
- std::unordered_map<VAddr, std::unique_ptr<u8[]>> kernel_memory_regions;
Core::System& system;
};
@@ -765,10 +748,6 @@ u8* Memory::GetPointer(VAddr vaddr) {
return impl->GetPointer(vaddr);
}
-u8* Memory::GetKernelBuffer(VAddr start_vaddr, size_t size) {
- return impl->GetKernelBuffer(start_vaddr, size);
-}
-
const u8* Memory::GetPointer(VAddr vaddr) const {
return impl->GetPointer(vaddr);
}
diff --git a/src/core/memory.h b/src/core/memory.h
index 345fd870d..c91eeced9 100644
--- a/src/core/memory.h
+++ b/src/core/memory.h
@@ -121,15 +121,6 @@ public:
*/
u8* GetPointer(VAddr vaddr);
- /**
- * Gets a pointer to the start of a kernel heap allocated memory region. Will allocate one if it
- * does not already exist.
- *
- * @param start_vaddr Start virtual address for the memory region.
- * @param size Size of the memory region.
- */
- u8* GetKernelBuffer(VAddr start_vaddr, size_t size);
-
template <typename T>
T* GetPointer(VAddr vaddr) {
return reinterpret_cast<T*>(GetPointer(vaddr));