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
|
#ifndef LFQUEUE_H
#define LFQUEUE_H
#include <QObject>
#include <QDebug>
/* macros */
#define IS_EMPTY() ( mWIdx.loadAcquire() == mRIdx.loadAcquire() )
#define IS_FULL() ( (mWIdx.loadAcquire()+1)%mSize == mRIdx.loadAcquire() )
template<class T>
class LFQueue
{
public:
LFQueue() : mSize(0), mArray(nullptr){}
~LFQueue() {setSize(0);}
bool setSize(int size) {
if(size<0)
return false;
if(mArray) {
delete[] mArray;
mArray = nullptr;
}
if(size>0) {
mArray = new T[size];
if(mArray)
mSize = size;
return ( mArray != nullptr );
}
return true;
}
void flush() {
mRIdx.storeRelease(0);
mWIdx.storeRelease(0);
}
T* get() {
if(IS_FULL())
return nullptr;
return &(mArray[mWIdx.loadAcquire()]); /* prevent memory reordering (belt and braces) */
}
void queue() {
#ifdef QT_DEBUG
if(IS_FULL())
qCritical() << "BUG: queueing in full queue";
#endif
int wIdx = mWIdx.loadAcquire();
mWIdx.storeRelease((wIdx+1)%mSize);
}
T* peek() {
if(IS_EMPTY())
return nullptr;
return &(mArray[mRIdx.loadAcquire()]); /* prevent memory reordering (belt and braces) */
}
void dequeue() {
#ifdef QT_DEBUG
if(IS_EMPTY())
qCritical() << "BUG: dequeueing an empty queue";
#endif
int rIdx = mRIdx.loadAcquire();
mRIdx.storeRelease((rIdx+1)%mSize);
}
private:
int mSize;
T* mArray;
QAtomicInt mRIdx;
QAtomicInt mWIdx;
};
#endif // LFQUEUE_H
|