7 #ifndef _LOCK_FREE_QUEUE_CLASS_HEADER_
8 #define _LOCK_FREE_QUEUE_CLASS_HEADER_
10 #ifndef A_UTILS_TAGGED_POINTER_AVALIABLE
18 #ifdef A_UTILS_TAGGED_POINTER_AVALIABLE
36 class A_UTILS_CAS_ALIGNMENT lock_free_queue
43 struct A_UTILS_CAS_ALIGNMENT cNode
45 tagged_ptr<cNode> m_pNext;
50 typedef tagged_ptr<cNode> tTaggedNodePtr;
53 tTaggedNodePtr m_pHead;
56 tTaggedNodePtr m_pTail;
59 free_list<cNode, T> m_oFree;
71 lock_free_queue(
tUInt nReserve = 0,
tBool bGrow =
tTrue): m_pHead(nullptr), m_pTail(nullptr), m_oFree(nReserve, bGrow)
73 m_pHead.Set(
new cNode);
80 virtual ~lock_free_queue()
84 while ((ERR_NOERROR) == Pop(&oTmp));
85 delete m_pHead.GetPtr();
97 cNode* pTmp = m_oFree.GetFreeNode();
104 pTmp->m_oData = oValue;
106 pTmp->m_pNext.Set(
nullptr, pTmp->m_pNext.GetTag() + 1);
111 tTaggedNodePtr pTail = m_pTail;
115 tTaggedNodePtr pNext = pTail->m_pNext;
117 if (pTail == m_pTail)
121 if (pTail->m_pNext.CompareAndSwap(pNext, pTmp))
123 m_pTail.CompareAndSwap(pTail, pTmp);
129 m_pTail.CompareAndSwap(pTail, pNext.GetPtr());
134 return (ERR_NOERROR);
148 tTaggedNodePtr pHead = m_pHead;
152 tTaggedNodePtr pTail = m_pTail;
156 cNode* pNext = pHead->m_pNext.GetPtr();
158 if (pHead == m_pHead)
160 if (pHead.GetPtr() == pTail.GetPtr())
162 if (pNext ==
nullptr)
167 m_pTail.CompareAndSwap(pTail, pNext);
171 if (pNext ==
nullptr)
176 *pValue = pNext->m_oData;
177 if (m_pHead.CompareAndSwap(pHead, pNext))
179 m_oFree.AddFreeNode(pHead.GetPtr());
186 return (ERR_NOERROR);
190 lock_free_queue(
const lock_free_queue& oOther);
210 std::queue<T> m_oQueue;
211 std::recursive_mutex m_oMutex;
239 std::lock_guard<std::recursive_mutex> oLck(m_oMutex);
240 m_oQueue.push(oValue);
241 return (ERR_NOERROR);
252 std::lock_guard<std::recursive_mutex> oLck(m_oMutex);
253 if (m_oQueue.empty())
257 *pValue = m_oQueue.front();
259 return (ERR_NOERROR);
unsigned int tUInt
type definition for unsigned integer value (platform and compiler dependent type).
bool tBool
The tBool defines the type for the Values tTrue and tFalse (platform and compiler dependent).
A common result class usable as return value throughout.
Lock-free queue (FIFO) class that allows multiple writers and readers.
lock_free_queue(tUInt nReserve=0, tBool bGrow=tTrue)
Constructor.
tResult Push(const T &oValue)
Pushes an element into the queue.
tResult Pop(T *pValue)
Pops an element from the queue.
virtual ~lock_free_queue()
Destructor.
#define tTrue
Value for tBool.
ADTF A_UTIL Namespace - Within adtf this is used as adtf::util or adtf_util.
tVoid memory_barrier()
This method will help ensure that all memory reads and writes will have been performed before this fu...