summaryrefslogtreecommitdiff
path: root/Source/Core/VideoCommon
diff options
context:
space:
mode:
authorLioncash <mathew1800@gmail.com>2015-05-27 03:08:48 -0400
committerLioncash <mathew1800@gmail.com>2015-05-27 03:53:29 -0400
commit1ba3b4e7ac9d53710454c46ac5384ee44a096b70 (patch)
tree272b191ed1fbddfd113af6e6b19b9c5173a4c954 /Source/Core/VideoCommon
parent1c2d4e5d42f173c60499f1c173b7ba4a70033128 (diff)
CommandProcessor: Replace volatile usages with atomics
Also remove said variables from being globals.
Diffstat (limited to 'Source/Core/VideoCommon')
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.cpp81
-rw-r--r--Source/Core/VideoCommon/CommandProcessor.h14
-rw-r--r--Source/Core/VideoCommon/Fifo.cpp12
-rw-r--r--Source/Core/VideoCommon/PixelEngine.cpp11
4 files changed, 78 insertions, 40 deletions
diff --git a/Source/Core/VideoCommon/CommandProcessor.cpp b/Source/Core/VideoCommon/CommandProcessor.cpp
index f682abdeee..449e99982f 100644
--- a/Source/Core/VideoCommon/CommandProcessor.cpp
+++ b/Source/Core/VideoCommon/CommandProcessor.cpp
@@ -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,14 +42,14 @@ 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;
-Common::Flag s_gpuMaySleep;
+static std::atomic<u32> s_vi_ticks(CommandProcessor::m_cpClockOrigin);
-volatile u32 VITicks = CommandProcessor::m_cpClockOrigin;
+Common::Flag s_gpuMaySleep;
static bool IsOnThread()
{
@@ -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
diff --git a/Source/Core/VideoCommon/CommandProcessor.h b/Source/Core/VideoCommon/CommandProcessor.h
index 5c49f0bb69..0b33150ce4 100644
--- a/Source/Core/VideoCommon/CommandProcessor.h
+++ b/Source/Core/VideoCommon/CommandProcessor.h
@@ -17,11 +17,6 @@ namespace CommandProcessor
{
extern SCPFifoStruct fifo; //This one is shared between gfx thread and emulator thread.
-
-extern volatile bool interruptSet;
-extern volatile bool interruptWaiting;
-extern volatile bool interruptTokenWaiting;
-extern volatile bool interruptFinishWaiting;
extern Common::Flag s_gpuMaySleep;
// internal hardware addresses
@@ -143,12 +138,19 @@ void GatherPipeBursted();
void UpdateInterrupts(u64 userdata);
void UpdateInterruptsFromVideoBackend(u64 userdata);
+bool IsInterruptWaiting();
+void SetInterruptTokenWaiting(bool waiting);
+void SetInterruptFinishWaiting(bool waiting);
+
void SetCpClearRegister();
void SetCpControlRegister();
void SetCpStatusRegister();
void ProcessFifoEvents();
void Update();
-extern volatile u32 VITicks;
+
+u32 GetVITicks();
+void SetVITicks(u32 ticks);
+void DecrementVITicks(u32 ticks);
} // namespace CommandProcessor
diff --git a/Source/Core/VideoCommon/Fifo.cpp b/Source/Core/VideoCommon/Fifo.cpp
index 1b556cca58..289a62d8e7 100644
--- a/Source/Core/VideoCommon/Fifo.cpp
+++ b/Source/Core/VideoCommon/Fifo.cpp
@@ -103,7 +103,7 @@ void Fifo_Init()
s_video_buffer = (u8*)AllocateMemoryPages(FIFO_SIZE + 4);
ResetVideoBuffer();
s_gpu_running_state.store(false);
- Common::AtomicStore(CommandProcessor::VITicks, CommandProcessor::m_cpClockOrigin);
+ CommandProcessor::SetVITicks(CommandProcessor::m_cpClockOrigin);
}
void Fifo_Shutdown()
@@ -321,17 +321,17 @@ void RunGpuLoop()
if (!fifo.isGpuReadingData)
{
- Common::AtomicStore(CommandProcessor::VITicks, CommandProcessor::m_cpClockOrigin);
+ CommandProcessor::SetVITicks(CommandProcessor::m_cpClockOrigin);
}
bool run_loop = true;
// check if we are able to run this buffer
- while (run_loop && !CommandProcessor::interruptWaiting && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
+ while (run_loop && !CommandProcessor::IsInterruptWaiting() && fifo.bFF_GPReadEnable && fifo.CPReadWriteDistance && !AtBreakpoint())
{
fifo.isGpuReadingData = true;
- if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU || Common::AtomicLoad(CommandProcessor::VITicks) > CommandProcessor::m_cpClockOrigin)
+ if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU || CommandProcessor::GetVITicks() > CommandProcessor::m_cpClockOrigin)
{
u32 readPtr = fifo.CPReadPointer;
ReadDataFromFifo(readPtr);
@@ -349,8 +349,8 @@ void RunGpuLoop()
s_video_buffer_read_ptr = OpcodeDecoder_Run(DataReader(s_video_buffer_read_ptr, write_ptr), &cyclesExecuted, false);
- if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU && Common::AtomicLoad(CommandProcessor::VITicks) >= cyclesExecuted)
- Common::AtomicAdd(CommandProcessor::VITicks, -(s32)cyclesExecuted);
+ if (SConfig::GetInstance().m_LocalCoreStartupParameter.bSyncGPU && CommandProcessor::GetVITicks() >= cyclesExecuted)
+ CommandProcessor::DecrementVITicks(cyclesExecuted);
Common::AtomicStore(fifo.CPReadPointer, readPtr);
Common::AtomicAdd(fifo.CPReadWriteDistance, -32);
diff --git a/Source/Core/VideoCommon/PixelEngine.cpp b/Source/Core/VideoCommon/PixelEngine.cpp
index 9b2c48876b..45db963d23 100644
--- a/Source/Core/VideoCommon/PixelEngine.cpp
+++ b/Source/Core/VideoCommon/PixelEngine.cpp
@@ -274,14 +274,14 @@ void SetToken_OnMainThread(u64 userdata, int cyclesLate)
s_signal_token_interrupt.store(1);
UpdateInterrupts();
}
- CommandProcessor::interruptTokenWaiting = false;
+ CommandProcessor::SetInterruptTokenWaiting(false);
}
void SetFinish_OnMainThread(u64 userdata, int cyclesLate)
{
s_signal_finish_interrupt.store(1);
UpdateInterrupts();
- CommandProcessor::interruptFinishWaiting = false;
+ CommandProcessor::SetInterruptFinishWaiting(false);
}
// SetToken
@@ -293,7 +293,8 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
s_signal_token_interrupt.store(1);
}
- CommandProcessor::interruptTokenWaiting = true;
+ CommandProcessor::SetInterruptTokenWaiting(true);
+
if (!SConfig::GetInstance().m_LocalCoreStartupParameter.bCPUThread || g_use_deterministic_gpu_thread)
CoreTiming::ScheduleEvent(0, et_SetTokenOnMainThread, _token | (_bSetTokenAcknowledge << 16));
else
@@ -304,11 +305,13 @@ void SetToken(const u16 _token, const int _bSetTokenAcknowledge)
// THIS IS EXECUTED FROM VIDEO THREAD (BPStructs.cpp) when a new frame has been drawn
void SetFinish()
{
- CommandProcessor::interruptFinishWaiting = true;
+ CommandProcessor::SetInterruptFinishWaiting(true);
+
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");
}