diff options
author | Determinant <ted.sybil@gmail.com> | 2018-11-11 23:02:59 -0500 |
---|---|---|
committer | Determinant <ted.sybil@gmail.com> | 2018-11-11 23:02:59 -0500 |
commit | dd09443b0b3c0b5d1a8c034644d1065dd25bf5a9 (patch) | |
tree | f770ccffa4ae89bfec00c65e162f4f0d0613c3ae /include/salticidae/queue.h | |
parent | b7d65ee96221e63c865b1bf8cda79b3021cba412 (diff) |
start debugging multiloops design
Diffstat (limited to 'include/salticidae/queue.h')
-rw-r--r-- | include/salticidae/queue.h | 28 |
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 |