From 47be9d8e6b8659e403ac4be5c709a48db647dac4 Mon Sep 17 00:00:00 2001 From: magumagu Date: Fri, 30 Jan 2015 14:48:23 -0800 Subject: [PATCH 1/2] Clean up usage of ScheduleEvent_Threadsafe. --- Source/Core/Core/CoreTiming.cpp | 2 ++ Source/Core/Core/HW/DSP.cpp | 5 +++-- Source/Core/Core/HW/DVDInterface.cpp | 1 + Source/Core/Core/HW/SI.cpp | 1 + Source/Core/Core/HW/WII_IPC.cpp | 8 ++++---- Source/Core/VideoCommon/PixelEngine.cpp | 11 +++++++++-- 6 files changed, 20 insertions(+), 8 deletions(-) diff --git a/Source/Core/Core/CoreTiming.cpp b/Source/Core/Core/CoreTiming.cpp index c6c349711b..e8cfbae287 100644 --- a/Source/Core/Core/CoreTiming.cpp +++ b/Source/Core/Core/CoreTiming.cpp @@ -224,6 +224,7 @@ u64 GetIdleTicks() // schedule things to be executed on the main thread. void ScheduleEvent_Threadsafe(int cyclesIntoFuture, int event_type, u64 userdata) { + _assert_msg_(POWERPC, !Core::IsCPUThread(), "ScheduleEvent_Threadsafe from wrong thread"); std::lock_guard lk(tsWriteLock); Event ne; ne.time = globalTimer + cyclesIntoFuture; @@ -279,6 +280,7 @@ static void AddEventToQueue(Event* ne) // than Advance void ScheduleEvent(int cyclesIntoFuture, int event_type, u64 userdata) { + _assert_msg_(POWERPC, Core::IsCPUThread(), "ScheduleEvent from wrong thread"); Event *ne = GetNewEvent(); ne->userdata = userdata; ne->type = event_type; diff --git a/Source/Core/Core/HW/DSP.cpp b/Source/Core/Core/HW/DSP.cpp index 124e2c92b8..11bd45005c 100644 --- a/Source/Core/Core/HW/DSP.cpp +++ b/Source/Core/Core/HW/DSP.cpp @@ -427,7 +427,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) // We make the samples ready as soon as possible void *address = Memory::GetPointer(g_audioDMA.SourceAddress); AudioCommon::SendAIBuffer((short*)address, g_audioDMA.AudioDMAControl.NumBlocks * 8); - CoreTiming::ScheduleEvent_Threadsafe(80, et_GenerateDSPInterrupt, INT_AID); + CoreTiming::ScheduleEvent(80, et_GenerateDSPInterrupt, INT_AID); } }) ); @@ -477,6 +477,7 @@ static void GenerateDSPInterrupt(u64 DSPIntType, int cyclesLate) // CALLED FROM DSP EMULATOR, POSSIBLY THREADED void GenerateDSPInterruptFromDSPEmu(DSPInterruptType type) { + // TODO: Maybe rethink this? ScheduleEvent_Threadsafe has unpredictable timing. CoreTiming::ScheduleEvent_Threadsafe_Immediate(et_GenerateDSPInterrupt, type); } @@ -543,7 +544,7 @@ static void Do_ARAM_DMA() if (instant_dma) ticksToTransfer = 0; - CoreTiming::ScheduleEvent_Threadsafe(ticksToTransfer, et_CompleteARAM); + CoreTiming::ScheduleEvent(ticksToTransfer, et_CompleteARAM); if (instant_dma) CoreTiming::ForceExceptionCheck(100); diff --git a/Source/Core/Core/HW/DVDInterface.cpp b/Source/Core/Core/HW/DVDInterface.cpp index 3a25ce97b5..bd6c3e2038 100644 --- a/Source/Core/Core/HW/DVDInterface.cpp +++ b/Source/Core/Core/HW/DVDInterface.cpp @@ -447,6 +447,7 @@ void ChangeDisc(const std::string& newFileName) std::string* _FileName = new std::string(newFileName); CoreTiming::ScheduleEvent_Threadsafe(0, ejectDisc); CoreTiming::ScheduleEvent_Threadsafe(500000000, insertDisc, (u64)_FileName); + // TODO: We shouldn't be modifying movie state from the GUI thread. if (Movie::IsRecordingInput()) { Movie::g_bDiscChange = true; diff --git a/Source/Core/Core/HW/SI.cpp b/Source/Core/Core/HW/SI.cpp index a25c956f8f..513f16da2d 100644 --- a/Source/Core/Core/HW/SI.cpp +++ b/Source/Core/Core/HW/SI.cpp @@ -492,6 +492,7 @@ void ChangeDevice(SIDevices device, int channel) { // Called from GUI, so we need to make it thread safe. // Let the hardware see no device for .5b cycles + // TODO: Calling GetDeviceType here isn't threadsafe. if (GetDeviceType(channel) != device) { CoreTiming::ScheduleEvent_Threadsafe(0, changeDevice, ((u64)channel << 32) | SIDEVICE_NONE); diff --git a/Source/Core/Core/HW/WII_IPC.cpp b/Source/Core/Core/HW/WII_IPC.cpp index a423d7a870..56019ddf51 100644 --- a/Source/Core/Core/HW/WII_IPC.cpp +++ b/Source/Core/Core/HW/WII_IPC.cpp @@ -162,7 +162,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) if (ctrl.X1) WII_IPC_HLE_Interface::EnqueueRequest(ppc_msg); WII_IPC_HLE_Interface::Update(); - CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + CoreTiming::ScheduleEvent(0, updateInterrupts, 0); }) ); @@ -176,7 +176,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) MMIO::ComplexWrite([](u32, u32 val) { ppc_irq_flags &= ~val; WII_IPC_HLE_Interface::Update(); - CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + CoreTiming::ScheduleEvent(0, updateInterrupts, 0); }) ); @@ -187,7 +187,7 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) if (ppc_irq_masks & INT_CAUSE_IPC_BROADWAY) // wtf? Reset(); WII_IPC_HLE_Interface::Update(); - CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + CoreTiming::ScheduleEvent(0, updateInterrupts, 0); }) ); @@ -228,7 +228,7 @@ void GenerateAck(u32 _Address) ctrl.Y2 = 1; INFO_LOG(WII_IPC, "GenerateAck: %08x | %08x [R:%i A:%i E:%i]", ppc_msg,_Address, ctrl.Y1, ctrl.Y2, ctrl.X1); - CoreTiming::ScheduleEvent_Threadsafe(0, updateInterrupts, 0); + CoreTiming::ScheduleEvent(0, updateInterrupts, 0); } void GenerateReply(u32 _Address) diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp index f6bc26186a..afe08c7d0a 100644 --- a/Source/Core/VideoCommon/PixelEngine.cpp +++ b/Source/Core/VideoCommon/PixelEngine.cpp @@ -16,6 +16,7 @@ #include "Core/HW/ProcessorInterface.h" #include "VideoCommon/BoundingBox.h" #include "VideoCommon/CommandProcessor.h" +#include "VideoCommon/Fifo.h" #include "VideoCommon/PixelEngine.h" #include "VideoCommon/RenderBase.h" #include "VideoCommon/VideoCommon.h" @@ -299,7 +300,10 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge) } CommandProcessor::interruptTokenWaiting = true; - CoreTiming::ScheduleEvent_Threadsafe(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || g_use_deterministic_gpu_thread) + CoreTiming::ScheduleEvent(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); + else + CoreTiming::ScheduleEvent_Threadsafe(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16)); } // SetFinish @@ -307,7 +311,10 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge) void SetFinish() { CommandProcessor::interruptFinishWaiting = true; - CoreTiming::ScheduleEvent_Threadsafe(0, et_SetFinishOnMainThread, 0); + if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || g_use_deterministic_gpu_thread) + CoreTiming::ScheduleEvent(0, et_SetFinishOnMainThread, 0); + else + CoreTiming::ScheduleEvent_Threadsafe(0, et_SetFinishOnMainThread, 0); INFO_LOG(PIXELENGINE, "VIDEO Set Finish"); } From 30d15b3a32485bda06f7eea605b1a66155e25dad Mon Sep 17 00:00:00 2001 From: magumagu Date: Fri, 30 Jan 2015 15:05:50 -0800 Subject: [PATCH 2/2] Clean up usage of PowerPCState::Exceptions. Accessing any member of ppcState from a thread other than the CPU thread is not allowed; don't pretend that there's any exception to that rule. --- Source/Core/Core/HW/MemmapFunctions.cpp | 4 +-- Source/Core/Core/HW/ProcessorInterface.cpp | 7 ++--- Source/Core/Core/HW/SystemTimers.cpp | 2 +- .../Core/PowerPC/Interpreter/Interpreter.cpp | 2 +- .../Interpreter/Interpreter_Branch.cpp | 2 +- .../Interpreter/Interpreter_Integer.cpp | 4 +-- .../Interpreter/Interpreter_LoadStore.cpp | 8 +++--- .../Interpreter_SystemRegisters.cpp | 2 +- Source/Core/Core/PowerPC/PowerPC.cpp | 27 +++++++++---------- Source/Core/Core/PowerPC/PowerPC.h | 2 +- 10 files changed, 29 insertions(+), 31 deletions(-) diff --git a/Source/Core/Core/HW/MemmapFunctions.cpp b/Source/Core/Core/HW/MemmapFunctions.cpp index f8380ac183..42d389a077 100644 --- a/Source/Core/Core/HW/MemmapFunctions.cpp +++ b/Source/Core/Core/HW/MemmapFunctions.cpp @@ -647,7 +647,7 @@ static void GenerateDSIException(u32 effectiveAddress, bool write) PowerPC::ppcState.spr[SPR_DAR] = effectiveAddress; - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); + PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; } @@ -656,7 +656,7 @@ static void GenerateISIException(u32 _EffectiveAddress) // Address of instruction could not be translated NPC = _EffectiveAddress; - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ISI); + PowerPC::ppcState.Exceptions |= EXCEPTION_ISI; } diff --git a/Source/Core/Core/HW/ProcessorInterface.cpp b/Source/Core/Core/HW/ProcessorInterface.cpp index 27306988d2..195660e17c 100644 --- a/Source/Core/Core/HW/ProcessorInterface.cpp +++ b/Source/Core/Core/HW/ProcessorInterface.cpp @@ -8,6 +8,7 @@ #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" +#include "Core/Core.h" #include "Core/CoreTiming.h" #include "Core/HW/CPU.h" #include "Core/HW/GPFifo.h" @@ -159,9 +160,9 @@ void RegisterMMIO(MMIO::Mapping* mmio, u32 base) void UpdateException() { if ((m_InterruptCause & m_InterruptMask) != 0) - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_EXTERNAL_INT); + PowerPC::ppcState.Exceptions |= EXCEPTION_EXTERNAL_INT; else - Common::AtomicAnd(PowerPC::ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); + PowerPC::ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; } static const char *Debug_GetInterruptName(u32 _causemask) @@ -190,7 +191,7 @@ static const char *Debug_GetInterruptName(u32 _causemask) void SetInterrupt(u32 _causemask, bool _bSet) { - // TODO(ector): add sanity check that current thread id is CPU thread + _assert_msg_(POWERPC, Core::IsCPUThread(), "SetInterrupt from wrong thread"); if (_bSet && !(m_InterruptCause & _causemask)) { diff --git a/Source/Core/Core/HW/SystemTimers.cpp b/Source/Core/Core/HW/SystemTimers.cpp index c907d3f1a1..f40a807239 100644 --- a/Source/Core/Core/HW/SystemTimers.cpp +++ b/Source/Core/Core/HW/SystemTimers.cpp @@ -158,7 +158,7 @@ static void CPCallback(u64 userdata, int cyclesLate) static void DecrementerCallback(u64 userdata, int cyclesLate) { PowerPC::ppcState.spr[SPR_DEC] = 0xFFFFFFFF; - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER); + PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; } void DecrementerSet() diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp index 749205201f..d8f7c86caa 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter.cpp @@ -146,7 +146,7 @@ int Interpreter::SingleStepInner() } else { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_FPU_UNAVAILABLE); + PowerPC::ppcState.Exceptions |= EXCEPTION_FPU_UNAVAILABLE; PowerPC::CheckExceptions(); m_EndBlock = true; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp index a7fe02bcb4..497f06fb82 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Branch.cpp @@ -124,7 +124,7 @@ void Interpreter::rfid(UGeckoInstruction _inst) // We do it anyway, though :P void Interpreter::sc(UGeckoInstruction _inst) { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_SYSCALL); + PowerPC::ppcState.Exceptions |= EXCEPTION_SYSCALL; PowerPC::CheckExceptions(); m_EndBlock = true; } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp index 954cc26205..7f7c8b3edc 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_Integer.cpp @@ -157,7 +157,7 @@ void Interpreter::twi(UGeckoInstruction _inst) (((u32)a <(u32)b) && (TO & 0x02)) || (((u32)a >(u32)b) && (TO & 0x01))) { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM); + PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; PowerPC::CheckExceptions(); m_EndBlock = true; // Dunno about this } @@ -423,7 +423,7 @@ void Interpreter::tw(UGeckoInstruction _inst) (((u32)a <(u32)b) && (TO & 0x02)) || (((u32)a >(u32)b) && (TO & 0x01))) { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_PROGRAM); + PowerPC::ppcState.Exceptions |= EXCEPTION_PROGRAM; PowerPC::CheckExceptions(); m_EndBlock = true; // Dunno about this } diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp index df98c97bd4..af5c29601b 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_LoadStore.cpp @@ -395,10 +395,10 @@ void Interpreter::eciwx(UGeckoInstruction _inst) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); + PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; } if (EA & 3) - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT); + PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; // _assert_msg_(POWERPC,0,"eciwx - fill r%i with word @ %08x from device %02x", // _inst.RS, EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); @@ -417,10 +417,10 @@ void Interpreter::ecowx(UGeckoInstruction _inst) if (!(PowerPC::ppcState.spr[SPR_EAR] & 0x80000000)) { - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DSI); + PowerPC::ppcState.Exceptions |= EXCEPTION_DSI; } if (EA & 3) - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_ALIGNMENT); + PowerPC::ppcState.Exceptions |= EXCEPTION_ALIGNMENT; // _assert_msg_(POWERPC,0,"ecowx - send stw request (%08x@%08x) to device %02x", // rGPR[_inst.RS], EA, PowerPC::ppcState.spr[SPR_EAR] & 0x1f); diff --git a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp index e181d1603d..50aac47962 100644 --- a/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp +++ b/Source/Core/Core/PowerPC/Interpreter/Interpreter_SystemRegisters.cpp @@ -344,7 +344,7 @@ void Interpreter::mtspr(UGeckoInstruction _inst) if (!(oldValue >> 31) && (rGPR[_inst.RD]>>31)) //top bit from 0 to 1 { PanicAlert("Interesting - Software triggered Decrementer exception"); - Common::AtomicOr(PowerPC::ppcState.Exceptions, EXCEPTION_DECREMENTER); + PowerPC::ppcState.Exceptions |= EXCEPTION_DECREMENTER; } SystemTimers::DecrementerSet(); break; diff --git a/Source/Core/Core/PowerPC/PowerPC.cpp b/Source/Core/Core/PowerPC/PowerPC.cpp index fca69f7bc1..1023b82a2f 100644 --- a/Source/Core/Core/PowerPC/PowerPC.cpp +++ b/Source/Core/Core/PowerPC/PowerPC.cpp @@ -2,7 +2,6 @@ // Licensed under GPLv2 // Refer to the license.txt file included. -#include "Common/Atomic.h" #include "Common/ChunkFile.h" #include "Common/CommonTypes.h" #include "Common/FPURoundMode.h" @@ -311,7 +310,6 @@ void UpdatePerformanceMonitor(u32 cycles, u32 num_load_stores, u32 num_fp_inst) void CheckExceptions() { - // Read volatile data once u32 exceptions = ppcState.Exceptions; // Example procedure: @@ -341,7 +339,7 @@ void CheckExceptions() PC = NPC = 0x00000400; INFO_LOG(POWERPC, "EXCEPTION_ISI"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_ISI); + ppcState.Exceptions &= ~EXCEPTION_ISI; } else if (exceptions & EXCEPTION_PROGRAM) { @@ -353,7 +351,7 @@ void CheckExceptions() PC = NPC = 0x00000700; INFO_LOG(POWERPC, "EXCEPTION_PROGRAM"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_PROGRAM); + ppcState.Exceptions &= ~EXCEPTION_PROGRAM; } else if (exceptions & EXCEPTION_SYSCALL) { @@ -364,7 +362,7 @@ void CheckExceptions() PC = NPC = 0x00000C00; INFO_LOG(POWERPC, "EXCEPTION_SYSCALL (PC=%08x)", PC); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_SYSCALL); + ppcState.Exceptions &= ~EXCEPTION_SYSCALL; } else if (exceptions & EXCEPTION_FPU_UNAVAILABLE) { @@ -376,7 +374,7 @@ void CheckExceptions() PC = NPC = 0x00000800; INFO_LOG(POWERPC, "EXCEPTION_FPU_UNAVAILABLE"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_FPU_UNAVAILABLE); + ppcState.Exceptions &= ~EXCEPTION_FPU_UNAVAILABLE; } else if (exceptions & EXCEPTION_DSI) { @@ -388,7 +386,7 @@ void CheckExceptions() //DSISR and DAR regs are changed in GenerateDSIException() INFO_LOG(POWERPC, "EXCEPTION_DSI"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DSI); + ppcState.Exceptions &= ~EXCEPTION_DSI; } else if (exceptions & EXCEPTION_ALIGNMENT) { @@ -403,7 +401,7 @@ void CheckExceptions() //TODO crazy amount of DSISR options to check out INFO_LOG(POWERPC, "EXCEPTION_ALIGNMENT"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_ALIGNMENT); + ppcState.Exceptions &= ~EXCEPTION_ALIGNMENT; } // EXTERNAL INTERRUPT @@ -419,7 +417,7 @@ void CheckExceptions() PC = NPC = 0x00000500; INFO_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); + ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; _dbg_assert_msg_(POWERPC, (SRR1 & 0x02) != 0, "EXTERNAL_INT unrecoverable???"); } @@ -432,7 +430,7 @@ void CheckExceptions() PC = NPC = 0x00000F00; INFO_LOG(POWERPC, "EXCEPTION_PERFORMANCE_MONITOR"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_PERFORMANCE_MONITOR); + ppcState.Exceptions &= ~EXCEPTION_PERFORMANCE_MONITOR; } else if (exceptions & EXCEPTION_DECREMENTER) { @@ -443,14 +441,13 @@ void CheckExceptions() PC = NPC = 0x00000900; INFO_LOG(POWERPC, "EXCEPTION_DECREMENTER"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DECREMENTER); + ppcState.Exceptions &= ~EXCEPTION_DECREMENTER; } } } void CheckExternalExceptions() { - // Read volatile data once u32 exceptions = ppcState.Exceptions; // EXTERNAL INTERRUPT @@ -466,7 +463,7 @@ void CheckExternalExceptions() PC = NPC = 0x00000500; INFO_LOG(POWERPC, "EXCEPTION_EXTERNAL_INT"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_EXTERNAL_INT); + ppcState.Exceptions &= ~EXCEPTION_EXTERNAL_INT; _dbg_assert_msg_(POWERPC, (SRR1 & 0x02) != 0, "EXTERNAL_INT unrecoverable???"); } @@ -479,7 +476,7 @@ void CheckExternalExceptions() PC = NPC = 0x00000F00; INFO_LOG(POWERPC, "EXCEPTION_PERFORMANCE_MONITOR"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_PERFORMANCE_MONITOR); + ppcState.Exceptions &= ~EXCEPTION_PERFORMANCE_MONITOR; } else if (exceptions & EXCEPTION_DECREMENTER) { @@ -490,7 +487,7 @@ void CheckExternalExceptions() PC = NPC = 0x00000900; INFO_LOG(POWERPC, "EXCEPTION_DECREMENTER"); - Common::AtomicAnd(ppcState.Exceptions, ~EXCEPTION_DECREMENTER); + ppcState.Exceptions &= ~EXCEPTION_DECREMENTER; } else { diff --git a/Source/Core/Core/PowerPC/PowerPC.h b/Source/Core/Core/PowerPC/PowerPC.h index 5ac0d802a4..6dce03a55b 100644 --- a/Source/Core/Core/PowerPC/PowerPC.h +++ b/Source/Core/Core/PowerPC/PowerPC.h @@ -73,7 +73,7 @@ struct GC_ALIGNED64(PowerPCState) u32 fpscr; // floating point flags/status bits // Exception management. - volatile u32 Exceptions; + u32 Exceptions; // Downcount for determining when we need to do timing // This isn't quite the right location for it, but it is here to accelerate the ARM JIT