properly do tls + array pod (#3529)

Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3529
Co-authored-by: lizzie <lizzie@eden-emu.dev>
Co-committed-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie
2026-02-12 20:38:04 +01:00
committed by crueter
parent 6b7e54e115
commit c487a5cbc4
6 changed files with 43 additions and 369 deletions
+2 -5
View File
@@ -200,11 +200,8 @@ private:
}
Common::VirtualBuffer<VAddr> cpu_backing_address;
inline static thread_local TranslationEntry t_slot0{};
inline static thread_local TranslationEntry t_slot1{};
inline static thread_local TranslationEntry t_slot2{};
inline static thread_local TranslationEntry t_slot3{};
inline static thread_local u32 cache_cursor = 0;
std::array<TranslationEntry, 4> t_slot{};
u32 cache_cursor = 0;
using CounterType = u8;
using CounterAtomicType = std::atomic_uint8_t;
static constexpr size_t subentries = 8 / sizeof(CounterType);
+16 -70
View File
@@ -247,10 +247,7 @@ void DeviceMemoryManager<Traits>::Map(DAddr address, VAddr virtual_address, size
}
impl->multi_dev_address.Register(new_dev, start_id);
}
t_slot0 = {};
t_slot1 = {};
t_slot2 = {};
t_slot3 = {};
t_slot = {};
if (track) {
TrackContinuityImpl(address, virtual_address, size, asid);
}
@@ -282,10 +279,7 @@ void DeviceMemoryManager<Traits>::Unmap(DAddr address, size_t size) {
compressed_device_addr[phys_addr - 1] = new_start | MULTI_FLAG;
}
}
t_slot0 = {};
t_slot1 = {};
t_slot2 = {};
t_slot3 = {};
t_slot = {};
}
template <typename Traits>
void DeviceMemoryManager<Traits>::TrackContinuityImpl(DAddr address, VAddr virtual_address,
@@ -428,42 +422,18 @@ void DeviceMemoryManager<Traits>::ReadBlock(DAddr address, void* dest_pointer, s
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK;
if (size <= Memory::YUZU_PAGESIZE - page_offset) {
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK);
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size);
return;
}
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size);
return;
}
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size);
return;
}
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size);
return;
for (size_t i = 0; i < 4; ++i) {
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size);
return;
}
}
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS;
const auto phys_addr = compressed_physical_ptr[page_index];
if (phys_addr != 0) {
auto* const mem_ptr = GetPointerFromRaw<u8>(
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS));
switch (cache_cursor & 3U) {
case 0:
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 1:
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 2:
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
default:
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
}
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS));
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
cache_cursor = (cache_cursor + 1) & 3U;
std::memcpy(dest_pointer, mem_ptr + page_offset, size);
return;
@@ -510,42 +480,18 @@ void DeviceMemoryManager<Traits>::ReadBlockUnsafe(DAddr address, void* dest_poin
const std::size_t page_offset = address & Memory::YUZU_PAGEMASK;
if (size <= Memory::YUZU_PAGESIZE - page_offset) {
const DAddr guest_page = address & ~static_cast<DAddr>(Memory::YUZU_PAGEMASK);
if (t_slot0.guest_page == guest_page && t_slot0.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot0.host_ptr + page_offset, size);
return;
}
if (t_slot1.guest_page == guest_page && t_slot1.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot1.host_ptr + page_offset, size);
return;
}
if (t_slot2.guest_page == guest_page && t_slot2.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot2.host_ptr + page_offset, size);
return;
}
if (t_slot3.guest_page == guest_page && t_slot3.host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot3.host_ptr + page_offset, size);
return;
for (size_t i = 0; i < 4; ++i) {
if (t_slot[i].guest_page == guest_page && t_slot[i].host_ptr != nullptr) {
std::memcpy(dest_pointer, t_slot[i].host_ptr + page_offset, size);
return;
}
}
const std::size_t page_index = address >> Memory::YUZU_PAGEBITS;
const auto phys_addr = compressed_physical_ptr[page_index];
if (phys_addr != 0) {
auto* const mem_ptr = GetPointerFromRaw<u8>(
(static_cast<PAddr>(phys_addr - 1) << Memory::YUZU_PAGEBITS));
switch (cache_cursor & 3U) {
case 0:
t_slot0 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 1:
t_slot1 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
case 2:
t_slot2 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
default:
t_slot3 = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
break;
}
auto* const mem_ptr = GetPointerFromRaw<u8>((PAddr(phys_addr - 1) << Memory::YUZU_PAGEBITS));
t_slot[cache_cursor % t_slot.size()] = TranslationEntry{.guest_page = guest_page, .host_ptr = mem_ptr};
cache_cursor = (cache_cursor + 1) & 3U;
std::memcpy(dest_pointer, mem_ptr + page_offset, size);
return;