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

This commit is contained in:
bunnei 2021-03-21 14:36:26 -07:00
parent 343eaecd38
commit 1996cae9cb
3 changed files with 47 additions and 35 deletions

View File

@ -2,6 +2,8 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <array>
#include "common/alignment.h" #include "common/alignment.h"
#include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/k_system_control.h"
@ -10,42 +12,18 @@ namespace Kernel {
namespace { 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> template <typename... Args>
KMemoryRegion* AllocateRegion(Args&&... args) { KMemoryRegion* AllocateRegion(KMemoryRegionAllocator& memory_region_allocator, Args&&... args) {
return g_memory_region_allocator.Allocate(std::forward<Args>(args)...); return memory_region_allocator.Allocate(std::forward<Args>(args)...);
} }
} // namespace } // 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) { 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) { 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()) const u64 new_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (address - old_address) ? old_pair + (address - old_address)
: old_pair; : 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. // 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()) const u64 after_pair = (old_pair != std::numeric_limits<u64>::max())
? old_pair + (inserted_region_end - old_address) ? old_pair + (inserted_region_end - old_address)
: old_pair; : old_pair;
this->insert( this->insert(*AllocateRegion(memory_region_allocator, inserted_region_end, old_last,
*AllocateRegion(inserted_region_end, old_last, after_pair, old_attr, old_type)); after_pair, old_attr, old_type));
} }
return true; 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, void KMemoryLayout::InitializeLinearMemoryRegionTrees(PAddr aligned_linear_phys_start,
VAddr linear_virtual_start) { VAddr linear_virtual_start) {
// Set static differences. // Set static differences.

View File

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

View File

@ -11,6 +11,8 @@
namespace Kernel { namespace Kernel {
class KMemoryRegionAllocator;
class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>, class KMemoryRegion final : public Common::IntrusiveRedBlackTreeBaseNode<KMemoryRegion>,
NonCopyable { NonCopyable {
friend class KMemoryRegionTree; friend class KMemoryRegionTree;
@ -155,9 +157,10 @@ public:
private: private:
TreeType m_tree{}; TreeType m_tree{};
KMemoryRegionAllocator& memory_region_allocator;
public: public:
constexpr KMemoryRegionTree() = default; KMemoryRegionTree(KMemoryRegionAllocator& memory_region_allocator_);
public: public:
KMemoryRegion* FindModifiable(u64 address) { 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 } // namespace Kernel