You're welcome to consider mine, it's nothing special. I use this in my iOS app between the UI thread and audio thread, so only one producer, one consumer.
#pragma once
#include <cstdio>
#include <libkern/OSAtomic.h>
namespace quorra
{
template <typename T>
class lockfreequeue
{
private:
int QUEUESIZE;
T* q; // body of queue
int qsize;
int first; // position of first element
int last; // position of last element
int count; // number of queue elements
public:
lockfreequeue(const int size = 256) :
QUEUESIZE(size), first(0), last(size - 1), count(0)
{
q = new T[size + 1];
}
~lockfreequeue()
{
delete q;
}
void push_back(const T& t)
{
volatile int32_t tempLast;
if (count >= QUEUESIZE)
{
printf("Warning: queue overflow enqueue %d\n", QUEUESIZE);
}
else
{
OSAtomicCompareAndSwap32Barrier(tempLast, last, &tempLast);
tempLast = (tempLast + 1) % QUEUESIZE;
OSAtomicCompareAndSwap32Barrier(last, tempLast, &last);
OSMemoryBarrier();
q[last] = t;
OSAtomicIncrement32Barrier(&count);
}
}
T pop_front()
{
volatile int32_t tempFirst;
T x;
if (count <= 0)
printf("Warning: empty queue dequeue.\n");
else
{
OSMemoryBarrier();
x = q[first];
OSAtomicCompareAndSwap32Barrier(tempFirst, first, &tempFirst);
tempFirst = (tempFirst + 1) % QUEUESIZE;
OSAtomicCompareAndSwap32Barrier(first, tempFirst, &first);
OSAtomicDecrement32Barrier(&count);
}
return x;
}
bool empty()
{
if (count <= 0) return true;
else return false;
}
T front()
{
OSMemoryBarrier();
return q[first];
}
void clear()
{
first = 0;
last = QUEUESIZE - 1;
count = 0;
}
size_t size()
{
return count;
}
};
}