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