File: lfqueue.h

package info (click to toggle)
savvycan 220-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 12,456 kB
  • sloc: cpp: 61,803; sh: 293; javascript: 91; python: 44; makefile: 8
file content (91 lines) | stat: -rw-r--r-- 1,732 bytes parent folder | download
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