diff options
| author | 2022-06-29 20:33:04 -0400 | |
|---|---|---|
| committer | 2022-10-06 21:00:54 +0200 | |
| commit | fa342cae227666c861806b9bf63e4286aff1e4d7 (patch) | |
| tree | db567b3031a00dda907fccb5fd3d46744a4bb9b8 /src/common/address_space.h | |
| parent | general: Format licenses as per SPDX guidelines (diff) | |
| download | yuzu-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.h | 105 |
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> |
| 24 | requires AddressSpaceValid<VaType, AddressSpaceBits> | 24 | requires AddressSpaceValid<VaType, AddressSpaceBits> |
| 25 | class FlatAddressSpaceMap { | 25 | class FlatAddressSpaceMap { |
| 26 | private: | 26 | public: |
| 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 | ||
| 30 | protected: | 50 | protected: |
| 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 | ||
| 78 | public: | 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) { | 102 | private: |
| 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 | |||
| 108 | private: | 115 | private: |
| 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 | |||
| 115 | public: | 118 | public: |
| 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 | |||
| 140 | private: | ||
| 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 |