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

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

◆ ~MPSCQueueIntrusive()

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

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
118 {
119 T* tail = _tail.load(std::memory_order_relaxed);
120 T* next = (tail->*IntrusiveLink).load(std::memory_order_acquire);
121 if (tail == _dummyPtr)
122 {
123 if (!next)
124 return false;
125
126 _tail.store(next, std::memory_order_release);
127 tail = next;
128 next = (next->*IntrusiveLink).load(std::memory_order_acquire);
129 }
130
131 if (next)
132 {
133 _tail.store(next, std::memory_order_release);
134 result = tail;
135 return true;
136 }
137
138 T* head = _head.load(std::memory_order_acquire);
139 if (tail != head)
140 return false;
141
143 next = (tail->*IntrusiveLink).load(std::memory_order_acquire);
144 if (next)
145 {
146 _tail.store(next, std::memory_order_release);
147 result = tail;
148 return true;
149 }
150 return false;
151 }
void Enqueue(T *input)
Definition: MPSCQueue.h:110

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
111 {
112 (input->*IntrusiveLink).store(nullptr, std::memory_order_release);
113 T* prevHead = _head.exchange(input, std::memory_order_acq_rel);
114 (prevHead->*IntrusiveLink).store(input, std::memory_order_release);
115 }

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