Просмотр исходного кода

hle: kernel: k_memory_layout: Move KMemoryRegionAllocator out of global.

bunnei 5 лет назад
Родитель
Сommit
1996cae9cb

+ 16 - 33
src/core/hle/kernel/k_memory_layout.cpp

@@ -2,6 +2,8 @@
 // Licensed under GPLv2 or any later version
 // Refer to the license.txt file included.
 
+#include <array>
+
 #include "common/alignment.h"
 #include "core/hle/kernel/k_memory_layout.h"
 #include "core/hle/kernel/k_system_control.h"
@@ -10,42 +12,18 @@ namespace Kernel {
 
 namespace {
 
-class KMemoryRegionAllocator final : NonCopyable {
-public:
-    static constexpr size_t MaxMemoryRegions = 200;
-
-private:
-    KMemoryRegion region_heap[MaxMemoryRegions]{};
-    size_t num_regions{};
-
-public:
-    constexpr KMemoryRegionAllocator() = default;
-
-public:
-    template <typename... Args>
-    KMemoryRegion* Allocate(Args&&... args) {
-        // Ensure we stay within the bounds of our heap.
-        ASSERT(this->num_regions < MaxMemoryRegions);
-
-        // Create the new region.
-        KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]);
-        new (region) KMemoryRegion(std::forward<Args>(args)...);
-
-        return region;
-    }
-};
-
-KMemoryRegionAllocator g_memory_region_allocator;
-
 template <typename... Args>
-KMemoryRegion* AllocateRegion(Args&&... args) {
-    return g_memory_region_allocator.Allocate(std::forward<Args>(args)...);
+KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) {
+    return memory_region_allocator.Allocate(std::forward<Args>(args)...);
 }
 
 } // namespace
 
+KMemoryRegionTree::KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_)
+    : memory_region_allocator{memory_region_allocator_} {}
+
 void KMemoryRegionTree::InsertDirectly(u64 address, u64 last_address, u32 attr, u32 type_id) {
-    this->insert(*AllocateRegion(address, last_address, attr, type_id));
+    this->insert(*AllocateRegion(memory_region_allocator, address, last_address, attr, type_id));
 }
 
 bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_attr, u32 old_attr) {
@@ -92,7 +70,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at
         const u64 new_pair = (old_pair != std::numeric_limits<u64>::max())
                                  ? old_pair + (address - old_address)
                                  : old_pair;
-        this->insert(*AllocateRegion(address, inserted_region_last, new_pair, new_attr, type_id));
+        this->insert(*AllocateRegion(memory_region_allocator, address, inserted_region_last,
+                                     new_pair, new_attr, type_id));
     }
 
     // If we need to insert a region after the region, do so.
@@ -100,8 +79,8 @@ bool KMemoryRegionTree::Insert(u64 address, size_t size, u32 type_id, u32 new_at
         const u64 after_pair = (old_pair != std::numeric_limits<u64>::max())
                                    ? old_pair + (inserted_region_end - old_address)
                                    : old_pair;
-        this->insert(
-            *AllocateRegion(inserted_region_end, old_last, after_pair, old_attr, old_type));
+        this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last,
+                                     after_pair, old_attr, old_type));
     }
 
     return true;
@@ -147,6 +126,10 @@ VAddr KMemoryRegionTree::GetRandomAlignedRegion(size_t size, size_t alignment, u
     }
 }
 
+KMemoryLayout::KMemoryLayout()
+    : virtual_tree{memory_region_allocator}, physical_tree{memory_region_allocator},
+      virtual_linear_tree{memory_region_allocator}, physical_linear_tree{memory_region_allocator} {}
+
 void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
                                                       VAddr linear_virtual_start) {
     // Set static differences.

+ 2 - 1
src/core/hle/kernel/k_memory_layout.h

@@ -73,7 +73,7 @@ constexpr bool IsKernelAddress(VAddr address) {
 
 class KMemoryLayout final {
 public:
-    KMemoryLayout() = default;
+    KMemoryLayout();
 
     KMemoryRegionTree& GetVirtualMemoryRegionTree() {
         return virtual_tree;
@@ -376,6 +376,7 @@ private:
 private:
     u64 linear_phys_to_virt_diff{};
     u64 linear_virt_to_phys_diff{};
+    KMemoryRegionAllocator memory_region_allocator;
     KMemoryRegionTree virtual_tree;
     KMemoryRegionTree physical_tree;
     KMemoryRegionTree virtual_linear_tree;

+ 29 - 1
src/core/hle/kernel/k_memory_region.h

@@ -11,6 +11,8 @@
 
 namespace Kernel {
 
+class KMemoryRegionAllocator;
+
 class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>,
                             NonCopyable {
     friend class KMemoryRegionTree;
@@ -155,9 +157,10 @@ public:
 
 private:
     TreeType m_tree{};
+    KMemoryRegionAllocator& memory_region_allocator;
 
 public:
-    constexpr KMemoryRegionTree() = default;
+    KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_);
 
 public:
     KMemoryRegion* FindModifiable(u64 address) {
@@ -321,4 +324,29 @@ public:
     }
 };
 
+class KMemoryRegionAllocator final : NonCopyable {
+public:
+    static constexpr size_t MaxMemoryRegions = 200;
+
+private:
+    std::array<KMemoryRegion, MaxMemoryRegions> region_heap{};
+    size_t num_regions{};
+
+public:
+    constexpr KMemoryRegionAllocator() = default;
+
+public:
+    template <typename... Args>
+    KMemoryRegion* Allocate(Args&&... args) {
+        // Ensure we stay within the bounds of our heap.
+        ASSERT(this->num_regions < MaxMemoryRegions);
+
+        // Create the new region.
+        KMemoryRegion* region = std::addressof(this->region_heap[this->num_regions++]);
+        new (region) KMemoryRegion(std::forward<Args>(args)...);
+
+        return region;
+    }
+};
+
 } // namespace Kernel