AzerothCore 3.3.5a
OpenSource WoW Emulator
Loading...
Searching...
No Matches
Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink > Class Template Reference

#include "MPSCQueue.h"

Public Member Functions

 MPSCQueueIntrusive ()
 
 ~MPSCQueueIntrusive ()
 
void Enqueue (T *input)
 
bool Dequeue (T *&result)
 

Private Member Functions

 MPSCQueueIntrusive (MPSCQueueIntrusive const &)=delete
 
MPSCQueueIntrusiveoperator= (MPSCQueueIntrusive const &)=delete
 

Private Attributes

std::aligned_storage_t< sizeof(T), alignof(T)> _dummy
 
T * _dummyPtr
 
std::atomic< T * > _head
 
std::atomic< T * > _tail
 

Detailed Description

template<typename T, std::atomic< T * > T::* IntrusiveLink>
class Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >

Constructor & Destructor Documentation

◆ MPSCQueueIntrusive() [1/2]

template<typename T , std::atomic< T * > T::* IntrusiveLink>
Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::MPSCQueueIntrusive ( )
inline
94 : _dummyPtr(reinterpret_cast<T*>(std::addressof(_dummy))), _head(_dummyPtr), _tail(_dummyPtr)
95 {
96 // _dummy is constructed from aligned_storage and is intentionally left uninitialized (it might not be default constructible)
97 // so we init only its IntrusiveLink here
98 std::atomic<T*>* dummyNext = new (&(_dummyPtr->*IntrusiveLink)) std::atomic<T*>();
99 dummyNext->store(nullptr, std::memory_order_relaxed);
100 }
T * _dummyPtr
Definition: MPSCQueue.h:154
std::atomic< T * > _head
Definition: MPSCQueue.h:155
std::atomic< T * > _tail
Definition: MPSCQueue.h:156
std::aligned_storage_t< sizeof(T), alignof(T)> _dummy
Definition: MPSCQueue.h:153

References Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_dummyPtr.

◆ ~MPSCQueueIntrusive()

template<typename T , std::atomic< T * > T::* IntrusiveLink>
Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::~MPSCQueueIntrusive ( )
inline
103 {
104 T* output;
105 while (Dequeue(output))
106 delete output;
107 }
bool Dequeue(T *&result)
Definition: MPSCQueue.h:116

References Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::Dequeue().

◆ MPSCQueueIntrusive() [2/2]

template<typename T , std::atomic< T * > T::* IntrusiveLink>
Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::MPSCQueueIntrusive ( MPSCQueueIntrusive< T, IntrusiveLink > const &  )
privatedelete

Member Function Documentation

◆ Dequeue()

template<typename T , std::atomic< T * > T::* IntrusiveLink>
bool Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::Dequeue ( T *&  result)
inline
117 {
118 T* tail = _tail.load(std::memory_order_relaxed);
119 T* next = (tail->*IntrusiveLink).load(std::memory_order_acquire);
120 if (tail == _dummyPtr)
121 {
122 if (!next)
123 return false;
124
125 _tail.store(next, std::memory_order_release);
126 tail = next;
127 next = (next->*IntrusiveLink).load(std::memory_order_acquire);
128 }
129
130 if (next)
131 {
132 _tail.store(next, std::memory_order_release);
133 result = tail;
134 return true;
135 }
136
137 T* head = _head.load(std::memory_order_acquire);
138 if (tail != head)
139 return false;
140
142 next = (tail->*IntrusiveLink).load(std::memory_order_acquire);
143 if (next)
144 {
145 _tail.store(next, std::memory_order_release);
146 result = tail;
147 return true;
148 }
149 return false;
150 }
void Enqueue(T *input)
Definition: MPSCQueue.h:109

References Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_dummyPtr, Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_head, Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_tail, and Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::Enqueue().

Referenced by Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::~MPSCQueueIntrusive().

◆ Enqueue()

template<typename T , std::atomic< T * > T::* IntrusiveLink>
void Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::Enqueue ( T *  input)
inline
110 {
111 (input->*IntrusiveLink).store(nullptr, std::memory_order_release);
112 T* prevHead = _head.exchange(input, std::memory_order_acq_rel);
113 (prevHead->*IntrusiveLink).store(input, std::memory_order_release);
114 }

References Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_head.

Referenced by Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::Dequeue().

◆ operator=()

template<typename T , std::atomic< T * > T::* IntrusiveLink>
MPSCQueueIntrusive & Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::operator= ( MPSCQueueIntrusive< T, IntrusiveLink > const &  )
privatedelete

Member Data Documentation

◆ _dummy

template<typename T , std::atomic< T * > T::* IntrusiveLink>
std::aligned_storage_t<sizeof(T), alignof(T)> Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_dummy
private

◆ _dummyPtr

template<typename T , std::atomic< T * > T::* IntrusiveLink>
T* Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_dummyPtr
private

◆ _head

template<typename T , std::atomic< T * > T::* IntrusiveLink>
std::atomic<T*> Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_head
private

◆ _tail

template<typename T , std::atomic< T * > T::* IntrusiveLink>
std::atomic<T*> Acore::Impl::MPSCQueueIntrusive< T, IntrusiveLink >::_tail
private