Skip to content
Browse files

Add sizeGuess() member to ProducerConsumerQueue

Summary:
This is part 1 of a change to add hysteretic behavior to a blocking queue based on ProducerConsumerQueue.

Knowing the size is useful for monitoring and possibly for objects that contain a ProducerConsumerQueue.

Test Plan:
Added tiny test-case.

Tests pass

Reviewed By: delong.j@fb.com

FB internal diff: D496787
  • Loading branch information...
1 parent 6207242 commit fdbbdb8f25443a74ec7f351abd9b7f13b6b78e13 Mike Curtiss committed with jdelong Jun 7, 2012
Showing with 23 additions and 3 deletions.
  1. +14 −0 folly/ProducerConsumerQueue.h
  2. +8 −3 folly/docs/ProducerConsumerQueue.md
  3. +1 −0 folly/test/ProducerConsumerQueueTest.cpp
View
14 folly/ProducerConsumerQueue.h
@@ -149,6 +149,20 @@ struct ProducerConsumerQueue : private boost::noncopyable {
return true;
}
+ // * If called by consumer, then true size may be more (because producer may
+ // be adding items concurrently).
+ // * If called by producer, then true size may be less (because consumer may
+ // be removing items concurrently).
+ // * It is undefined to call this from any other thread.
+ size_t sizeGuess() const {
+ int ret = writeIndex_.load(std::memory_order_consume) -
+ readIndex_.load(std::memory_order_consume);
+ if (ret < 0) {
+ ret += size_;
+ }
+ return ret;
+ }
+
private:
const uint32_t size_;
T* const records_;
View
11 folly/docs/ProducerConsumerQueue.md
@@ -18,12 +18,17 @@ operations:
empty).
* `isEmpty`: Check if the queue is empty.
* `isFull`: Check if the queue is full.
+ * `sizeGuess`: Returns the number of entries in the queue. Because of the
+ way we coordinate threads, this guess could be slightly wrong
+ when called by the producer/consumer thread, and it could be
+ wildly inaccurate if called from any other threads. Hence,
+ only call from producer/consumer threads!
All of these operations are wait-free. The read operations (including
`frontPtr` and `popFront`) and write operations must only be called by the
-reader and writer thread, respectively. `isFull` and `isEmpty` may be called by
-either thread, but the return values from `read`, `write`, or `frontPtr` are
-sufficient for most cases.
+reader and writer thread, respectively. `isFull`, `isEmpty`, and `sizeGuess`
+may be called by either thread, but the return values from `read`, `write`, or
+`frontPtr` are sufficient for most cases.
`write` may fail if the queue is full, and `read` may fail if the queue is
empty, so in many situations it is important to choose the queue size such that
View
1 folly/test/ProducerConsumerQueueTest.cpp
@@ -281,4 +281,5 @@ TEST(PCQ, EmptyFull) {
EXPECT_TRUE(queue.isFull()); // Tricky: full after 2 writes, not 3.
EXPECT_FALSE(queue.write(3));
+ EXPECT_EQ(queue.sizeGuess(), 2);
}

0 comments on commit fdbbdb8

Please sign in to comment.
Something went wrong with that request. Please try again.