I was just reading your code, which interests me since I&#x27;ve been interested in lock-free programming for a while but only recently started learning about the C11 and C++11 memory model and atomic operations.<p>I had some thoughts, which I&#x27;m offering in hopes of clarifying my understanding, and possibly helping to improve your software in the process.<p>I don&#x27;t see any correctness problems in your code, but I do see what look like several opportunities for optimization.  Though please take these with a slight grain of salt, as I am still learning the C11 atomics.<p>Your aring_give() ends with a release barrier and your aring_take() begins with an acquire barrier.  That makes sense to me, as a way of ensuring the sequencing of the reads&#x2F;writes to aring-&gt;rb and to item.  However I don&#x27;t see why aring_give() needs to begin with an acquire and aring_take() needs to end with a release.  I think both of these could be changed to memory_order_relaxed with no change in correctness.<p>But I think we can go a step further actually.  Your atomic_fetch_add_explicit() and atomic_fetch_sub_explicit() operations operate on a shared aring-&gt;items member.  Both the reader and writer write to this variable, which requires expensive locked operations and which will degrade under contention.  I don&#x27;t think this is actually necessary.<p>Instead you could eliminate aring-&gt;items completely and simply compute it based on aring-&gt;head and aring-&gt;tail.  Only the writer writes to head and only the reader writes to tail, so you could use just atomic_load_explicit()&#x2F;atomic_store_explicit() with memory_order_relaxed on these variables to read and write them.  Then calculate the number of items present by comparing them.  This could make the overall queue significantly more efficient.<p>I&#x27;d be curious to hear your thoughts on this.