Improved the generic atomic int classes. Added atomic_int_generic.h, which should work everywhere but relies on mutexes.

This commit is contained in:
Paolo Cignoni 2011-12-14 19:20:40 +00:00
parent e1c9f212da
commit 1dc98465ae
3 changed files with 163 additions and 30 deletions

View File

@ -1,16 +1,35 @@
#include "../platform.h" #ifndef _ATOMIC_INT_H
#define _ATOMIC_INT_H
#ifndef GC_ATOMIC_INT_H
#define GC_ATOMIC_INT_H
#ifdef QT_CORE_LIB #ifdef QT_CORE_LIB
#include <QAtomicInt>
namespace mt{
typedef QAtomicInt atomicInt;
}
#include <QAtomicInt> #elif defined(__APPLE__)
typedef QAtomicInt GAtomincInt; # include "atomic_int_apple.h"
#elif defined(__GC_APPLE__) ??
# include "GCAtomicInt_apple.h" //generic implementation using mutexes
#else
# include "atomic_int_generic.h"
#endif #endif
/*
#elif defined(_WIN32)
# include "atomic_int_win32.h"
#endif #endif
#elif defined(__linux__)
# include "atomic_int_linux.h"
#endif
*/
/*
__linux__
__unix__
__posix__
*/
#endif // _ATOMIC_INT_H

View File

@ -1,22 +1,24 @@
#ifndef GC_ATOMIC_INT_APPLE_H #ifndef _ATOMIC_INT_APPLE_H
#define GC_ATOMIC_INT_APPLE_H #define _ATOMIC_INT_APPLE_H
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
//http://developer.apple.com/library/mac/#documentation/Darwin/Reference/KernelIOKitFramework/OSAtomic_h/index.html //http://developer.apple.com/library/mac/#documentation/Darwin/Reference/KernelIOKitFramework/OSAtomic_h/index.html
class GCAtomicInt namespace mt{
class atomicInt
{ {
public: public:
GCAtomicInt() atomicInt()
{ {
_q_value = 0; value = 0;
} }
GCAtomicInt( int value ) atomicInt( int value )
{ {
_q_value = value; value = value;
} }
// atomic API // atomic API
@ -39,17 +41,17 @@ public:
int originalValue; int originalValue;
do { do {
originalValue = _q_value; originalValue = value;
} while (!OSAtomicCompareAndSwap32Barrier(originalValue, originalValue+valueToAdd, &_q_value)); } while (!OSAtomicCompareAndSwap32Barrier(originalValue, originalValue+valueToAdd, &value));
return originalValue; return originalValue;
} }
/** /**
Atomically increments the value of this GCAtomicInt. Atomically increments the value of this atomicInt.
Returns true if the new value is non-zero, false otherwise.*/ Returns true if the new value is non-zero, false otherwise.*/
inline bool ref() inline bool ref()
{ {
return OSAtomicIncrement32Barrier(&_q_value) != 0; return OSAtomicIncrement32Barrier(&value) != 0;
} }
/* /*
@ -57,7 +59,7 @@ public:
Returns true if the new value is non-zero, false otherwise.*/ Returns true if the new value is non-zero, false otherwise.*/
inline bool deref() inline bool deref()
{ {
return OSAtomicDecrement32Barrier(&_q_value) != 0; return OSAtomicDecrement32Barrier(&value) != 0;
} }
inline bool testAndSetOrdered(int expectedValue, int newValue) inline bool testAndSetOrdered(int expectedValue, int newValue)
@ -68,51 +70,52 @@ public:
// } // }
//return false; //return false;
return OSAtomicCompareAndSwap32Barrier(expectedValue, newValue, &_q_value); return OSAtomicCompareAndSwap32Barrier(expectedValue, newValue, &value);
} }
// Non-atomic API // Non-atomic API
inline bool operator==(int value) const inline bool operator==(int value) const
{ {
return _q_value == value; return value == value;
} }
inline bool operator!=(int value) const inline bool operator!=(int value) const
{ {
return _q_value != value; return value != value;
} }
inline bool operator!() const inline bool operator!() const
{ {
return _q_value == 0; return value == 0;
} }
inline operator int() const inline operator int() const
{ {
return _q_value; return value;
} }
inline GCAtomicInt &operator=(int value) inline atomicInt &operator=(int value)
{ {
_q_value = value; value = value;
return *this; return *this;
} }
inline bool operator>(int value) const inline bool operator>(int value) const
{ {
return _q_value > value; return value > value;
} }
inline bool operator<(int value) const inline bool operator<(int value) const
{ {
return _q_value < value; return value < value;
} }
private: private:
volatile int _q_value; volatile int value;
}; };
}//namespace
#endif #endif

View File

@ -0,0 +1,111 @@
#ifndef _ATOMIC_INT_GENERIC_H
#define _ATOMIC_INT_GENERIC_H
#include "mt.h"
namespace mt{
class atomicInt
{
public:
atomicInt()
{
value = 0;
}
atomicInt( int value )
{
value = value;
}
// atomic API
/**
Reads the current value of this QAtomicInt and then adds valueToAdd
to the current value, returning the original value.
*/
inline int fetchAndAddAcquire( int valueToAdd )
{
mutexlocker lock(m);
int originalValue = value;
value += valueToAdd;
return originalValue;
}
/**
Atomically increments the value of this atomicInt.
Returns true if the new value is non-zero, false otherwise.*/
inline bool ref()
{
mutexlocker lock(m);
value++;
return value == 0;
}
/*
Atomically decrements the value of this QAtomicInt.
Returns true if the new value is non-zero, false otherwise.*/
inline bool deref()
{
mutexlocker lock(m);
value--;
return value == 0;
}
inline bool testAndSetOrdered(int expectedValue, int newValue)
{
mutexlocker lock(m);
if (value == expectedValue) {
value = newValue;
return true;
}
return false;
}
// Non-atomic API
inline bool operator==(int value) const
{
return value == value;
}
inline bool operator!=(int value) const
{
return value != value;
}
inline bool operator!() const
{
return value == 0;
}
inline operator int() const
{
return value;
}
inline atomicInt &operator=(int value)
{
value = value;
return *this;
}
inline bool operator>(int value) const
{
return value > value;
}
inline bool operator<(int value) const
{
return value < value;
}
private:
volatile int value;
mutex m;
};
}//namespace
#endif