mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-06-14 00:58:51 +02:00
CommandProcessor: Replace volatile usages with atomics
Also remove said variables from being globals.
This commit is contained in:
@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include "Common/Atomic.h"
|
||||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
@ -40,15 +42,15 @@ static u16 m_bboxright;
|
||||
static u16 m_bboxbottom;
|
||||
static u16 m_tokenReg;
|
||||
|
||||
volatile bool interruptSet= false;
|
||||
volatile bool interruptWaiting= false;
|
||||
volatile bool interruptTokenWaiting = false;
|
||||
volatile bool interruptFinishWaiting = false;
|
||||
static std::atomic<bool> s_interrupt_set;
|
||||
static std::atomic<bool> s_interrupt_waiting;
|
||||
static std::atomic<bool> s_interrupt_token_waiting;
|
||||
static std::atomic<bool> s_interrupt_finish_waiting;
|
||||
|
||||
static std::atomic<u32> s_vi_ticks(CommandProcessor::m_cpClockOrigin);
|
||||
|
||||
Common::Flag s_gpuMaySleep;
|
||||
|
||||
volatile u32 VITicks = CommandProcessor::m_cpClockOrigin;
|
||||
|
||||
static bool IsOnThread()
|
||||
{
|
||||
return SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread;
|
||||
@ -71,10 +73,10 @@ void DoState(PointerWrap &p)
|
||||
p.Do(m_tokenReg);
|
||||
p.Do(fifo);
|
||||
|
||||
p.Do(interruptSet);
|
||||
p.Do(interruptWaiting);
|
||||
p.Do(interruptTokenWaiting);
|
||||
p.Do(interruptFinishWaiting);
|
||||
p.Do(s_interrupt_set);
|
||||
p.Do(s_interrupt_waiting);
|
||||
p.Do(s_interrupt_token_waiting);
|
||||
p.Do(s_interrupt_finish_waiting);
|
||||
}
|
||||
|
||||
static inline void WriteLow(volatile u32& _reg, u16 lowbits)
|
||||
@ -118,10 +120,10 @@ void Init()
|
||||
fifo.bFF_LoWatermark = 0;
|
||||
fifo.bFF_LoWatermarkInt = 0;
|
||||
|
||||
interruptSet = false;
|
||||
interruptWaiting = false;
|
||||
interruptFinishWaiting = false;
|
||||
interruptTokenWaiting = false;
|
||||
s_interrupt_set.store(false);
|
||||
s_interrupt_waiting.store(false);
|
||||
s_interrupt_finish_waiting.store(false);
|
||||
s_interrupt_token_waiting.store(false);
|
||||
|
||||
et_UpdateInterrupts = CoreTiming::RegisterEvent("CPInterrupt", UpdateInterrupts_Wrapper);
|
||||
}
|
||||
@ -358,18 +360,18 @@ void UpdateInterrupts(u64 userdata)
|
||||
{
|
||||
if (userdata)
|
||||
{
|
||||
interruptSet = true;
|
||||
s_interrupt_set.store(true);
|
||||
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
interruptSet = false;
|
||||
s_interrupt_set.store(false);
|
||||
INFO_LOG(COMMANDPROCESSOR,"Interrupt cleared");
|
||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, false);
|
||||
}
|
||||
CoreTiming::ForceExceptionCheck(0);
|
||||
interruptWaiting = false;
|
||||
s_interrupt_waiting.store(false);
|
||||
RunGpu();
|
||||
}
|
||||
|
||||
@ -379,6 +381,21 @@ void UpdateInterruptsFromVideoBackend(u64 userdata)
|
||||
CoreTiming::ScheduleEvent_Threadsafe(0, et_UpdateInterrupts, userdata);
|
||||
}
|
||||
|
||||
bool IsInterruptWaiting()
|
||||
{
|
||||
return s_interrupt_waiting.load();
|
||||
}
|
||||
|
||||
void SetInterruptTokenWaiting(bool waiting)
|
||||
{
|
||||
s_interrupt_token_waiting.store(waiting);
|
||||
}
|
||||
|
||||
void SetInterruptFinishWaiting(bool waiting)
|
||||
{
|
||||
s_interrupt_finish_waiting.store(waiting);
|
||||
}
|
||||
|
||||
void SetCPStatusFromGPU()
|
||||
{
|
||||
// breakpoint
|
||||
@ -416,7 +433,7 @@ void SetCPStatusFromGPU()
|
||||
|
||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||
|
||||
if (interrupt != interruptSet && !interruptWaiting)
|
||||
if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load())
|
||||
{
|
||||
u64 userdata = interrupt ? 1 : 0;
|
||||
if (IsOnThread())
|
||||
@ -424,7 +441,7 @@ void SetCPStatusFromGPU()
|
||||
if (!interrupt || bpInt || undfInt || ovfInt)
|
||||
{
|
||||
// Schedule the interrupt asynchronously
|
||||
interruptWaiting = true;
|
||||
s_interrupt_waiting.store(true);
|
||||
CommandProcessor::UpdateInterruptsFromVideoBackend(userdata);
|
||||
}
|
||||
}
|
||||
@ -447,14 +464,14 @@ void SetCPStatusFromCPU()
|
||||
|
||||
bool interrupt = (bpInt || ovfInt || undfInt) && m_CPCtrlReg.GPReadEnable;
|
||||
|
||||
if (interrupt != interruptSet && !interruptWaiting)
|
||||
if (interrupt != s_interrupt_set.load() && !s_interrupt_waiting.load())
|
||||
{
|
||||
u64 userdata = interrupt ? 1 : 0;
|
||||
if (IsOnThread())
|
||||
{
|
||||
if (!interrupt || bpInt || undfInt || ovfInt)
|
||||
{
|
||||
interruptSet = interrupt;
|
||||
s_interrupt_set.store(interrupt);
|
||||
INFO_LOG(COMMANDPROCESSOR,"Interrupt set");
|
||||
ProcessorInterface::SetInterrupt(INT_CAUSE_CP, interrupt);
|
||||
}
|
||||
@ -468,7 +485,7 @@ void SetCPStatusFromCPU()
|
||||
|
||||
void ProcessFifoEvents()
|
||||
{
|
||||
if (IsOnThread() && (interruptWaiting || interruptFinishWaiting || interruptTokenWaiting))
|
||||
if (IsOnThread() && (s_interrupt_waiting.load() || s_interrupt_finish_waiting.load() || s_interrupt_token_waiting.load()))
|
||||
CoreTiming::ProcessFifoWaitEvents();
|
||||
}
|
||||
|
||||
@ -533,12 +550,28 @@ void SetCpClearRegister()
|
||||
|
||||
void Update()
|
||||
{
|
||||
while (VITicks > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread())
|
||||
while (s_vi_ticks.load() > m_cpClockOrigin && fifo.isGpuReadingData && IsOnThread())
|
||||
Common::YieldCPU();
|
||||
|
||||
if (fifo.isGpuReadingData)
|
||||
Common::AtomicAdd(VITicks, SystemTimers::GetTicksPerSecond() / 10000);
|
||||
s_vi_ticks.fetch_add(SystemTimers::GetTicksPerSecond() / 10000);
|
||||
|
||||
RunGpu();
|
||||
}
|
||||
|
||||
u32 GetVITicks()
|
||||
{
|
||||
return s_vi_ticks.load();
|
||||
}
|
||||
|
||||
void SetVITicks(u32 ticks)
|
||||
{
|
||||
s_vi_ticks.store(ticks);
|
||||
}
|
||||
|
||||
void DecrementVITicks(u32 ticks)
|
||||
{
|
||||
s_vi_ticks.fetch_sub(ticks);
|
||||
}
|
||||
|
||||
} // end of namespace CommandProcessor
|
||||
|
Reference in New Issue
Block a user