Several bugfixes

This commit is contained in:
Paolo Cignoni 2011-12-15 18:51:53 +00:00
parent 3adba90ef3
commit 6b2e8c50d2
2 changed files with 117 additions and 106 deletions

View File

@ -12,106 +12,113 @@ namespace mt{
class atomicInt class atomicInt
{ {
public: public:
atomicInt() atomicInt()
{ {
value = 0; _q_value = 0;
} }
atomicInt( int value )
{
value = value;
}
// atomic API 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. Reads the current value of this QAtomicInt and then adds valueToAdd
to the current value, returning the original value.
Implementation based on SDL: Unfortunately, MacOSX does not provide with fetch-and-add functions,
//http://lists.libsdl.org/pipermail/commits-libsdl.org/2011-January/003568.html only add-and-fetch. Therefore, we have to simulate them.
*/
inline int fetchAndAddAcquire( int valueToAdd )
{
//T *originalValue = currentValue;
//currentValue += valueToAdd;
//return originalValue;
int originalValue; Implementation based on SDL:
do { //http://lists.libsdl.org/pipermail/commits-libsdl.org/2011-January/003568.html
originalValue = value; */
} while (!OSAtomicCompareAndSwap32Barrier(originalValue, originalValue+valueToAdd, &value)); inline int fetchAndAddAcquire( int valueToAdd )
return originalValue; {
} //T *originalValue = currentValue;
//currentValue += valueToAdd;
//return originalValue;
/** int originalValue;
Atomically increments the value of this atomicInt. do {
Returns true if the new value is non-zero, false otherwise.*/ originalValue = _q_value;
inline bool ref() } while (!OSAtomicCompareAndSwap32Barrier(originalValue, originalValue+valueToAdd, &_q_value));
{ return originalValue;
return OSAtomicIncrement32Barrier(&value) != 0; }
}
/* /**
Atomically decrements the value of this QAtomicInt. 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 deref() inline bool ref()
{ {
return OSAtomicDecrement32Barrier(&value) != 0; return OSAtomicIncrement32Barrier(&_q_value) != 0;
} }
inline bool testAndSetOrdered(int expectedValue, int newValue) /*
{ Atomically decrements the value of this QAtomicInt.
//if (currentValue == expectedValue) { Returns true if the new value is non-zero, false otherwise.*/
// currentValue = newValue; inline bool deref()
// return true; {
// } return OSAtomicDecrement32Barrier(&_q_value) != 0;
//return false; }
return OSAtomicCompareAndSwap32Barrier(expectedValue, newValue, &value); /*
} 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 // Non-atomic API
inline bool operator==(int value) const
{
return value == value;
}
inline bool operator!=(int value) const inline bool operator==(int value) const
{ {
return value != value; return _q_value == value;
} }
inline bool operator!() const inline bool operator!=(int value) const
{ {
return value == 0; return _q_value != value;
} }
inline operator int() const inline bool operator!() const
{ {
return value; return _q_value == 0;
} }
inline atomicInt &operator=(int value)
{
value = value;
return *this;
}
inline bool operator>(int value) const inline operator int() const
{ {
return value > value; return _q_value;
} }
inline bool operator<(int value) const inline atomicInt &operator=(int value)
{ {
return value < 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;
}
private: private:
volatile int value; volatile int _q_value;
}; };

View File

@ -4,6 +4,8 @@
#include "mt.h" #include "mt.h"
#include <iostream>
namespace mt{ namespace mt{
class atomicInt class atomicInt
@ -11,48 +13,50 @@ class atomicInt
public: public:
atomicInt() atomicInt()
{ {
value = 0; _q_value = 0;
std::cout << "atomicInt init a 0\n";
} }
atomicInt( int value ) atomicInt( int value )
{ {
value = value; _q_value = value;
std::cout << "atomicInt init a " << _q_value << std::endl;
} }
// atomic API // atomic API
/** /**
Reads the current value of this QAtomicInt and then adds valueToAdd Reads the current _q_value of this QAtomicInt and then adds valueToAdd
to the current value, returning the original value. to the current _q_value, returning the original _q_value.
*/ */
inline int fetchAndAddAcquire( int valueToAdd ) inline int fetchAndAddAcquire( int valueToAdd )
{ {
mutexlocker lock(&m); mutexlocker lock(&m);
int originalValue = value; int originalValue = _q_value;
value += valueToAdd; _q_value += valueToAdd;
return originalValue; return originalValue;
} }
/** /**
Atomically increments the value of this atomicInt. Atomically increments the _q_value of this atomicInt.
Returns true if the new value is non-zero, false otherwise.*/ Returns true if the new _q_value is non-zero, false otherwise.*/
inline bool ref() inline bool ref()
{ {
mutexlocker lock(&m); mutexlocker lock(&m);
return ++value != 0; return ++_q_value != 0;
} }
/* /*
Atomically decrements the value of this QAtomicInt. Atomically decrements the _q_value of this QAtomicInt.
Returns true if the new value is non-zero, false otherwise.*/ Returns true if the new _q_value is non-zero, false otherwise.*/
inline bool deref() inline bool deref()
{ {
mutexlocker lock(&m); mutexlocker lock(&m);
return --value != 0; return --_q_value != 0;
} }
/* /*
If the current value of this QAtomicInt is the expectedValue, If the current _q_value of this QAtomicInt is the expectedValue,
the test-and-set functions assign the newValue to this QAtomicInt the test-and-set functions assign the newValue to this QAtomicInt
and return true. If the values are not the same, this function and return true. If the values are not the same, this function
does nothing and returns false. does nothing and returns false.
@ -60,8 +64,8 @@ does nothing and returns false.
inline bool testAndSetOrdered(int expectedValue, int newValue) inline bool testAndSetOrdered(int expectedValue, int newValue)
{ {
mutexlocker lock(&m); mutexlocker lock(&m);
if (value == expectedValue) { if (_q_value == expectedValue) {
value = newValue; _q_value = newValue;
return true; return true;
} }
return false; return false;
@ -70,42 +74,42 @@ does nothing and returns false.
// Non-atomic API // Non-atomic API
inline bool operator==(int value) const inline bool operator==(int value) const
{ {
return value == value; return _q_value == value;
} }
inline bool operator!=(int value) const inline bool operator!=(int value) const
{ {
return value != value; return _q_value != value;
} }
inline bool operator!() const inline bool operator!() const
{ {
return value == 0; return _q_value == 0;
} }
inline operator int() const inline operator int() const
{ {
return value; return _q_value;
} }
inline atomicInt &operator=(int value) inline atomicInt &operator=(int value)
{ {
value = value; _q_value = value;
return *this; return *this;
} }
inline bool operator>(int value) const inline bool operator>(int value) const
{ {
return value > value; return _q_value > value;
} }
inline bool operator<(int value) const inline bool operator<(int value) const
{ {
return value < value; return _q_value < value;
} }
private: private:
volatile int value; volatile int _q_value;
mutex m; mutex m;
}; };