summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Fernando Sahmkow2024-01-30 20:14:06 +0100
committerGravatar Fernando Sahmkow2024-01-31 16:38:51 +0100
commit738e9a79a06c9d3955488022a1d3afd67bc5a11d (patch)
treef9d574ddd4e886e1e7938db8d5f6e68bed5eb240 /src
parentNVDRV: Join the heaper optimization blocks (diff)
downloadyuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.tar.gz
yuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.tar.xz
yuzu-738e9a79a06c9d3955488022a1d3afd67bc5a11d.zip
DeviceMemory: Make counter types configurable
Diffstat (limited to 'src')
-rw-r--r--src/core/device_memory_manager.h15
-rw-r--r--src/core/device_memory_manager.inc18
2 files changed, 19 insertions, 14 deletions
diff --git a/src/core/device_memory_manager.h b/src/core/device_memory_manager.h
index 63823602c..0568a821b 100644
--- a/src/core/device_memory_manager.h
+++ b/src/core/device_memory_manager.h
@@ -5,6 +5,7 @@
5 5
6#include <array> 6#include <array>
7#include <atomic> 7#include <atomic>
8#include <bit>
8#include <deque> 9#include <deque>
9#include <memory> 10#include <memory>
10#include <mutex> 11#include <mutex>
@@ -181,24 +182,28 @@ private:
181 } 182 }
182 183
183 Common::VirtualBuffer<VAddr> cpu_backing_address; 184 Common::VirtualBuffer<VAddr> cpu_backing_address;
184 static constexpr size_t subentries = 8 / sizeof(u8); 185 using CounterType = u8;
186 using CounterAtomicType = std::atomic_uint8_t;
187 static constexpr size_t subentries = 8 / sizeof(CounterType);
185 static constexpr size_t subentries_mask = subentries - 1; 188 static constexpr size_t subentries_mask = subentries - 1;
189 static constexpr size_t subentries_shift =
190 std::countr_zero(sizeof(u64)) - std::countr_zero(sizeof(CounterType));
186 class CounterEntry final { 191 class CounterEntry final {
187 public: 192 public:
188 CounterEntry() = default; 193 CounterEntry() = default;
189 194
190 std::atomic_uint8_t& Count(std::size_t page) { 195 CounterAtomicType& Count(std::size_t page) {
191 return values[page & subentries_mask]; 196 return values[page & subentries_mask];
192 } 197 }
193 198
194 const std::atomic_uint8_t& Count(std::size_t page) const { 199 const CounterAtomicType& Count(std::size_t page) const {
195 return values[page & subentries_mask]; 200 return values[page & subentries_mask];
196 } 201 }
197 202
198 private: 203 private:
199 std::array<std::atomic_uint8_t, subentries> values{}; 204 std::array<CounterAtomicType, subentries> values{};
200 }; 205 };
201 static_assert(sizeof(CounterEntry) == subentries * sizeof(u8), 206 static_assert(sizeof(CounterEntry) == subentries * sizeof(CounterType),
202 "CounterEntry should be 8 bytes!"); 207 "CounterEntry should be 8 bytes!");
203 208
204 static constexpr size_t num_counter_entries = 209 static constexpr size_t num_counter_entries =
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc
index 0a59000aa..7afe54949 100644
--- a/src/core/device_memory_manager.inc
+++ b/src/core/device_memory_manager.inc
@@ -213,8 +213,8 @@ void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) {
213} 213}
214 214
215template <typename Traits> 215template <typename Traits>
216void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, 216void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, Asid asid,
217 Asid asid, bool track) { 217 bool track) {
218 Core::Memory::Memory* process_memory = registered_processes[asid.id]; 218 Core::Memory::Memory* process_memory = registered_processes[asid.id];
219 size_t start_page_d = address >> Memory::YUZU_PAGEBITS; 219 size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
220 size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS; 220 size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS;
@@ -522,10 +522,10 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
522 size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS; 522 size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
523 auto* memory_device_inter = registered_processes[asid.id]; 523 auto* memory_device_inter = registered_processes[asid.id];
524 for (; page != page_end; ++page) { 524 for (; page != page_end; ++page) {
525 std::atomic_uint8_t& count = cached_pages->at(page >> 3).Count(page); 525 CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page);
526 526
527 if (delta > 0) { 527 if (delta > 0) {
528 ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<u8>::max(), 528 ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(),
529 "Count may overflow!"); 529 "Count may overflow!");
530 } else if (delta < 0) { 530 } else if (delta < 0) {
531 ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); 531 ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!");
@@ -534,7 +534,7 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
534 } 534 }
535 535
536 // Adds or subtracts 1, as count is a unsigned 8-bit value 536 // Adds or subtracts 1, as count is a unsigned 8-bit value
537 count.fetch_add(static_cast<u8>(delta), std::memory_order_release); 537 count.fetch_add(static_cast<CounterType>(delta), std::memory_order_release);
538 538
539 // Assume delta is either -1 or 1 539 // Assume delta is either -1 or 1
540 if (count.load(std::memory_order::relaxed) == 0) { 540 if (count.load(std::memory_order::relaxed) == 0) {
@@ -553,15 +553,15 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
553 } 553 }
554 cache_bytes += Memory::YUZU_PAGESIZE; 554 cache_bytes += Memory::YUZU_PAGESIZE;
555 } else if (cache_bytes > 0) { 555 } else if (cache_bytes > 0) {
556 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, 556 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
557 true); 557 cache_bytes, true);
558 cache_bytes = 0; 558 cache_bytes = 0;
559 } 559 }
560 vpage++; 560 vpage++;
561 } 561 }
562 if (uncache_bytes > 0) { 562 if (uncache_bytes > 0) {
563 MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes, 563 MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
564 false); 564 uncache_bytes, false);
565 } 565 }
566 if (cache_bytes > 0) { 566 if (cache_bytes > 0) {
567 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, 567 MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,