29 #ifndef JUCE_ATOMIC_H_INCLUDED
30 #define JUCE_ATOMIC_H_INCLUDED
40 template <
typename Type>
52 :
value (initialValue)
94 Type operator--() noexcept;
156 template <
typename Dest,
typename Source>
157 static inline Dest castTo (Source value) noexcept {
union { Dest d; Source s; } u; u.s =
value;
return u.d; }
159 static inline Type castFrom32Bit (
int32 value) noexcept {
return castTo <Type, int32> (
value); }
160 static inline Type castFrom64Bit (
int64 value) noexcept {
return castTo <Type, int64> (
value); }
161 static inline int32 castTo32Bit (Type value) noexcept {
return castTo <int32, Type> (
value); }
162 static inline int64 castTo64Bit (Type value) noexcept {
return castTo <int64, Type> (
value); }
168 template <
typename ValueType>
169 inline ValueType negateValue (ValueType n) noexcept
171 return sizeof (ValueType) == 1 ? (ValueType) -(
signed char) n
172 : (
sizeof (ValueType) == 2 ? (ValueType) -(
short) n
173 : (
sizeof (ValueType) == 4 ? (ValueType) -(
int) n
174 : ((ValueType) -(
int64) n)));
178 template <
typename Po
interType>
179 inline PointerType* negateValue (PointerType* n) noexcept
181 return reinterpret_cast <PointerType*> (-reinterpret_cast <
pointer_sized_int> (n));
190 #if JUCE_MAC && (JUCE_PPC || __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 2))
191 #define JUCE_ATOMICS_MAC_LEGACY 1 // Older OSX builds using gcc4.1 or earlier
193 #if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5
194 #define JUCE_MAC_ATOMICS_VOLATILE
196 #define JUCE_MAC_ATOMICS_VOLATILE volatile
201 template <
typename Type>
static Type OSAtomicAdd64Barrier (Type
b, JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept {
jassertfalse;
return *a +=
b; }
202 template <
typename Type>
static Type OSAtomicIncrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept {
jassertfalse;
return ++*a; }
203 template <
typename Type>
static Type OSAtomicDecrement64Barrier (JUCE_MAC_ATOMICS_VOLATILE Type* a) noexcept {
jassertfalse;
return --*a; }
204 template <
typename Type>
static bool OSAtomicCompareAndSwap64Barrier (Type old, Type newValue, JUCE_MAC_ATOMICS_VOLATILE Type* value) noexcept
205 {
jassertfalse;
if (old == *value) { *value = newValue;
return true; }
return false; }
206 #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1
210 #elif JUCE_GCC || JUCE_CLANG
211 #define JUCE_ATOMICS_GCC 1 // GCC with intrinsics
213 #if JUCE_IOS || JUCE_ANDROID // (64-bit ops will compile but not link on these mobile OSes)
214 #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1
219 #define JUCE_ATOMICS_WINDOWS 1 // Windows with intrinsics
221 #if JUCE_USE_MSVC_INTRINSICS
222 #ifndef __INTEL_COMPILER
223 #pragma intrinsic (_InterlockedExchange, _InterlockedIncrement, _InterlockedDecrement, _InterlockedCompareExchange, \
224 _InterlockedCompareExchange64, _InterlockedExchangeAdd, _ReadWriteBarrier)
226 #define juce_InterlockedExchange(a, b) _InterlockedExchange(a, b)
227 #define juce_InterlockedIncrement(a) _InterlockedIncrement(a)
228 #define juce_InterlockedDecrement(a) _InterlockedDecrement(a)
229 #define juce_InterlockedExchangeAdd(a, b) _InterlockedExchangeAdd(a, b)
230 #define juce_InterlockedCompareExchange(a, b, c) _InterlockedCompareExchange(a, b, c)
231 #define juce_InterlockedCompareExchange64(a, b, c) _InterlockedCompareExchange64(a, b, c)
232 #define juce_MemoryBarrier _ReadWriteBarrier
244 #ifndef __INTEL_COMPILER
245 #pragma intrinsic (_InterlockedExchangeAdd64, _InterlockedExchange64, _InterlockedIncrement64, _InterlockedDecrement64)
247 #define juce_InterlockedExchangeAdd64(a, b) _InterlockedExchangeAdd64(a, b)
248 #define juce_InterlockedExchange64(a, b) _InterlockedExchange64(a, b)
249 #define juce_InterlockedIncrement64(a) _InterlockedIncrement64(a)
250 #define juce_InterlockedDecrement64(a) _InterlockedDecrement64(a)
253 template <
typename Type>
static Type juce_InterlockedExchangeAdd64 (
volatile Type* a, Type
b) noexcept {
jassertfalse; Type old = *a; *a +=
b;
return old; }
254 template <
typename Type>
static Type juce_InterlockedExchange64 (
volatile Type* a, Type
b) noexcept {
jassertfalse; Type old = *a; *a =
b;
return old; }
255 template <
typename Type>
static Type juce_InterlockedIncrement64 (
volatile Type* a) noexcept {
jassertfalse;
return ++*a; }
256 template <
typename Type>
static Type juce_InterlockedDecrement64 (
volatile Type* a) noexcept {
jassertfalse;
return --*a; }
257 #define JUCE_64BIT_ATOMICS_UNAVAILABLE 1
263 #pragma warning (push)
264 #pragma warning (disable: 4311) // (truncation warning)
268 template <
typename Type>
271 #if JUCE_ATOMICS_MAC_LEGACY
272 return sizeof (Type) == 4 ? castFrom32Bit ((
int32) OSAtomicAdd32Barrier ((int32_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value))
273 : castFrom64Bit ((
int64) OSAtomicAdd64Barrier ((int64_t) 0, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value));
274 #elif JUCE_ATOMICS_WINDOWS
276 : castFrom64Bit ((
int64) juce_InterlockedExchangeAdd64 ((
volatile __int64*) &value, (__int64) 0));
277 #elif JUCE_ATOMICS_GCC
278 return sizeof (Type) == 4 ? castFrom32Bit ((
int32) __sync_add_and_fetch ((
volatile int32*) &value, 0))
279 : castFrom64Bit ((
int64) __sync_add_and_fetch ((
volatile int64*) &value, 0));
283 template <
typename Type>
286 #if JUCE_ATOMICS_MAC_LEGACY || JUCE_ATOMICS_GCC
287 Type currentVal = value;
288 while (! compareAndSetBool (newValue, currentVal)) { currentVal = value; }
290 #elif JUCE_ATOMICS_WINDOWS
292 : castFrom64Bit ((
int64) juce_InterlockedExchange64 ((
volatile __int64*) &value, (__int64) castTo64Bit (newValue)));
296 template <
typename Type>
299 #if JUCE_ATOMICS_MAC_LEGACY
300 return sizeof (Type) == 4 ? (Type) OSAtomicAdd32Barrier ((int32_t) castTo32Bit (amountToAdd), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
301 : (Type) OSAtomicAdd64Barrier ((int64_t) amountToAdd, (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
302 #elif JUCE_ATOMICS_WINDOWS
303 return sizeof (Type) == 4 ? (Type) (
juce_InterlockedExchangeAdd ((
volatile long*) &value, (
long) amountToAdd) + (long) amountToAdd)
304 : (Type) (juce_InterlockedExchangeAdd64 ((
volatile __int64*) &value, (__int64) amountToAdd) + (__int64) amountToAdd);
305 #elif JUCE_ATOMICS_GCC
306 return (Type) __sync_add_and_fetch (&value, amountToAdd);
310 template <
typename Type>
313 return operator+= (negateValue (amountToSubtract));
316 template <
typename Type>
319 #if JUCE_ATOMICS_MAC_LEGACY
320 return sizeof (Type) == 4 ? (Type) OSAtomicIncrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
321 : (Type) OSAtomicIncrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
322 #elif JUCE_ATOMICS_WINDOWS
324 : (Type) juce_InterlockedIncrement64 ((
volatile __int64*) &value);
325 #elif JUCE_ATOMICS_GCC
326 return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) 1)
327 : (Type) __sync_add_and_fetch ((int64_t*) &value, 1);
331 template <
typename Type>
334 #if JUCE_ATOMICS_MAC_LEGACY
335 return sizeof (Type) == 4 ? (Type) OSAtomicDecrement32Barrier ((JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
336 : (Type) OSAtomicDecrement64Barrier ((JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
337 #elif JUCE_ATOMICS_WINDOWS
339 : (Type) juce_InterlockedDecrement64 ((
volatile __int64*) &value);
340 #elif JUCE_ATOMICS_GCC
341 return sizeof (Type) == 4 ? (Type) __sync_add_and_fetch (&value, (Type) -1)
342 : (Type) __sync_add_and_fetch ((int64_t*) &value, -1);
346 template <
typename Type>
349 #if JUCE_ATOMICS_MAC_LEGACY
350 return sizeof (Type) == 4 ? OSAtomicCompareAndSwap32Barrier ((int32_t) castTo32Bit (valueToCompare), (int32_t) castTo32Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int32_t*) &value)
351 : OSAtomicCompareAndSwap64Barrier ((int64_t) castTo64Bit (valueToCompare), (int64_t) castTo64Bit (newValue), (JUCE_MAC_ATOMICS_VOLATILE int64_t*) &value);
352 #elif JUCE_ATOMICS_WINDOWS
353 return compareAndSetValue (newValue, valueToCompare) == valueToCompare;
354 #elif JUCE_ATOMICS_GCC
355 return sizeof (Type) == 4 ? __sync_bool_compare_and_swap ((
volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue))
356 : __sync_bool_compare_and_swap ((
volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue));
360 template <
typename Type>
363 #if JUCE_ATOMICS_MAC_LEGACY
366 if (compareAndSetBool (newValue, valueToCompare))
367 return valueToCompare;
369 const Type result = value;
370 if (result != valueToCompare)
374 #elif JUCE_ATOMICS_WINDOWS
375 return sizeof (Type) == 4 ? castFrom32Bit ((
int32)
juce_InterlockedCompareExchange ((
volatile long*) &value, (
long) castTo32Bit (newValue), (
long) castTo32Bit (valueToCompare)))
377 #elif JUCE_ATOMICS_GCC
378 return sizeof (Type) == 4 ? castFrom32Bit ((
int32) __sync_val_compare_and_swap ((
volatile int32*) &value, castTo32Bit (valueToCompare), castTo32Bit (newValue)))
379 : castFrom64Bit ((
int64) __sync_val_compare_and_swap ((
volatile int64*) &value, castTo64Bit (valueToCompare), castTo64Bit (newValue)));
383 template <
typename Type>
386 #if JUCE_ATOMICS_MAC_LEGACY
388 #elif JUCE_ATOMICS_GCC
389 __sync_synchronize();
390 #elif JUCE_ATOMICS_WINDOWS
396 #pragma warning (pop)
399 #endif // JUCE_ATOMIC_H_INCLUDED
static void memoryBarrier() noexcept
Definition: juce_Atomic.h:384
Atomic(const Atomic &other) noexcept
Definition: juce_Atomic.h:57
__int64 juce_InterlockedCompareExchange64(volatile __int64 *a, __int64 b, __int64 c) noexcept
Definition: juce_win32_Threads.cpp:48
Atomic() noexcept
Definition: juce_Atomic.h:45
Type get() const noexcept
Definition: juce_Atomic.h:269
#define noexcept
Definition: juce_CompilerSupport.h:141
Definition: juce_Atomic.h:41
void set(Type newValue) noexcept
Definition: juce_Atomic.h:79
TOUCHINPUT int
Definition: juce_win32_Windowing.cpp:123
long b
Definition: jpegint.h:371
Type exchange(Type value) noexcept
Definition: juce_Atomic.h:284
Type operator--() noexcept
Definition: juce_Atomic.h:332
void juce_MemoryBarrier() noexcept
Definition: juce_Atomic.h:240
Type operator-=(Type amountToSubtract) noexcept
Definition: juce_Atomic.h:311
long juce_InterlockedExchangeAdd(volatile long *a, long b) noexcept
Definition: juce_win32_Threads.cpp:45
long juce_InterlockedIncrement(volatile long *a) noexcept
Definition: juce_win32_Threads.cpp:43
volatile Type value
Definition: juce_Atomic.h:153
long long int64
Definition: juce_MathsFunctions.h:60
long juce_InterlockedDecrement(volatile long *a) noexcept
Definition: juce_win32_Threads.cpp:44
Type operator++() noexcept
Definition: juce_Atomic.h:317
bool compareAndSetBool(Type newValue, Type valueToCompare) noexcept
Definition: juce_Atomic.h:347
Type operator+=(Type amountToAdd) noexcept
Definition: juce_Atomic.h:297
~Atomic() noexcept
Definition: juce_Atomic.h:63
long juce_InterlockedExchange(volatile long *a, long b) noexcept
Definition: juce_win32_Threads.cpp:42
long juce_InterlockedCompareExchange(volatile long *a, long b, long c) noexcept
Definition: juce_win32_Threads.cpp:46
Atomic & operator=(const Atomic &other) noexcept
Definition: juce_Atomic.h:73
Atomic(const Type initialValue) noexcept
Definition: juce_Atomic.h:51
Type compareAndSetValue(Type newValue, Type valueToCompare) noexcept
Definition: juce_Atomic.h:361
signed int int32
Definition: juce_MathsFunctions.h:49