1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
#ifndef _ATOMIC_INT_APPLE_H
#define _ATOMIC_INT_APPLE_H
#include <libkern/OSAtomic.h>
//http://developer.apple.com/library/mac/#documentation/Darwin/Reference/KernelIOKitFramework/OSAtomic_h/index.html
namespace mt{
class atomicInt
{
private:
volatile int _q_value;
public:
atomicInt()
{
_q_value = 0;
}
atomicInt( int value )
{
_q_value = value;
}
// atomic API
/**
Reads the current value of this QAtomicInt and then adds valueToAdd
to the current value, returning the original value.
Unfortunately, MacOSX does not provide with fetch-and-add functions,
only add-and-fetch. Therefore, we have to simulate them.
Implementation based on SDL:
//http://lists.libsdl.org/pipermail/commits-libsdl.org/2011-January/003568.html
*/
inline int fetchAndAddAcquire( int valueToAdd )
{
//T *originalValue = currentValue;
//currentValue += valueToAdd;
//return originalValue;
int originalValue;
do {
originalValue = _q_value;
} while (!OSAtomicCompareAndSwap32Barrier(originalValue, originalValue+valueToAdd, &_q_value));
return originalValue;
}
/**
Atomically increments the value of this atomicInt.
Returns true if the new value is non-zero, false otherwise.*/
inline bool ref()
{
return OSAtomicIncrement32Barrier(&_q_value) != 0;
}
/*
Atomically decrements the value of this QAtomicInt.
Returns true if the new value is non-zero, false otherwise.*/
inline bool deref()
{
return OSAtomicDecrement32Barrier(&_q_value) != 0;
}
/*
If the current _q_value of this QAtomicInt is the expectedValue,
the test-and-set functions assign the newValue to this QAtomicInt
and return true. If the values are not the same, this function
does nothing and returns false.
*/
inline bool testAndSetOrdered(int expectedValue, int newValue)
{
//if (currentValue == expectedValue) {
// currentValue = newValue;
// return true;
// }
//return false;
return OSAtomicCompareAndSwap32Barrier(expectedValue, newValue, &_q_value);
}
// Non-atomic API
inline bool operator==(int value) const
{
return _q_value == value;
}
inline bool operator!=(int value) const
{
return _q_value != value;
}
inline bool operator!() const
{
return _q_value == 0;
}
inline operator int() const
{
return _q_value;
}
inline atomicInt &operator=(int value)
{
_q_value = value;
return *this;
}
inline bool operator>(int value) const
{
return _q_value > value;
}
inline bool operator<(int value) const
{
return _q_value < value;
}
};
}//namespace
#endif
|