aboutsummaryrefslogtreecommitdiff
path: root/include/salticidae/queue.h
diff options
context:
space:
mode:
authorDeterminant <ted.sybil@gmail.com>2018-11-11 23:02:59 -0500
committerDeterminant <ted.sybil@gmail.com>2018-11-11 23:02:59 -0500
commitdd09443b0b3c0b5d1a8c034644d1065dd25bf5a9 (patch)
treef770ccffa4ae89bfec00c65e162f4f0d0613c3ae /include/salticidae/queue.h
parentb7d65ee96221e63c865b1bf8cda79b3021cba412 (diff)
start debugging multiloops design
Diffstat (limited to 'include/salticidae/queue.h')
-rw-r--r--include/salticidae/queue.h28
1 files changed, 28 insertions, 0 deletions
diff --git a/include/salticidae/queue.h b/include/salticidae/queue.h
index 88b3fc3..9045e2b 100644
--- a/include/salticidae/queue.h
+++ b/include/salticidae/queue.h
@@ -90,6 +90,7 @@ class FreeList {
template<typename T>
class MPMCQueue {
+ protected:
struct Block: public FreeList::Node {
T elem;
std::atomic<Block *> next;
@@ -171,6 +172,33 @@ class MPMCQueue {
}
};
+template<typename T>
+struct MPSCQueue: public MPMCQueue<T> {
+ using MPMCQueue<T>::MPMCQueue;
+ bool try_dequeue(T &e) {
+ auto h = this->head.load(std::memory_order_acquire);
+ auto nh = h->next.load(std::memory_order_relaxed);
+ if (nh == nullptr)
+ return false;
+ e = std::move(nh->elem);
+ this->head.store(nh, std::memory_order_release);
+ this->blks.push(h);
+ return true;
+ }
+
+ template<typename U>
+ bool rewind(U &&e) {
+ FreeList::Node * _nblk;
+ if (!this->blks.pop(_nblk)) return false;
+ auto nblk = static_cast<typename MPMCQueue<T>::Block *>(_nblk);
+ auto h = this->head.load(std::memory_order_acquire);
+ nblk->next.store(h, std::memory_order_release);
+ new (&(h->elem)) T(std::forward<U>(e));
+ this->head.store(nblk, std::memory_order_release);
+ return true;
+ }
+};
+
}
#endif