diff --git a/Source/Core/Common/Src/Thread.cpp b/Source/Core/Common/Src/Thread.cpp index 716f79ff55..df7c8d50d9 100644 --- a/Source/Core/Common/Src/Thread.cpp +++ b/Source/Core/Common/Src/Thread.cpp @@ -344,6 +344,17 @@ void Event::Wait() is_set_ = false; pthread_mutex_unlock(&mutex_); } + +int InterlockedExchangeAdd( int* Addend, int Increment ) +{ + +#if defined(__GNUC__) && defined (__GNUC_MINOR__) && ((4 < __GNUC__) || (4 == __GNUC__ && 1 <= __GNUC_MINOR__)) + return __sync_add_and_fetch(Addend, Increment); +#else + // TODO support old gcc +#endif +} + #endif diff --git a/Source/Core/Common/Src/Thread.h b/Source/Core/Common/Src/Thread.h index 9e351bc839..3cc608f335 100644 --- a/Source/Core/Common/Src/Thread.h +++ b/Source/Core/Common/Src/Thread.h @@ -113,6 +113,9 @@ class Event void SleepCurrentThread(int ms); void SetCurrentThreadName(const char* name); + +int InterlockedExchangeAdd( int* Addend, int Increment ); } // end of namespace Common + #endif diff --git a/Source/Core/Core/Src/HW/CommandProcessor.cpp b/Source/Core/Core/Src/HW/CommandProcessor.cpp index f9af5f798b..db2a7959de 100644 --- a/Source/Core/Core/Src/HW/CommandProcessor.cpp +++ b/Source/Core/Core/Src/HW/CommandProcessor.cpp @@ -378,10 +378,8 @@ void GatherPipeBursted() Common::SleepCurrentThread(1); #ifdef _WIN32 InterlockedExchangeAdd((LONG*)&fifo.CPReadWriteDistance, GPFifo::GATHER_PIPE_SIZE); -#else - fifo.sync->Enter(); - fifo.CPReadWriteDistance += GPFifo::GATHER_PIPE_SIZE; - fifo.sync->Leave(); +#else + Common::InterlockedExchangeAdd((int*)&fifo.CPReadWriteDistance, GPFifo::GATHER_PIPE_SIZE); #endif // check if we are in sync diff --git a/Source/Core/VideoCommon/Src/Fifo.cpp b/Source/Core/VideoCommon/Src/Fifo.cpp index dfa770ea8e..7e0cc6abd3 100644 --- a/Source/Core/VideoCommon/Src/Fifo.cpp +++ b/Source/Core/VideoCommon/Src/Fifo.cpp @@ -217,12 +217,13 @@ void Fifo_EnterLoop(const SVideoInitialize &video_initialize) #endif _fifo.CPReadPointer += 32; Video_SendFifoData(uData); + #ifdef _WIN32 InterlockedExchangeAdd((LONG*)&_fifo.CPReadWriteDistance, -32); LeaveCriticalSection(&_fifo.sync); #else - _fifo.CPReadWriteDistance -= 32; - _fifo.sync->Leave(); + Common::InterlockedExchangeAdd((int*)&_fifo.CPReadWriteDistance, -32); + _fifo.sync->Leave(); #endif // increase the ReadPtr if (_fifo.CPReadPointer >= _fifo.CPEnd)