[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 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.
constexpr std::array<s32, Common::BitSize<u64>()> VirtualToPhysicalCoreMap{

View file

@ -14,7 +14,7 @@
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) {}
size_t ExclusiveMonitor::GetProcessorCount() const {

View file

@ -14,7 +14,7 @@
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) {}
size_t ExclusiveMonitor::GetProcessorCount() const {
@ -29,20 +29,16 @@ void ExclusiveMonitor::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;
Lock();
if (exclusive_addresses[processor_id] != masked_address) {
Unlock();
return false;
}
for (VAddr& other_address : exclusive_addresses) {
if (other_address == masked_address) {
for (VAddr& other_address : exclusive_addresses)
if (other_address == masked_address)
other_address = INVALID_EXCLUSIVE_ADDRESS;
}
}
return true;
}

View file

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

View file

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

View file

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

View file

@ -6,11 +6,10 @@
#pragma once
#include <array>
#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <vector>
#include <boost/container/static_vector.hpp>
#include <dynarmic/common/spin_lock.h>
@ -80,9 +79,10 @@ private:
static constexpr VAddr RESERVATION_GRANULE_MASK = 0xFFFF'FFFF'FFFF'FFFFull;
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;
std::vector<VAddr> exclusive_addresses;
std::vector<Vector> exclusive_values;
};
} // namespace Dynarmic