aboutsummaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/salticidae/queue.h16
1 files changed, 9 insertions, 7 deletions
diff --git a/include/salticidae/queue.h b/include/salticidae/queue.h
index 3df1529..0417750 100644
--- a/include/salticidae/queue.h
+++ b/include/salticidae/queue.h
@@ -105,7 +105,7 @@ class MPMCQueue {
bool _enqueue(U &&e, bool unbounded = true) {
for (;;)
{
- auto t = tail.load(std::memory_order_relaxed);
+ auto t = tail.load(std::memory_order_acquire);
auto tcnt = t->refcnt.load(std::memory_order_relaxed);
if (!tcnt) continue;
if (!t->refcnt.compare_exchange_weak(tcnt, tcnt + 1, std::memory_order_relaxed))
@@ -188,7 +188,7 @@ class MPMCQueue {
bool try_dequeue(T &e) {
for (;;)
{
- auto h = this->head.load(std::memory_order_relaxed);
+ auto h = this->head.load(std::memory_order_acquire);
auto hcnt = h->refcnt.load(std::memory_order_relaxed);
if (!hcnt) continue;
if (!h->refcnt.compare_exchange_weak(hcnt, hcnt + 1, std::memory_order_relaxed))
@@ -199,19 +199,21 @@ class MPMCQueue {
if (hh >= tt)
{
if (tt < MPMCQ_SIZE) { blks.release_ref(h); return false; }
- auto hnext = h->next.load(std::memory_order_relaxed);
+ auto hnext = h->next.load(std::memory_order_acquire);
if (hnext == nullptr) { blks.release_ref(h); return false; }
- if (this->head.compare_exchange_weak(h, hnext, std::memory_order_relaxed))
+ auto h2 = h;
+ if (this->head.compare_exchange_weak(h2, hnext, std::memory_order_acq_rel))
this->blks.push(h);
blks.release_ref(h);
continue;
}
- while (!h->avail[hh].load(std::memory_order_acquire))
- std::this_thread::yield();
auto hh2 = hh;
if (h->head.compare_exchange_weak(hh2, hh2 + 1, std::memory_order_relaxed))
{
+ while (!h->avail[hh].load(std::memory_order_acquire))
+ std::this_thread::yield();
e = std::move(h->elem[hh]);
+ h->avail[hh].store(false, std::memory_order_relaxed);
blks.release_ref(h);
break;
}
@@ -241,9 +243,9 @@ struct MPSCQueue: public MPMCQueue<T> {
this->blks.push(h);
continue;
}
+ h->head.store(hh + 1, std::memory_order_relaxed);
while (!h->avail[hh].load(std::memory_order_acquire))
std::this_thread::yield();
- h->head.store(hh + 1, std::memory_order_relaxed);
e = std::move(h->elem[hh]);
h->avail[hh].store(false, std::memory_order_relaxed);
break;