![]() |
Shadowrun: Awakened 29 September 2011 - Build 871
|
#include <LocklessFIFO.hpp>
Public Member Functions | |
| T * | Dequeue () |
| T * | DequeueWait () |
| void | Enqueue (T *data) |
| void | FixList (Ptr< T > tail, Ptr< T > head) |
| Queue () | |
| ~Queue () | |
Private Attributes | |
| Ptr< T > | Head |
| Ptr< T > | Tail |
Definition at line 105 of file LocklessFIFO.hpp.
| cat::FIFO::Queue< T >::Queue | ( | ) |
Definition at line 175 of file LocklessFIFO.hpp.
References cat::Singleton< RegionAllocator >::ii, and cat::FIFO::Node< T >::value.
{
#if defined(CAT_OS_WINDOWS)
hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
#endif
Node<T> *node = new (RegionAllocator::ii) Node<T>;
node->value = 0;
Head.ptr = Tail.ptr = node;
}
| cat::FIFO::Queue< T >::~Queue | ( | ) |
Definition at line 188 of file LocklessFIFO.hpp.
References cat::RegionAllocator::Delete(), cat::Singleton< RegionAllocator >::ii, and cat::FIFO::Node< T >::next.
{
// Destroy objects that are still queued
for (Node<T> *next, *ptr = Head.ptr; ptr; ptr = next)
{
next = ptr->next.ptr;
if (ptr->value)
RegionAllocator::ii->Delete(ptr->value);
RegionAllocator::ii->Delete(ptr);
}
#if defined(CAT_OS_WINDOWS)
CloseHandle(hEvent);
#endif
}
| T * cat::FIFO::Queue< T >::Dequeue | ( | ) |
Definition at line 254 of file LocklessFIFO.hpp.
References cat::FIFO::CAS2(), cat::RegionAllocator::Delete(), cat::Singleton< RegionAllocator >::ii, cat::FIFO::Node< T >::next, cat::FIFO::Ptr< T >::ptr, T, cat::FIFO::Ptr< T >::tag, and cat::FIFO::Node< T >::value.
{
Ptr<T> tail, head, firstNodePrev;
Node<T> *nd_dummy;
T *val;
for (;;)
{
head = Head;
tail = Tail;
firstNodePrev = head.ptr->prev;
val = head.ptr->value;
if (head == Head)
{
if (val != 0)
{
if (tail != head)
{
if (firstNodePrev.tag != head.tag)
{
FixList(tail, head);
continue;
}
}
else
{
nd_dummy = new (RegionAllocator::ii) Node<T>;
nd_dummy->value = 0;
nd_dummy->next.ptr = tail.ptr;
nd_dummy->next.tag = tail.tag + 1;
Ptr<T> new_tail;
new_tail.ptr = nd_dummy;
new_tail.tag = tail.tag + 1;
if (CAS2(Tail, tail, new_tail))
{
head.ptr->prev.ptr = nd_dummy;
head.ptr->prev.tag = tail.tag;
}
else
{
RegionAllocator::ii->Delete(nd_dummy);
}
continue;
}
Ptr<T> new_head;
new_head.ptr = firstNodePrev.ptr;
new_head.tag = head.tag + 1;
if (CAS2(Head, head, new_head))
{
RegionAllocator::ii->Delete(head.ptr);
return val;
}
}
else
{
if (tail.ptr == head.ptr)
return 0;
if (firstNodePrev.tag != head.tag)
{
FixList(tail, head);
continue;
}
Ptr<T> new_head;
new_head.ptr = firstNodePrev.ptr;
new_head.tag = head.tag + 1;
CAS2(Head, head, new_head);
}
}
}
}
| T * cat::FIFO::Queue< T >::DequeueWait | ( | ) |
Definition at line 236 of file LocklessFIFO.hpp.
References T.
{
for (;;)
{
// Attempt to dequeue a message
// If we won the race to service the message, then return it
T *retval = Dequeue();
if (retval) return retval;
#if defined(CAT_OS_WINDOWS)
// If the sychronization wait fails (handle closed), abort with 0
if (WaitForSingleObject(hEvent, INFINITE) != WAIT_OBJECT_0)
return 0;
#endif
}
}
| void cat::FIFO::Queue< T >::Enqueue | ( | T * | data | ) |
Definition at line 206 of file LocklessFIFO.hpp.
References cat::FIFO::CAS2(), cat::Singleton< RegionAllocator >::ii, cat::FIFO::Node< T >::next, cat::FIFO::Ptr< T >::ptr, cat::FIFO::Ptr< T >::tag, and cat::FIFO::Node< T >::value.
{
Ptr<T> tail;
Node<T> *nd = new (RegionAllocator::ii) Node<T>;
nd->value = val;
for (;;)
{
tail = Tail;
nd->next.ptr = tail.ptr;
nd->next.tag = tail.tag + 1;
Ptr<T> new_tail;
new_tail.ptr = nd;
new_tail.tag = tail.tag + 1;
if (CAS2(Tail, tail, new_tail))
{
tail.ptr->prev.ptr = nd;
tail.ptr->prev.tag = tail.tag;
break;
}
}
#if defined(CAT_OS_WINDOWS)
SetEvent(hEvent);
#endif
}
Definition at line 336 of file LocklessFIFO.hpp.
References cat::FIFO::Ptr< T >::ptr, and cat::FIFO::Ptr< T >::tag.
{
Ptr<T> curNode, curNodeNext, nextNodePrev;
curNode = tail;
while (head == Head && curNode != head)
{
curNodeNext = curNode.ptr->next;
if (curNodeNext.tag != curNode.tag)
return;
nextNodePrev = curNodeNext.ptr->prev;
if (nextNodePrev.ptr != curNode.ptr || nextNodePrev.tag != curNode.tag - 1)
{
curNodeNext.ptr->prev.ptr = curNode.ptr;
curNodeNext.ptr->prev.tag = curNode.tag - 1;
}
curNode.ptr = curNodeNext.ptr;
curNode.tag = curNode.tag - 1;
}
}
Ptr<T> cat::FIFO::Queue< T >::Head [private] |
Definition at line 108 of file LocklessFIFO.hpp.
Ptr<T> cat::FIFO::Queue< T >::Tail [private] |
Definition at line 108 of file LocklessFIFO.hpp.
Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.