From 3fa198f2082c06543a21b7bcc4e2a51bac47f582 Mon Sep 17 00:00:00 2001 From: Nolan Check Date: Thu, 30 Jul 2009 23:05:54 +0000 Subject: [PATCH] Work on atomic library. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3911 8ced0084-cf51-0410-be5f-012b33b47a6e --- Source/Core/Common/Src/Atomic_GCC.h | 12 ++++++++++-- Source/Core/Common/Src/Atomic_Win32.h | 18 ++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Source/Core/Common/Src/Atomic_GCC.h b/Source/Core/Common/Src/Atomic_GCC.h index 5eae99c63c..62a2ecfb6b 100644 --- a/Source/Core/Common/Src/Atomic_GCC.h +++ b/Source/Core/Common/Src/Atomic_GCC.h @@ -41,6 +41,10 @@ inline void AtomicAdd(volatile u32& target, u32 value) { __sync_add_and_fetch(&target, value); } +inline void AtomicAnd(volatile u32& target, u32 value) { + __sync_and_and_fetch(&target, value); +} + inline void AtomicIncrement(volatile u32& target) { __sync_add_and_fetch(&target, 1); } @@ -49,15 +53,19 @@ inline u32 AtomicLoad(volatile u32& src) { return src; // 32-bit reads are always atomic. } inline u32 AtomicLoadAcquire(volatile u32& src) { - __sync_synchronize(); + __sync_synchronize(); // TODO: May not be necessary. return src; } +inline void AtomicOr(volatile u32& target, u32 value) { + __sync_or_and_fetch(&target, value); +} + inline void AtomicStore(volatile u32& dest, u32 value) { dest = value; // 32-bit writes are always atomic. } inline void AtomicStoreRelease(volatile u32& dest, u32 value) { - __sync_lock_test_and_set(&dest, value); + __sync_lock_test_and_set(&dest, value); // TODO: Wrong! This function is has acquire semantics. } } diff --git a/Source/Core/Common/Src/Atomic_Win32.h b/Source/Core/Common/Src/Atomic_Win32.h index 658603fa3b..b9e3197881 100644 --- a/Source/Core/Common/Src/Atomic_Win32.h +++ b/Source/Core/Common/Src/Atomic_Win32.h @@ -19,6 +19,7 @@ #define _ATOMIC_WIN32_H_ #include "Common.h" +#include #include // Atomic operations are performed in a single step by the CPU. It is @@ -46,6 +47,10 @@ inline void AtomicAdd(volatile u32& target, u32 value) { InterlockedExchangeAdd((volatile LONG*)&target, (LONG)value); } +inline void AtomicAnd(volatile u32& target, u32 value) { + InterlockedAnd((volatile LONG*)&target, (LONG)value); +} + inline void AtomicIncrement(volatile u32& target) { InterlockedIncrement((volatile LONG*)&target); } @@ -54,16 +59,21 @@ inline u32 AtomicLoad(volatile u32& src) { return src; // 32-bit reads are always atomic. } inline u32 AtomicLoadAcquire(volatile u32& src) { - MemoryBarrier(); - return src; // 32-bit reads are always atomic. + u32 result = src; // 32-bit reads are always atomic. + _ReadBarrier(); // Compiler instruction only. x86 loads always have acquire semantics. + return result; +} + +inline void AtomicOr(volatile u32& target, u32 value) { + InterlockedOr((volatile LONG*)&target, (LONG)value); } inline void AtomicStore(volatile u32& dest, u32 value) { dest = value; // 32-bit writes are always atomic. } inline void AtomicStoreRelease(volatile u32& dest, u32 value) { - // InterlockedExchange includes a memory barrier as a bonus. - InterlockedExchange((volatile LONG*)&dest, (LONG)value); + _WriteBarrier(); // Compiler instruction only. x86 stores always have release semantics. + dest = value; // 32-bit writes are always atomic. } }