diff options
| -rw-r--r-- | src/core/hle/kernel/k_memory_layout.cpp | 49 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_layout.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_memory_region.h | 30 | 
3 files changed, 47 insertions, 35 deletions
diff --git a/src/core/hle/kernel/k_memory_layout.cpp b/src/core/hle/kernel/k_memory_layout.cpp index 58fe4a133..fb1e2435f 100644 --- a/src/core/hle/kernel/k_memory_layout.cpp +++ b/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. diff --git a/src/core/hle/kernel/k_memory_layout.h b/src/core/hle/kernel/k_memory_layout.h index f2b46c932..b3e057326 100644 --- a/src/core/hle/kernel/k_memory_layout.h +++ b/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; diff --git a/src/core/hle/kernel/k_memory_region.h b/src/core/hle/kernel/k_memory_region.h index 1d4fcde6f..374b24bd3 100644 --- a/src/core/hle/kernel/k_memory_region.h +++ b/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  | 
