diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 32ff3c34540dea09bd3e61a43d9149c35c43309c..8416e73b0467a99cc589a4324511ddd9332de824 100644 --- a/src/core/arm/arm_interface.h +++ b/src/core/arm/arm_interface.h @@ -116,6 +116,8 @@ public: */ virtual void LoadContext(const ThreadContext& ctx) = 0; + virtual void ClearExclusiveState() = 0; + /// Prepare core for thread reschedule (if needed to correctly handle state) virtual void PrepareReschedule() = 0; }; diff --git a/src/core/arm/dynarmic/arm_dynarmic.cpp b/src/core/arm/dynarmic/arm_dynarmic.cpp index 42605374b62b6c7d339869fca77785c48a6a3cdb..3572ee7b93d31cdeb088956a76d128b772e5377e 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic.cpp @@ -226,6 +226,10 @@ void ARM_Dynarmic::ClearInstructionCache() { jit->ClearCache(); } +void ARM_Dynarmic::ClearExclusiveState() { + jit->ClearExclusiveState(); +} + void ARM_Dynarmic::PageTableChanged() { jit = MakeJit(cb); current_page_table = Memory::GetCurrentPageTable(); diff --git a/src/core/arm/dynarmic/arm_dynarmic.h b/src/core/arm/dynarmic/arm_dynarmic.h index 128669d0161ae7073154bbbf6c90a9ea4d86266d..ed724c3f168b9005e9733860ea11f786d35324e3 100644 --- a/src/core/arm/dynarmic/arm_dynarmic.h +++ b/src/core/arm/dynarmic/arm_dynarmic.h @@ -39,6 +39,7 @@ public: void LoadContext(const ThreadContext& ctx) override; void PrepareReschedule() override; + void ClearExclusiveState() override; void ClearInstructionCache() override; void PageTableChanged() override; diff --git a/src/core/arm/unicorn/arm_unicorn.cpp b/src/core/arm/unicorn/arm_unicorn.cpp index f239cf0eaa3b4e00a14770e1f03479340c1bc286..d2d699e9bd9ea4cf32ad4528dd2e9834f80e5d32 100644 --- a/src/core/arm/unicorn/arm_unicorn.cpp +++ b/src/core/arm/unicorn/arm_unicorn.cpp @@ -263,6 +263,8 @@ void ARM_Unicorn::PrepareReschedule() { CHECKED(uc_emu_stop(uc)); } +void ARM_Unicorn::ClearExclusiveState() {} + void ARM_Unicorn::ClearInstructionCache() {} void ARM_Unicorn::RecordBreak(GDBStub::BreakpointAddress bkpt) { diff --git a/src/core/arm/unicorn/arm_unicorn.h b/src/core/arm/unicorn/arm_unicorn.h index a482a2aa36982b257adc1d250a693e679f92a50c..a78a0acf2612833a9dee63e53c7bae95bd9909a5 100644 --- a/src/core/arm/unicorn/arm_unicorn.h +++ b/src/core/arm/unicorn/arm_unicorn.h @@ -31,6 +31,7 @@ public: void SaveContext(ThreadContext& ctx) override; void LoadContext(const ThreadContext& ctx) override; void PrepareReschedule() override; + void ClearExclusiveState() override; void ExecuteInstructions(int num_instructions); void Run() override; void Step() override; diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp index 11c2cb69ef8521ea690ecdbb46d0d5ad066ac601..ca8807e196c0771da53a483a43ff502358beb7c2 100644 --- a/src/core/hle/kernel/scheduler.cpp +++ b/src/core/hle/kernel/scheduler.cpp @@ -85,6 +85,7 @@ void Scheduler::SwitchContext(Thread* new_thread) { cpu_core->LoadContext(new_thread->context); cpu_core->SetTlsAddress(new_thread->GetTLSAddress()); + cpu_core->ClearExclusiveState(); } else { current_thread = nullptr; // Note: We do not reset the current process and current page table when idling because