[dynarmic] reduce exclusive monitor overhead

Signed-off-by: lizzie <lizzie@eden-emu.dev>
This commit is contained in:
lizzie 2025-08-08 18:47:03 +01:00 committed by crueter
parent 5dbecc45c7
commit 425ccf333b
7 changed files with 16 additions and 21 deletions

View file

@ -15,7 +15,7 @@ namespace Hardware {
constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz constexpr u64 BASE_CLOCK_RATE = 1'020'000'000; // Default CPU Frequency = 1020 MHz
constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz constexpr u64 CNTFREQ = 19'200'000; // CNTPCT_EL0 Frequency = 19.2 MHz
constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores constexpr u32 NUM_CPU_CORES = 4; // Number of CPU Cores - sync with dynarmic exclusive_monitor.h
// Virtual to Physical core map. // Virtual to Physical core map.
constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{ constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{

View file

@ -14,7 +14,7 @@
namespace Dynarmic { namespace Dynarmic {
ExclusiveMonitor::ExclusiveMonitor(size_t processor_count) ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count)
: exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {} : exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {}
size_t ExclusiveMonitor::GetProcessorCount() const { size_t ExclusiveMonitor::GetProcessorCount() const {

View file

@ -14,7 +14,7 @@
namespace Dynarmic { namespace Dynarmic {
ExclusiveMonitor::ExclusiveMonitor(size_t processor_count) ExclusiveMonitor::ExclusiveMonitor(std::size_t processor_count)
: exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {} : exclusive_addresses(processor_count, INVALID_EXCLUSIVE_ADDRESS), exclusive_values(processor_count) {}
size_t ExclusiveMonitor::GetProcessorCount() const { size_t ExclusiveMonitor::GetProcessorCount() const {
@ -29,20 +29,16 @@ void ExclusiveMonitor::Unlock() {
lock.Unlock(); lock.Unlock();
} }
bool ExclusiveMonitor::CheckAndClear(size_t processor_id, VAddr address) { bool ExclusiveMonitor::CheckAndClear(std::size_t processor_id, VAddr address) {
const VAddr masked_address = address & RESERVATION_GRANULE_MASK; const VAddr masked_address = address & RESERVATION_GRANULE_MASK;
Lock(); Lock();
if (exclusive_addresses[processor_id] != masked_address) { if (exclusive_addresses[processor_id] != masked_address) {
Unlock(); Unlock();
return false; return false;
} }
for (VAddr& other_address : exclusive_addresses)
for (VAddr& other_address : exclusive_addresses) { if (other_address == masked_address)
if (other_address == masked_address) {
other_address = INVALID_EXCLUSIVE_ADDRESS; other_address = INVALID_EXCLUSIVE_ADDRESS;
}
}
return true; return true;
} }

View file

@ -8,9 +8,8 @@
namespace Dynarmic { namespace Dynarmic {
struct SpinLock { struct SpinLock {
void Lock(); void Lock() noexcept;
void Unlock(); void Unlock() noexcept;
volatile int storage = 0; volatile int storage = 0;
}; };

View file

@ -73,12 +73,12 @@ void SpinLockImpl::Initialize() {
} // namespace } // namespace
void SpinLock::Lock() { void SpinLock::Lock() noexcept {
std::call_once(flag, &SpinLockImpl::Initialize, impl); std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.lock(&storage); impl.lock(&storage);
} }
void SpinLock::Unlock() { void SpinLock::Unlock() noexcept {
std::call_once(flag, &SpinLockImpl::Initialize, impl); std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.unlock(&storage); impl.unlock(&storage);
} }

View file

@ -62,12 +62,12 @@ void SpinLockImpl::Initialize() {
} // namespace } // namespace
void SpinLock::Lock() { void SpinLock::Lock() noexcept {
std::call_once(flag, &SpinLockImpl::Initialize, impl); std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.lock(&storage); impl.lock(&storage);
} }
void SpinLock::Unlock() { void SpinLock::Unlock() noexcept {
std::call_once(flag, &SpinLockImpl::Initialize, impl); std::call_once(flag, &SpinLockImpl::Initialize, impl);
impl.unlock(&storage); impl.unlock(&storage);
} }

View file

@ -6,11 +6,10 @@
#pragma once #pragma once
#include <array> #include <array>
#include <atomic>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <vector> #include <boost/container/static_vector.hpp>
#include <dynarmic/common/spin_lock.h> #include <dynarmic/common/spin_lock.h>
@ -80,9 +79,10 @@ private:
static constexpr VAddr RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFFFull; static constexpr VAddr RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFFFull;
static constexpr VAddr INVALID_EXCLUSIVE_ADDRESS = 0xDEAD'DEAD'DEAD'DEADull; static constexpr VAddr INVALID_EXCLUSIVE_ADDRESS = 0xDEAD'DEAD'DEAD'DEADull;
static constexpr size_t MAX_NUM_CPU_CORES = 4; // Sync with src/core/hardware_properties
boost::container::static_vector<VAddr, MAX_NUM_CPU_CORES> exclusive_addresses;
boost::container::static_vector<Vector, MAX_NUM_CPU_CORES> exclusive_values;
SpinLock lock; SpinLock lock;
std::vector<VAddr> exclusive_addresses;
std::vector<Vector> exclusive_values;
}; };
} // namespace Dynarmic } // namespace Dynarmic