Browse Source

DeviceMemory: Make counter types configurable

nce_cpp
Fernando Sahmkow 2 years ago
parent
commit
0ed58aa5ac
  1. 15
      src/core/device_memory_manager.h
  2. 18
      src/core/device_memory_manager.inc

15
src/core/device_memory_manager.h

@ -5,6 +5,7 @@
#include <array> #include <array>
#include <atomic> #include <atomic>
#include <bit>
#include <deque> #include <deque>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
@ -181,24 +182,28 @@ private:
} }
Common::VirtualBuffer<VAddr> cpu_backing_address; Common::VirtualBuffer<VAddr> cpu_backing_address;
static constexpr size_t subentries = 8 / sizeof(u8);
using CounterType = u8;
using CounterAtomicType = std::atomic_uint8_t;
static constexpr size_t subentries = 8 / sizeof(CounterType);
static constexpr size_t subentries_mask = subentries - 1; static constexpr size_t subentries_mask = subentries - 1;
static constexpr size_t subentries_shift =
std::countr_zero(sizeof(u64)) - std::countr_zero(sizeof(CounterType));
class CounterEntry final { class CounterEntry final {
public: public:
CounterEntry() = default; CounterEntry() = default;
std::atomic_uint8_t& Count(std::size_t page) {
CounterAtomicType& Count(std::size_t page) {
return values[page & subentries_mask]; return values[page & subentries_mask];
} }
const std::atomic_uint8_t& Count(std::size_t page) const {
const CounterAtomicType& Count(std::size_t page) const {
return values[page & subentries_mask]; return values[page & subentries_mask];
} }
private: private:
std::array<std::atomic_uint8_t, subentries> values{};
std::array<CounterAtomicType, subentries> values{};
}; };
static_assert(sizeof(CounterEntry) == subentries * sizeof(u8),
static_assert(sizeof(CounterEntry) == subentries * sizeof(CounterType),
"CounterEntry should be 8 bytes!"); "CounterEntry should be 8 bytes!");
static constexpr size_t num_counter_entries = static constexpr size_t num_counter_entries =

18
src/core/device_memory_manager.inc

@ -213,8 +213,8 @@ void DeviceMemoryManager<Traits>::Free(DAddr start, size_t size) {
} }
template <typename Traits> template <typename Traits>
void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size,
Asid asid, bool track) {
void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size_t size, Asid asid,
bool track) {
Core::Memory::Memory* process_memory = registered_processes[asid.id]; Core::Memory::Memory* process_memory = registered_processes[asid.id];
size_t start_page_d = address >> Memory::YUZU_PAGEBITS; size_t start_page_d = address >> Memory::YUZU_PAGEBITS;
size_t num_pages = Common::AlignUp(size, Memory::YUZU_PAGESIZE) >> Memory::YUZU_PAGEBITS; 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
size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS; size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS;
auto* memory_device_inter = registered_processes[asid.id]; auto* memory_device_inter = registered_processes[asid.id];
for (; page != page_end; ++page) { for (; page != page_end; ++page) {
std::atomic_uint8_t& count = cached_pages->at(page >> 3).Count(page);
CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page);
if (delta > 0) { if (delta > 0) {
ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<u8>::max(),
ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(),
"Count may overflow!"); "Count may overflow!");
} else if (delta < 0) { } else if (delta < 0) {
ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); 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
} }
// Adds or subtracts 1, as count is a unsigned 8-bit value // Adds or subtracts 1, as count is a unsigned 8-bit value
count.fetch_add(static_cast<u8>(delta), std::memory_order_release);
count.fetch_add(static_cast<CounterType>(delta), std::memory_order_release);
// Assume delta is either -1 or 1 // Assume delta is either -1 or 1
if (count.load(std::memory_order::relaxed) == 0) { if (count.load(std::memory_order::relaxed) == 0) {
@ -553,15 +553,15 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size
} }
cache_bytes += Memory::YUZU_PAGESIZE; cache_bytes += Memory::YUZU_PAGESIZE;
} else if (cache_bytes > 0) { } else if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,
true);
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS,
cache_bytes, true);
cache_bytes = 0; cache_bytes = 0;
} }
vpage++; vpage++;
} }
if (uncache_bytes > 0) { if (uncache_bytes > 0) {
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, uncache_bytes,
false);
MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS,
uncache_bytes, false);
} }
if (cache_bytes > 0) { if (cache_bytes > 0) {
MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes,

Loading…
Cancel
Save