I have a producer thread that produces objects at a rate that might (temporarily) be too fast for the consumer thread to consume. Therefore, I'd like a FIFO that buffers the remaining work. Once the FIFO is full, the producer shall simply retire or retry later. Also, I would like to be able to notify the consumer that no more work is to be done (without enqueuing a special object into the FIFO). The producer shall not get slowed down and the consumer shall not waste CPU cycles, so I have the following requirements:
I am envisioning the following C++ class:
template <typename T, std::size_t N>
class spsc_circular_half_blocking {
std::array<T, N> buffer;
// bookkeeping, atomics, mutexes etc. go here
public:
bool try_push(const T&); // returns whether object could be enqueued
void notify(); // notifies consumer
bool wait_pop(T&); // returns whether object was dequeued or notification was received
};
Being able to modify the elements in-place would be nice. It may also use dynamic allocation of the buffer (e.g. size is passed to constructor, buffer is a unique_ptr
).
Now for my questions. Is this thing even possible (on x86, at least)?
Pointers to related material, even if it does not exactly fulfill my needs, would also be greatly appreciated.
One solution would be to use boost single-producer single-consumer queue with you own signalling and blocking.