diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/host_memory.cpp | 21 | ||||
| -rw-r--r-- | src/common/host_memory.h | 6 |
2 files changed, 27 insertions, 0 deletions
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 75a9da80e9..2c45dfd3a5 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -790,6 +790,27 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, MemoryPermission #endif } +void HostMemory::HintCold(size_t physical_offset, size_t length, + std::optional<size_t> virtual_offset) const { + if (length == 0 || backing_base == nullptr) { + return; + } + const auto hint = [length](u8* address) { +#ifdef _WIN32 + // Unlocking pages that are not locked takes them out of the working set. + VirtualUnlock(address, length); +#elif defined(__linux__) && defined(MADV_PAGEOUT) + madvise(address, length, MADV_PAGEOUT); +#else + static_cast<void>(address); +#endif + }; + hint(backing_base + physical_offset); + if (virtual_offset && virtual_base != nullptr && *virtual_offset + length <= virtual_size) { + hint(virtual_base + *virtual_offset); + } +} + void HostMemory::ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value) { std::memset(backing_base + physical_offset, fill_value, length); } diff --git a/src/common/host_memory.h b/src/common/host_memory.h index 8747a1850f..4d8d15cf58 100644 --- a/src/common/host_memory.h +++ b/src/common/host_memory.h @@ -54,6 +54,12 @@ public: void ClearBackingRegion(size_t physical_offset, size_t length, u32 fill_value); + /// Memory written once and read again rarely: its pages leave the working set (backing and, + /// when given, its view at virtual_offset), so the OS compresses or pages them out first when + /// it needs RAM. The contents stay; using the pages brings them back. + void HintCold(size_t physical_offset, size_t length, + std::optional<size_t> virtual_offset) const; + [[nodiscard]] u8* BackingBasePointer() noexcept { return backing_base; } |
