yuzu-emu
/
yuzu-mainline
Archived
1
0
Fork 0

dynarmic: Better interrupts

This commit is contained in:
merry 2022-04-03 16:29:05 +01:00
parent 51a8dd4919
commit f8b8af47ad
7 changed files with 28 additions and 23 deletions

2
externals/dynarmic vendored

@ -1 +1 @@
Subproject commit 8bcd46b7e9dc487da217b216c908f2ef15e7a8cf Subproject commit 644172477eaf0d822178cb7e96c62b75caa96573

View File

@ -171,6 +171,9 @@ public:
/// Prepare core for thread reschedule (if needed to correctly handle state) /// Prepare core for thread reschedule (if needed to correctly handle state)
virtual void PrepareReschedule() = 0; virtual void PrepareReschedule() = 0;
/// Signal an interrupt and ask the core to halt as soon as possible.
virtual void SignalInterrupt() = 0;
struct BacktraceEntry { struct BacktraceEntry {
std::string module; std::string module;
u64 address; u64 address;

View File

@ -88,9 +88,8 @@ public:
} }
void AddTicks(u64 ticks) override { void AddTicks(u64 ticks) override {
if (parent.uses_wall_clock) { ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
return;
}
// Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
// rough approximation of the amount of executed ticks in the system, it may be thrown off // rough approximation of the amount of executed ticks in the system, it may be thrown off
// if not all cores are doing a similar amount of work. Instead of doing this, we should // if not all cores are doing a similar amount of work. Instead of doing this, we should
@ -106,12 +105,8 @@ public:
} }
u64 GetTicksRemaining() override { u64 GetTicksRemaining() override {
if (parent.uses_wall_clock) { ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) {
return minimum_run_cycles;
}
return 0U;
}
return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0);
} }
@ -146,6 +141,7 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
// Timing // Timing
config.wall_clock_cntpct = uses_wall_clock; config.wall_clock_cntpct = uses_wall_clock;
config.enable_cycle_counting = !uses_wall_clock;
// Code cache size // Code cache size
config.code_cache_size = 512_MiB; config.code_cache_size = 512_MiB;
@ -222,13 +218,13 @@ std::shared_ptr<Dynarmic::A32::Jit> ARM_Dynarmic_32::MakeJit(Common::PageTable*
void ARM_Dynarmic_32::Run() { void ARM_Dynarmic_32::Run() {
while (true) { while (true) {
jit->Run(); const auto hr = jit->Run();
if (!svc_called) { if (!svc_called) {
break; break;
} }
svc_called = false; svc_called = false;
Kernel::Svc::Call(system, svc_swi); Kernel::Svc::Call(system, svc_swi);
if (shutdown) { if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) {
break; break;
} }
} }
@ -318,6 +314,10 @@ void ARM_Dynarmic_32::PrepareReschedule() {
shutdown = true; shutdown = true;
} }
void ARM_Dynarmic_32::SignalInterrupt() {
jit->HaltExecution(Dynarmic::HaltReason::UserDefined2);
}
void ARM_Dynarmic_32::ClearInstructionCache() { void ARM_Dynarmic_32::ClearInstructionCache() {
jit->ClearCache(); jit->ClearCache();
} }

View File

@ -57,6 +57,7 @@ public:
void LoadContext(const ThreadContext64& ctx) override {} void LoadContext(const ThreadContext64& ctx) override {}
void PrepareReschedule() override; void PrepareReschedule() override;
void SignalInterrupt() override;
void ClearExclusiveState() override; void ClearExclusiveState() override;
void ClearInstructionCache() override; void ClearInstructionCache() override;

View File

@ -130,9 +130,7 @@ public:
} }
void AddTicks(u64 ticks) override { void AddTicks(u64 ticks) override {
if (parent.uses_wall_clock) { ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
return;
}
// Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a // Divide the number of ticks by the amount of CPU cores. TODO(Subv): This yields only a
// rough approximation of the amount of executed ticks in the system, it may be thrown off // rough approximation of the amount of executed ticks in the system, it may be thrown off
@ -147,12 +145,8 @@ public:
} }
u64 GetTicksRemaining() override { u64 GetTicksRemaining() override {
if (parent.uses_wall_clock) { ASSERT_MSG(!parent.uses_wall_clock, "This should never happen - dynarmic ticking disabled");
if (!parent.interrupt_handlers[parent.core_index].IsInterrupted()) {
return minimum_run_cycles;
}
return 0U;
}
return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0); return std::max<s64>(parent.system.CoreTiming().GetDowncount(), 0);
} }
@ -208,6 +202,7 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
// Timing // Timing
config.wall_clock_cntpct = uses_wall_clock; config.wall_clock_cntpct = uses_wall_clock;
config.enable_cycle_counting = !uses_wall_clock;
// Code cache size // Code cache size
config.code_cache_size = 512_MiB; config.code_cache_size = 512_MiB;
@ -284,13 +279,13 @@ std::shared_ptr<Dynarmic::A64::Jit> ARM_Dynarmic_64::MakeJit(Common::PageTable*
void ARM_Dynarmic_64::Run() { void ARM_Dynarmic_64::Run() {
while (true) { while (true) {
jit->Run(); const auto hr = jit->Run();
if (!svc_called) { if (!svc_called) {
break; break;
} }
svc_called = false; svc_called = false;
Kernel::Svc::Call(system, svc_swi); Kernel::Svc::Call(system, svc_swi);
if (shutdown) { if (shutdown || Has(hr, Dynarmic::HaltReason::UserDefined2)) {
break; break;
} }
} }
@ -385,6 +380,10 @@ void ARM_Dynarmic_64::PrepareReschedule() {
shutdown = true; shutdown = true;
} }
void ARM_Dynarmic_64::SignalInterrupt() {
jit->HaltExecution(Dynarmic::HaltReason::UserDefined2);
}
void ARM_Dynarmic_64::ClearInstructionCache() { void ARM_Dynarmic_64::ClearInstructionCache() {
jit->ClearCache(); jit->ClearCache();
} }

View File

@ -51,6 +51,7 @@ public:
void LoadContext(const ThreadContext64& ctx) override; void LoadContext(const ThreadContext64& ctx) override;
void PrepareReschedule() override; void PrepareReschedule() override;
void SignalInterrupt() override;
void ClearExclusiveState() override; void ClearExclusiveState() override;
void ClearInstructionCache() override; void ClearInstructionCache() override;

View File

@ -58,6 +58,7 @@ bool PhysicalCore::IsInterrupted() const {
void PhysicalCore::Interrupt() { void PhysicalCore::Interrupt() {
guard->lock(); guard->lock();
interrupts[core_index].SetInterrupt(true); interrupts[core_index].SetInterrupt(true);
arm_interface->SignalInterrupt();
guard->unlock(); guard->unlock();
} }