1
0
Fork 0
mirror of https://github.com/juce-framework/JUCE.git synced 2026-01-10 23:44:24 +00:00

Fix for mac compareAndSwap().

This commit is contained in:
Julian Storer 2010-04-17 17:01:16 +01:00
parent a612dfdc2f
commit 2415dd0d85
2 changed files with 66 additions and 32 deletions

View file

@ -3135,14 +3135,43 @@ private:
Atomic& operator= (const Atomic&);
};
#if (JUCE_MAC || JUCE_IPHONE) // Mac and iPhone...
// If we've got gcc4.2 or later, we can use its atomic intrinsics...
#if JUCE_GCC && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
}
#elif (JUCE_MAC || JUCE_IPHONE) // Older Mac builds using gcc4.0 or earlier...
inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)); }
{
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
{
if (OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)))
return oldValue;
const uint32 result = destination;
if (result != oldValue)
return result;
}
}
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
@ -3155,7 +3184,7 @@ private:
return currentVal;
}
#elif JUCE_LINUX // Linux...
#elif JUCE_LINUX // Linux with compilers other than gcc4.2 or later...
#if __INTEL_COMPILER
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); }
@ -3175,19 +3204,7 @@ private:
}
#else
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
}
#error "Linux build requires gcc4.2 or later for atomic operations"
#endif
#elif JUCE_USE_INTRINSICS // Windows...

View file

@ -62,14 +62,43 @@ private:
//==============================================================================
#if (JUCE_MAC || JUCE_IPHONE) // Mac and iPhone...
// If we've got gcc4.2 or later, we can use its atomic intrinsics...
#if JUCE_GCC && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2))
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
}
#elif (JUCE_MAC || JUCE_IPHONE) // Older Mac builds using gcc4.0 or earlier...
inline void Atomic::increment (int32& variable) { OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return OSAtomicIncrement32 (static_cast <int32_t*> (&variable)); }
inline void Atomic::decrement (int32& variable) { OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return OSAtomicDecrement32 (static_cast <int32_t*> (&variable)); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)); }
{
for (;;) // Annoying workaround for OSX only having a bool CAS operation..
{
if (OSAtomicCompareAndSwap32Barrier (oldValue, newValue, static_cast <int32_t*> (&destination)))
return oldValue;
const uint32 result = destination;
if (result != oldValue)
return result;
}
}
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
@ -83,7 +112,7 @@ private:
}
//==============================================================================
#elif JUCE_LINUX // Linux...
#elif JUCE_LINUX // Linux with compilers other than gcc4.2 or later...
#if __INTEL_COMPILER
inline void Atomic::increment (int32& variable) { _InterlockedIncrement (&variable); }
@ -103,19 +132,7 @@ private:
}
#else
inline void Atomic::increment (int32& variable) { __sync_add_and_fetch (&variable, 1); }
inline int32 Atomic::incrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, 1); }
inline void Atomic::decrement (int32& variable) { __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::decrementAndReturn (int32& variable) { return __sync_add_and_fetch (&variable, -1); }
inline int32 Atomic::compareAndExchange (int32& destination, int32 newValue, int32 oldValue)
{ return __sync_val_compare_and_swap (&destination, oldValue, newValue); }
inline void* Atomic::swapPointers (void* volatile* value1, void* value2)
{
void* currentVal = *value1;
while (! __sync_bool_compare_and_swap (value1, currentVal, value2)) { currentVal = *value1; }
return currentVal;
}
#error "Linux build requires gcc4.2 or later for atomic operations"
#endif
//==============================================================================