Commit 59ea1768 authored by Maged Michael's avatar Maged Michael Committed by Facebook Github Bot 4

Dynamic expansion of folly MPMC queue

Summary:
This diff allows queues to start with small capacity and expand as needed up to the specified capacity.
The main additions and changes:
- Extra template parameter `Dynamic` that enables dynamic expansion (`default 'false').
- `ClosedArray` type.
- Extra members:
  -- `dstate_`: a packed 64 bit unsigned int that contains a seqlock (which implicitly indicates the number of expansions and the lowest ticket for the current `dslots_/dcapacity_/dstride_` configuration.
 -- `dcapacity_`: current dynamic capacity.
 -- `dslots_`: current dynamic slots array. (in anonymous union with `slots_`)
 -- `dstride_`: current dynamic stride. (in anonymous union with `stride_`)
 -- `closed_` a logarithmic-sized array of ClosedArray to hold information about earlier smaller queue arrays for use by lagging consumers.

Design sketch:
- Reallocate a new larger array on expansion
- Expansion uses a seqlock. The common case critical path includes a seqlock read-only section.
- Lagging consumers and lagging blocking producers use a logarithmic-sized array for info about closed arrays
- Tickets are adjusted by an offset (to accounts for the tickets associated with earlier closed arrays) in order to calculate appropriate index and turn.
- The synching of `pushTicket_` with the ticket offset packed in `dstate_` is tricky. `pushTicket_` is accessed outside `dstate_`'s seqlock.

Reviewed By: djwatson

Differential Revision: D3462592

fbshipit-source-id: d442a7694190cca3c33753409ffac941d7463f83
parent 1cd90b1d
This diff is collapsed.
...@@ -76,8 +76,8 @@ class MPMCPipelineStageImpl { ...@@ -76,8 +76,8 @@ class MPMCPipelineStageImpl {
} }
uint64_t blockingRead(T& elem) noexcept { uint64_t blockingRead(T& elem) noexcept {
uint64_t ticket = queue_.popTicket_++; uint64_t ticket;
queue_.dequeueWithTicket(ticket, elem); queue_.blockingReadWithTicket(ticket, elem);
return ticket; return ticket;
} }
...@@ -87,12 +87,7 @@ class MPMCPipelineStageImpl { ...@@ -87,12 +87,7 @@ class MPMCPipelineStageImpl {
template <class... Args> template <class... Args>
bool readAndGetTicket(uint64_t& ticket, T& elem) noexcept { bool readAndGetTicket(uint64_t& ticket, T& elem) noexcept {
if (queue_.tryObtainReadyPopTicket(ticket)) { return queue_.readAndGetTicket(ticket, elem);
queue_.dequeueWithTicket(ticket, elem);
return true;
} else {
return false;
}
} }
// See MPMCQueue<T>::writeCount; only works for the first stage // See MPMCQueue<T>::writeCount; only works for the first stage
......
This diff is collapsed.
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