Separately; the simulator is cool and very helpful!
Separately; the simulator is cool and very helpful!
Also this one enqueue will be mega expensive - a clear "fat tail" in the latency histogram.
In MultiArrayQueue you keep all already enqueued material in-place, "just" allocate the bigger array, register the new diversion, enqueue the one new element - and done.
Thanks
for me it would be better to allocate new buffer but allow reading from old one until it contains data and after that dealocate it and keep only new one in use
One other thing I want to shout out, I saw what I thought was a really neat multicast ring buffer the other day where the author has an atomic for each element, rather than the typical reader/writer atomics. The promise was having much less contention on any given atomic, in most cases. https://github.com/rezabrizi/SPMC-Queue https://news.ycombinator.com/item?id=40410172
You never know how many concurrent threads still "are" on the place you wish to remove.
You would have to deal with stuff like hazard pointers, limbo lists and the like.
Better to keep the small arrays there.
If queue only allows to copy out data you can increase reader pointer after data were copied to different buffer, therefore nothing can be at the place we are removing
Perhaps we want to have any of the given multicast readers able to read more than one element at a time, and that does complicate things somewhat. But hardly impossible to handle.
Again: deeply disagreeing with the premise here that this can't be done. And it isn't even really a significant penalty, if your consumers do have to be async consumers that need to hold open their reading for a while. Unclear what the protests are.
The smaller arrays are not "left behind" in the garbage sense - the queue will use them again and again in the next rounds. See simulator. Re-use, not Re-cycle - the Garbage-Free Mantra.
If the Queue re-cycles the smaller arrays, it would not be garbage-free anymore.
If you still believe that the smaller arrays should be re-cycled (would be curious why), then comes the technical problem:
Let's imagine a reader stands immediately before reading the array (e.g. to check if the writer has already written). Now the OS preempts him. For how long: We don't know. In the meantime all things in the queue move forward and the program code in some other thread (writer probably) decides to de-allocate the array (and indeed does it).
Now the preempted reader wakes up and the first thing it does is to read from that (deallocated) array ...
[0] It needs a refactor, but here's some version of the idea. https://github.com/hmusgrave/zcirc
[1] You're not _really_ bounded since you have blocking calls to the underlying allocator (usually somewhere close to the OS, and even that can do more work than you might expect when you ask for a contiguous array), but it's still much cheaper than a bulk copy.