25 #ifndef __CLOCKUTILS_CONTAINER_LOCKFREEQUEUE_H__ 26 #define __CLOCKUTILS_CONTAINER_LOCKFREEQUEUE_H__ 45 template<
typename T,
size_t SIZE>
51 LockFreeQueue() : _readIndex(0), _writeIndex(0), _enqueuing(false), _dequeuing(false), _data() {
58 bool enqueueing =
false;
59 while (!std::atomic_compare_exchange_strong(&_enqueuing, &enqueueing,
true)) {
64 uint64_t readIndex = _readIndex;
65 uint64_t writeIndex = _writeIndex;
67 if (writeIndex - readIndex < SIZE || readIndex > writeIndex) {
68 _data[writeIndex % SIZE] = value;
69 _writeIndex.fetch_add(1);
73 _enqueuing.exchange(
false);
81 bool dequeueing =
false;
82 while (!std::atomic_compare_exchange_strong(&_dequeuing, &dequeueing,
true)) {
87 uint64_t writeIndex = _writeIndex;
89 if (writeIndex <= _readIndex) {
92 _readIndex.fetch_add(1);
94 _dequeuing.exchange(
false);
102 bool dequeueing =
false;
103 while (!std::atomic_compare_exchange_strong(&_dequeuing, &dequeueing,
true)) {
108 uint64_t writeIndex = _writeIndex;
109 uint64_t readIndex = _readIndex;
111 if (writeIndex > readIndex) {
112 value = _data[readIndex % SIZE];
116 _dequeuing.exchange(
false);
124 bool dequeueing =
false;
125 while (!std::atomic_compare_exchange_strong(&_dequeuing, &dequeueing,
true)) {
130 uint64_t writeIndex = _writeIndex;
131 uint64_t readIndex = _readIndex;
133 if (writeIndex > readIndex) {
134 value = _data[readIndex % SIZE];
135 _readIndex.fetch_add(1);
139 _dequeuing.exchange(
false);
147 uint64_t readIdx = _readIndex;
148 uint64_t writeIdx = _writeIndex;
149 return readIdx == writeIdx;
156 uint64_t readIdx = _readIndex;
157 uint64_t writeIdx = _writeIndex;
158 return size_t(writeIdx - readIdx);
165 _readIndex.store(_writeIndex);
169 std::atomic<uint64_t> _readIndex;
170 std::atomic<uint64_t> _writeIndex;
171 std::atomic<bool> _enqueuing;
172 std::atomic<bool> _dequeuing;
174 std::array<T, SIZE> _data;
bool empty() const
returns true if the queue is empty, otherwise false
size_t size() const
returns size of the queue
LockFreeQueue()
default constructor
ClockError front(T &value)
returns first entry of the queue, but keeps it in the queue
0x11 no more space available in container
ClockError push(const T &value)
pushes the given value into the queue
ClockError pop()
removes first entry of the queue
void clear()
removes all elements in the queue
0x10 no element available
0x0 method call succeeded
ClockError poll(T &value)
removes first entry of the queue and returns its value