Use of std::memory_order_consume in the Folly's lock free SPSC queue

Viewed 1045

In the process of trying to understand how to deal with lock free code, I attempted to write a single consumer/single producer lock free queue. As always, I checked papers, articles, and code, especially considering that this is a somewhat delicate subject.

So, I stumbled upon an implementation of this data structure in the Folly library, which can be found here : https://github.com/facebook/folly/blob/master/folly/ProducerConsumerQueue.h

As every lock-free queue I saw, this one seems to use a circular buffer, so we got two std::atomic<unsigned int> variables : readIndex_ and writeIndex_. The readIndex_ indicate the next index at which we will read, and writeIndex_ the next at which we will write. Seems simple enough.

So, the implementation seems clean and pretty simple at first sight, but I found one thing troublesome. Indeed, some functions like isEmpty(), isFull() or guessSize() are using std::memory_order_consume to retrieve the value of the indices.

And to be fair, I really don't know what purpose they do serve. Don't get me wrong, I'm aware of the use of std::memory_order_consume in the classical case of dependency-carrying through an atomic pointer, but here, we do not seem to carry any dependency ! We just got indices, unsigned integers, we do not create dependencies. To me in this scenario, a std::memory_order_relaxed is equivalent.

However, I do not trust myself to understand memory ordering better than those who engineered this code, hence why I ask this question here. Is there anything I missed or misunderstood ?

I thank you in advance for your answers !

1 Answers
Related