From 56cc1c11ecad9e7ea2a36fbb74852a7579b53802 Mon Sep 17 00:00:00 2001 From: MerryMage Date: Mon, 16 Jul 2018 11:24:00 +0100 Subject: scheduler: Clear exclusive state when switching contexts --- src/core/arm/arm_interface.h | 2 ++ src/core/arm/dynarmic/arm_dynarmic.cpp | 4 ++++ src/core/arm/dynarmic/arm_dynarmic.h | 1 + src/core/arm/unicorn/arm_unicorn.cpp | 2 ++ src/core/arm/unicorn/arm_unicorn.h | 1 + src/core/hle/kernel/scheduler.cpp | 1 + 6 files changed, 11 insertions(+) (limited to 'src') diff --git a/src/core/arm/arm_interface.h b/src/core/arm/arm_interface.h index 32ff3c345..8416e73b0 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 42605374b..3572ee7b9 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 128669d01..ed724c3f1 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 f239cf0ea..d2d699e9b 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 a482a2aa3..a78a0acf2 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 11c2cb69e..ca8807e19 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 -- cgit v1.2.3