diff options
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 |