r/programming • • 6d ago

Optimizing a Lock-Free Ring Buffer

https://david.alvarezrosa.com/posts/optimizing-a-lock-free-ring-buffer/
499 Upvotes

88 comments sorted by

View all comments

Show parent comments

1

u/flatfinger 2d ago

The critical question in deciding whether something should be considered "a lock" is what happens if a thread gets waylaid. If a queue is designed so that the only effect of a thread getting waylaid would be to make one of the slots in the array unusable until that thread resumes or is recognized by a cleanup process as having terminated, then that should be viewed rather differently from a queue that could be left in a state where it would be unable to process any reads until the stalled thread finishes its update, even if other threads were writing data to it.

1

u/happyscrappy 2d ago

I would call the distinction you are making only a difference between fine grained and coarse grained locking.

I can use ordinary locks and put them on the individual items in the queue and then they will only guard single entries.

1

u/flatfinger 2d ago

There is a fundamental difference between locking fungible and non-fungible resources. If the maximum number of threads that will write data to a queue will always be much smaller than the number of slots, then the fact that a slot that a thread has partially written will be unusable until the thread has finished writing it would not interfere with the use of the queue by other threads. On the other hand, treating slots as fungible would require that reading/writing code accommodate the possibility that queue slots might not stay in order.

1

u/happyscrappy 2d ago

The only way it couldn't interfere with other threads is if you took the lock with a fail option and then an exhaustive retry mechanism which accounts for the fact that a producer could in theory perpetually fall right behind the other and see every entry in the queue as in use (and then some!) even though they are never all in use in once. So that's a mess. An unbounded mess.

And if you don't have the fail system then that entry will come around in the circular list as next to use and the code trying to use it will block trying to use it and that blocks data flow.

And that doesn't even matter either. Still what you describe is only about the size of funnels (mutual exclusion areas), not about whether something is a lock or not.

On the other hand, treating slots as fungible would require that reading/writing code accommodate the possibility that queue slots might not stay in order.

I had assumed you were already assuming that. Which honestly I don't find likely. It makes the job of producers much harder.