Commit fdbbdb8f authored by Mike Curtiss's avatar Mike Curtiss Committed by Jordan DeLong

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
parent 62072424
......@@ -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_;
......
......@@ -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
......
......@@ -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);
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment