mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-27 04:25:12 +00:00
Defer memory protect
This commit is contained in:
parent
7c6f3cc00c
commit
291d989b49
@ -1,7 +1,7 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include <boost/icl/interval_set.hpp>
|
#include <boost/container/small_vector.hpp>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/signal_context.h"
|
#include "common/signal_context.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
@ -54,6 +54,12 @@ struct PageManager::Impl {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct UpdateProtectRange {
|
||||||
|
VAddr addr;
|
||||||
|
u64 size;
|
||||||
|
Core::MemoryPermission perms;
|
||||||
|
};
|
||||||
|
|
||||||
static constexpr size_t ADDRESS_BITS = 40;
|
static constexpr size_t ADDRESS_BITS = 40;
|
||||||
static constexpr size_t NUM_ADDRESS_PAGES = 1ULL << (40 - PAGE_BITS);
|
static constexpr size_t NUM_ADDRESS_PAGES = 1ULL << (40 - PAGE_BITS);
|
||||||
inline static Vulkan::Rasterizer* rasterizer;
|
inline static Vulkan::Rasterizer* rasterizer;
|
||||||
@ -184,6 +190,8 @@ struct PageManager::Impl {
|
|||||||
#endif
|
#endif
|
||||||
template <s32 delta>
|
template <s32 delta>
|
||||||
void UpdatePageWatchers(VAddr addr, u64 size) {
|
void UpdatePageWatchers(VAddr addr, u64 size) {
|
||||||
|
boost::container::small_vector<UpdateProtectRange, 16> update_ranges;
|
||||||
|
{
|
||||||
std::scoped_lock lk(lock);
|
std::scoped_lock lk(lock);
|
||||||
|
|
||||||
size_t page = addr >> PAGE_BITS;
|
size_t page = addr >> PAGE_BITS;
|
||||||
@ -192,8 +200,10 @@ struct PageManager::Impl {
|
|||||||
u64 range_bytes = 0;
|
u64 range_bytes = 0;
|
||||||
|
|
||||||
const auto release_pending = [&] {
|
const auto release_pending = [&] {
|
||||||
|
RENDERER_TRACE;
|
||||||
if (range_bytes > 0) {
|
if (range_bytes > 0) {
|
||||||
Protect(range_begin << PAGE_BITS, range_bytes, perms);
|
// Add pending (un)protect action
|
||||||
|
update_ranges.push_back({range_begin << PAGE_BITS, range_bytes, perms});
|
||||||
range_bytes = 0;
|
range_bytes = 0;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -206,7 +216,7 @@ struct PageManager::Impl {
|
|||||||
// Apply the change to the page state
|
// Apply the change to the page state
|
||||||
const u8 new_count = state.AddDelta<delta>();
|
const u8 new_count = state.AddDelta<delta>();
|
||||||
|
|
||||||
// If the protection changed flush pending (un)protect action
|
// If the protection changed add pending (un)protect action
|
||||||
if (auto new_perms = state.Perm(); new_perms != perms) [[unlikely]] {
|
if (auto new_perms = state.Perm(); new_perms != perms) [[unlikely]] {
|
||||||
release_pending();
|
release_pending();
|
||||||
perms = new_perms;
|
perms = new_perms;
|
||||||
@ -223,10 +233,16 @@ struct PageManager::Impl {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush pending (un)protect action
|
// Add pending (un)protect action
|
||||||
release_pending();
|
release_pending();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Flush deferred protects
|
||||||
|
for (const auto& range : update_ranges) {
|
||||||
|
Protect(range.addr, range.size, range.perms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::array<PageState, NUM_ADDRESS_PAGES> cached_pages{};
|
std::array<PageState, NUM_ADDRESS_PAGES> cached_pages{};
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
Common::AdaptiveMutex lock;
|
Common::AdaptiveMutex lock;
|
||||||
|
Loading…
Reference in New Issue
Block a user