Hi!
Your scheme sounds reasonable.
As far as I understand it's related to your other question about SPMC
queue. So if you use a queue like this:
http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
and have an upper bound on buffer size and ready to waste some memory,
then you can embed the buffer directly into each element of the queue.
This queue is actually bi-directional, currently consumers transfer
"empty" elements back to producer. But there is no reason they can not
transfer useful payload back to producer. So in the extreme case you
can have just:
#define MAX_MSG_SIZE (64<<10)
#define QUEUE_SIZE (1<<10)
struct element {
char buf[MAX_MSG_SIZE];
... other data
};
queue<QUEUE_SIZE, element> q;
This consumes 64M of memory persistently. But it is as simple and as
fast as you can get.
You will need to "split" enqueue and dequeue functions into 2 parts:
first waits when the next element becomes ready for
production/consumption, and the second part "commits"
production/consumption.
Producer workflow:
- wait till the next element becomes ready for production (it's most
likely already ready, because the queue if FIFO)
- fill in the element (the buffer is already there, right in the element)
- commit production (make the element ready for consumption)
- repeat
Consumer workflow is symmetric:
- wait till the next element becomes ready for consumption
- process the element (don't need to copy the buffer, read it right in place)
- commit consumption (make the element ready for subsequent production)