summaryrefslogtreecommitdiff
path: root/src/common/address_space.h
diff options
context:
space:
mode:
authorGravatar Morph2022-06-29 20:33:04 -0400
committerGravatar Fernando Sahmkow2022-10-06 21:00:54 +0200
commitfa342cae227666c861806b9bf63e4286aff1e4d7 (patch)
treedb567b3031a00dda907fccb5fd3d46744a4bb9b8 /src/common/address_space.h
parentgeneral: Format licenses as per SPDX guidelines (diff)
downloadyuzu-fa342cae227666c861806b9bf63e4286aff1e4d7.tar.gz
yuzu-fa342cae227666c861806b9bf63e4286aff1e4d7.tar.xz
yuzu-fa342cae227666c861806b9bf63e4286aff1e4d7.zip
address_space: Address feedback
Diffstat (limited to 'src/common/address_space.h')
-rw-r--r--src/common/address_space.h105
1 files changed, 60 insertions, 45 deletions
diff --git a/src/common/address_space.h b/src/common/address_space.h
index 5b3832f07..bf649018c 100644
--- a/src/common/address_space.h
+++ b/src/common/address_space.h
@@ -23,9 +23,29 @@ template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa
23 bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct> 23 bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct>
24requires AddressSpaceValid<VaType, AddressSpaceBits> 24requires AddressSpaceValid<VaType, AddressSpaceBits>
25class FlatAddressSpaceMap { 25class FlatAddressSpaceMap {
26private: 26public:
27 std::function<void(VaType, VaType)> 27 /// The maximum VA that this AS can technically reach
28 unmapCallback{}; //!< Callback called when the mappings in an region have changed 28 static constexpr VaType VaMaximum{(1ULL << (AddressSpaceBits - 1)) +
29 ((1ULL << (AddressSpaceBits - 1)) - 1)};
30
31 explicit FlatAddressSpaceMap(VaType va_limit,
32 std::function<void(VaType, VaType)> unmap_callback = {});
33
34 FlatAddressSpaceMap() = default;
35
36 void Map(VaType virt, PaType phys, VaType size, ExtraBlockInfo extra_info = {}) {
37 std::scoped_lock lock(block_mutex);
38 MapLocked(virt, phys, size, extra_info);
39 }
40
41 void Unmap(VaType virt, VaType size) {
42 std::scoped_lock lock(block_mutex);
43 UnmapLocked(virt, size);
44 }
45
46 VaType GetVALimit() const {
47 return va_limit;
48 }
29 49
30protected: 50protected:
31 /** 51 /**
@@ -33,68 +53,55 @@ protected:
33 * another block with a different phys address is hit 53 * another block with a different phys address is hit
34 */ 54 */
35 struct Block { 55 struct Block {
36 VaType virt{UnmappedVa}; //!< VA of the block 56 /// VA of the block
37 PaType phys{UnmappedPa}; //!< PA of the block, will increase 1-1 with VA until a new block 57 VaType virt{UnmappedVa};
38 //!< is encountered 58 /// PA of the block, will increase 1-1 with VA until a new block is encountered
39 [[no_unique_address]] ExtraBlockInfo extraInfo; 59 PaType phys{UnmappedPa};
60 [[no_unique_address]] ExtraBlockInfo extra_info;
40 61
41 Block() = default; 62 Block() = default;
42 63
43 Block(VaType virt_, PaType phys_, ExtraBlockInfo extraInfo_) 64 Block(VaType virt_, PaType phys_, ExtraBlockInfo extra_info_)
44 : virt(virt_), phys(phys_), extraInfo(extraInfo_) {} 65 : virt(virt_), phys(phys_), extra_info(extra_info_) {}
45 66
46 constexpr bool Valid() { 67 bool Valid() const {
47 return virt != UnmappedVa; 68 return virt != UnmappedVa;
48 } 69 }
49 70
50 constexpr bool Mapped() { 71 bool Mapped() const {
51 return phys != UnmappedPa; 72 return phys != UnmappedPa;
52 } 73 }
53 74
54 constexpr bool Unmapped() { 75 bool Unmapped() const {
55 return phys == UnmappedPa; 76 return phys == UnmappedPa;
56 } 77 }
57 78
58 bool operator<(const VaType& pVirt) const { 79 bool operator<(const VaType& p_virt) const {
59 return virt < pVirt; 80 return virt < p_virt;
60 } 81 }
61 }; 82 };
62 83
63 std::mutex blockMutex;
64 std::vector<Block> blocks{Block{}};
65
66 /** 84 /**
67 * @brief Maps a PA range into the given AS region 85 * @brief Maps a PA range into the given AS region
68 * @note blockMutex MUST be locked when calling this 86 * @note block_mutex MUST be locked when calling this
69 */ 87 */
70 void MapLocked(VaType virt, PaType phys, VaType size, ExtraBlockInfo extraInfo); 88 void MapLocked(VaType virt, PaType phys, VaType size, ExtraBlockInfo extra_info);
71 89
72 /** 90 /**
73 * @brief Unmaps the given range and merges it with other unmapped regions 91 * @brief Unmaps the given range and merges it with other unmapped regions
74 * @note blockMutex MUST be locked when calling this 92 * @note block_mutex MUST be locked when calling this
75 */ 93 */
76 void UnmapLocked(VaType virt, VaType size); 94 void UnmapLocked(VaType virt, VaType size);
77 95
78public: 96 std::mutex block_mutex;
79 static constexpr VaType VaMaximum{(1ULL << (AddressSpaceBits - 1)) + 97 std::vector<Block> blocks{Block{}};
80 ((1ULL << (AddressSpaceBits - 1)) -
81 1)}; //!< The maximum VA that this AS can technically reach
82
83 VaType vaLimit{VaMaximum}; //!< A soft limit on the maximum VA of the AS
84
85 FlatAddressSpaceMap(VaType vaLimit, std::function<void(VaType, VaType)> unmapCallback = {});
86
87 FlatAddressSpaceMap() = default;
88 98
89 void Map(VaType virt, PaType phys, VaType size, ExtraBlockInfo extraInfo = {}) { 99 /// a soft limit on the maximum VA of the AS
90 std::scoped_lock lock(blockMutex); 100 VaType va_limit{VaMaximum};
91 MapLocked(virt, phys, size, extraInfo);
92 }
93 101
94 void Unmap(VaType virt, VaType size) { 102private:
95 std::scoped_lock lock(blockMutex); 103 /// Callback called when the mappings in an region have changed
96 UnmapLocked(virt, size); 104 std::function<void(VaType, VaType)> unmap_callback{};
97 }
98}; 105};
99 106
100/** 107/**
@@ -108,14 +115,8 @@ class FlatAllocator
108private: 115private:
109 using Base = FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits>; 116 using Base = FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits>;
110 117
111 VaType currentLinearAllocEnd; //!< The end address for the initial linear allocation pass, once
112 //!< this reaches the AS limit the slower allocation path will be
113 //!< used
114
115public: 118public:
116 VaType vaStart; //!< The base VA of the allocator, no allocations will be below this 119 explicit FlatAllocator(VaType va_start, VaType va_limit = Base::VaMaximum);
117
118 FlatAllocator(VaType vaStart, VaType vaLimit = Base::VaMaximum);
119 120
120 /** 121 /**
121 * @brief Allocates a region in the AS of the given size and returns its address 122 * @brief Allocates a region in the AS of the given size and returns its address
@@ -131,5 +132,19 @@ public:
131 * @brief Frees an AS region so it can be used again 132 * @brief Frees an AS region so it can be used again
132 */ 133 */
133 void Free(VaType virt, VaType size); 134 void Free(VaType virt, VaType size);
135
136 VaType GetVAStart() const {
137 return va_start;
138 }
139
140private:
141 /// The base VA of the allocator, no allocations will be below this
142 VaType va_start;
143
144 /**
145 * The end address for the initial linear allocation pass
146 * Once this reaches the AS limit the slower allocation path will be used
147 */
148 VaType current_linear_alloc_end;
134}; 149};
135} // namespace Common 150} // namespace Common