Reputation: 3802
I want to use boost::atomic
for a wait-free ring buffer as described here:
My producer
provides large amount of data at the same time (unsigned char, +- 3000 values), just like a matrix it would fill line by line. What is the best way to push
these values in the buffer ? Should I just loop over them or can I memcpy
them inside somehow?
Same goes for pop
if I want to read a bunch of values at the same time...
Here is what I came up with, any reason this should not be good ?
I just need to make sure RINGBUFFERSIZE % iSize = 0
.
#define RINGBUFFERSIZE = 30000
ring_[RINGBUFFERSIZE];
bool push(unsigned char* iData, int iSize)
{
size_t head = head_.load(boost::memory_order_relaxed);
size_t next_head = next(head,iSize);
if (next_head == tail_.load(boost::memory_order_acquire))
return false;
memcpy(ring_+head,iData,iSize);
head_.store(next_head, boost::memory_order_release);
}
bool pop(unsigned char * value, int iSize)
{
size_t tail = tail_.load(boost::memory_order_relaxed);
if (tail == head_.load(boost::memory_order_acquire))
return false;
value = &ring_[tail];
tail_.store(next(tail,iSize), boost::memory_order_release);
return true;
}
size_t next(size_t current, int iSize)
{
return (current + iSize) % RINGBUFFERSIZE;
}
Upvotes: 1
Views: 1967
Reputation: 67713
The fastest way is to push a pointer (either unsigned char *
or pointer to some structure which contains the length as well).
Of course, assuming it's ok to force pop
to take exactly the same chunks that were pushed, this just moves the problem: now you have to manage the allocation of these buffers somehow.
Simple sample solution for managing your chunks:
unsigned char data[3096]
or whatever)If you really can't do this, you could pick a maximum size for your chunks and push/pop objects of that size by value ... but honestly this seems very wasteful (even if object knows its length so doesn't have to memcpy
the whole 3k array for smaller chunks).
Upvotes: 1