forked from suyu/suyu
hle: kernel: k_memory_layout: Move KMemoryRegionAllocator out of global.
This commit is contained in:
parent
343eaecd38
commit
1996cae9cb
3 changed files with 47 additions and 35 deletions
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue