diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/device_memory_manager.inc | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/src/core/device_memory_manager.inc b/src/core/device_memory_manager.inc index 7afe54949..b026f4220 100644 --- a/src/core/device_memory_manager.inc +++ b/src/core/device_memory_manager.inc | |||
| @@ -519,18 +519,32 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
| 519 | const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE); | 519 | const size_t page_end = Common::DivCeil(addr + size, Memory::YUZU_PAGESIZE); |
| 520 | size_t page = addr >> Memory::YUZU_PAGEBITS; | 520 | size_t page = addr >> Memory::YUZU_PAGEBITS; |
| 521 | auto [asid, base_vaddress] = ExtractCPUBacking(page); | 521 | auto [asid, base_vaddress] = ExtractCPUBacking(page); |
| 522 | size_t vpage = base_vaddress >> Memory::YUZU_PAGEBITS; | ||
| 523 | auto* memory_device_inter = registered_processes[asid.id]; | 522 | auto* memory_device_inter = registered_processes[asid.id]; |
| 523 | const auto release_pending = [&] { | ||
| 524 | if (uncache_bytes > 0) { | ||
| 525 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, | ||
| 526 | uncache_bytes, false); | ||
| 527 | uncache_bytes = 0; | ||
| 528 | } | ||
| 529 | if (cache_bytes > 0) { | ||
| 530 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, | ||
| 531 | cache_bytes, true); | ||
| 532 | cache_bytes = 0; | ||
| 533 | } | ||
| 534 | }; | ||
| 524 | for (; page != page_end; ++page) { | 535 | for (; page != page_end; ++page) { |
| 525 | CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page); | 536 | CounterAtomicType& count = cached_pages->at(page >> subentries_shift).Count(page); |
| 537 | auto [asid_2, vpage] = ExtractCPUBacking(page); | ||
| 538 | vpage >>= Memory::YUZU_PAGEBITS; | ||
| 526 | 539 | ||
| 527 | if (delta > 0) { | 540 | if (vpage == 0) [[unlikely]] { |
| 528 | ASSERT_MSG(count.load(std::memory_order::relaxed) < std::numeric_limits<CounterType>::max(), | 541 | release_pending(); |
| 529 | "Count may overflow!"); | 542 | continue; |
| 530 | } else if (delta < 0) { | 543 | } |
| 531 | ASSERT_MSG(count.load(std::memory_order::relaxed) > 0, "Count may underflow!"); | 544 | |
| 532 | } else { | 545 | if (asid.id != asid_2.id) [[unlikely]] { |
| 533 | ASSERT_MSG(false, "Delta must be non-zero!"); | 546 | release_pending(); |
| 547 | memory_device_inter = registered_processes[asid_2.id]; | ||
| 534 | } | 548 | } |
| 535 | 549 | ||
| 536 | // Adds or subtracts 1, as count is a unsigned 8-bit value | 550 | // Adds or subtracts 1, as count is a unsigned 8-bit value |
| @@ -557,16 +571,8 @@ void DeviceMemoryManager<Traits>::UpdatePagesCachedCount(DAddr addr, size_t size | |||
| 557 | cache_bytes, true); | 571 | cache_bytes, true); |
| 558 | cache_bytes = 0; | 572 | cache_bytes = 0; |
| 559 | } | 573 | } |
| 560 | vpage++; | ||
| 561 | } | ||
| 562 | if (uncache_bytes > 0) { | ||
| 563 | MarkRegionCaching(memory_device_inter, uncache_begin << Memory::YUZU_PAGEBITS, | ||
| 564 | uncache_bytes, false); | ||
| 565 | } | ||
| 566 | if (cache_bytes > 0) { | ||
| 567 | MarkRegionCaching(memory_device_inter, cache_begin << Memory::YUZU_PAGEBITS, cache_bytes, | ||
| 568 | true); | ||
| 569 | } | 574 | } |
| 575 | release_pending(); | ||
| 570 | } | 576 | } |
| 571 | 577 | ||
| 572 | } // namespace Core | 578 | } // namespace Core |