Commit d7626a92 authored by Doron Roberts-Kedes's avatar Doron Roberts-Kedes Committed by Facebook Github Bot

MPMCQueue: Fix anonymous union of T and Atom<T> treatment

Summary: The previous code issued stores/loads to the non-atomic anonymous union members from partially specialized Dynamic=true code. This breaks when Atom is a class that doesn't behave like a std::atomic.

Reviewed By: magedm

Differential Revision: D10502987

fbshipit-source-id: 8c4670df98dbc830593b5f0edaaa56e2d8842719
parent 85cf282f
......@@ -210,8 +210,10 @@ class MPMCQueue<T, Atom, true>
MPMCQueue(MPMCQueue<T, Atom, true>&& rhs) noexcept {
this->capacity_ = rhs.capacity_;
this->slots_ = rhs.slots_;
this->stride_ = rhs.stride_;
new (&this->dslots_)
Atom<Slot*>(rhs.dslots_.load(std::memory_order_relaxed));
new (&this->dstride_)
Atom<int>(rhs.dstride_.load(std::memory_order_relaxed));
this->dstate_.store(
rhs.dstate_.load(std::memory_order_relaxed), std::memory_order_relaxed);
this->dcapacity_.store(
......@@ -233,8 +235,8 @@ class MPMCQueue<T, Atom, true>
closed_ = rhs.closed_;
rhs.capacity_ = 0;
rhs.slots_ = nullptr;
rhs.stride_ = 0;
rhs.dslots_.store(nullptr, std::memory_order_relaxed);
rhs.dstride_.store(0, std::memory_order_relaxed);
rhs.dstate_.store(0, std::memory_order_relaxed);
rhs.dcapacity_.store(0, std::memory_order_relaxed);
rhs.pushTicket_.store(0, std::memory_order_relaxed);
......@@ -260,6 +262,13 @@ class MPMCQueue<T, Atom, true>
}
delete[] closed_;
}
using AtomInt = Atom<int>;
this->dstride_.~AtomInt();
using AtomSlot = Atom<Slot*>;
// Sort of a hack to get ~MPMCQueueBase to free dslots_
auto slots = this->dslots_.load();
this->dslots_.~AtomSlot();
this->slots_ = slots;
}
size_t allocatedCapacity() const noexcept {
......@@ -337,8 +346,9 @@ class MPMCQueue<T, Atom, true>
ClosedArray* closed_;
void initQueue(const size_t cap, const size_t mult) {
this->stride_ = this->computeStride(cap);
this->slots_ = new Slot[cap + 2 * this->kSlotPadding];
new (&this->dstride_) Atom<int>(this->computeStride(cap));
Slot* slots = new Slot[cap + 2 * this->kSlotPadding];
new (&this->dslots_) Atom<Slot*>(slots);
this->dstate_.store(0);
this->dcapacity_.store(cap);
dmult_ = mult;
......@@ -648,6 +658,8 @@ class MPMCQueueBase<Derived<T, Atom, Dynamic>> : boost::noncopyable {
explicit MPMCQueueBase(size_t queueCapacity)
: capacity_(queueCapacity),
dstate_(0),
dcapacity_(0),
pushTicket_(0),
popTicket_(0),
pushSpinCutoff_(0),
......
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