X-Git-Url: http://plrg.eecs.uci.edu/git/?p=folly.git;a=blobdiff_plain;f=folly%2FProducerConsumerQueue.h;h=de0e3cc0a39892cde2903ad60f560de33b8809d5;hp=6a545dea9269bf0853ad1e6ca3504ea499c51c83;hb=c51f93205176b9bb3792a1c8bedcf5228ce669ac;hpb=f389df4f9036c68a19a7987cf3ac2c3bad55fb9d diff --git a/folly/ProducerConsumerQueue.h b/folly/ProducerConsumerQueue.h index 6a545dea..de0e3cc0 100644 --- a/folly/ProducerConsumerQueue.h +++ b/folly/ProducerConsumerQueue.h @@ -86,6 +86,7 @@ struct ProducerConsumerQueue : private boost::noncopyable { return false; } + // move (or copy) the value at the front of the queue to given variable bool read(T& record) { auto const currentRead = readIndex_.load(std::memory_order_relaxed); if (currentRead == writeIndex_.load(std::memory_order_acquire)) { @@ -103,6 +104,35 @@ struct ProducerConsumerQueue : private boost::noncopyable { return true; } + // pointer to the value at the front of the queue (for use in-place) or + // nullptr if empty. + T* frontPtr() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + if (currentRead == writeIndex_.load(std::memory_order_acquire)) { + // queue is empty + return nullptr; + } + return &records_[currentRead]; + } + + // queue must not be empty + void popFront() { + auto const currentRead = readIndex_.load(std::memory_order_relaxed); + assert(currentRead != writeIndex_.load(std::memory_order_acquire)); + + auto nextRecord = currentRead + 1; + if (nextRecord == size_) { + nextRecord = 0; + } + records_[currentRead].~T(); + readIndex_.store(nextRecord, std::memory_order_release); + } + + bool isEmpty() const { + return readIndex_.load(std::memory_order_consume) != + writeIndex_.load(std::memory_order_consume); + } + bool isFull() const { auto nextRecord = writeIndex_.load(std::memory_order_consume) + 1; if (nextRecord == size_) {