mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Add LockFreeStack iterators
This commit is contained in:
@@ -23,6 +23,94 @@
|
||||
struct LockFreeStackDefaultTag;
|
||||
|
||||
/*============================================================================*/
|
||||
|
||||
template <class Container, bool IsConst>
|
||||
class LockFreeStackIterator
|
||||
: public std::iterator <
|
||||
std::forward_iterator_tag,
|
||||
typename Container::value_type,
|
||||
typename Container::difference_type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type,
|
||||
typename mpl::IfCond <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type>
|
||||
{
|
||||
protected:
|
||||
typedef typename Container::Node Node;
|
||||
typedef typename mpl::IfCond <IsConst, Node const*, Node*>::type NodePtr;
|
||||
|
||||
public:
|
||||
typedef typename Container::value_type value_type;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typename Container::const_pointer,
|
||||
typename Container::pointer>::type pointer;
|
||||
typedef typename mpl::IfCond <IsConst,
|
||||
typename Container::const_reference,
|
||||
typename Container::reference>::type reference;
|
||||
|
||||
LockFreeStackIterator ()
|
||||
: m_node ()
|
||||
{
|
||||
}
|
||||
|
||||
LockFreeStackIterator (NodePtr node)
|
||||
: m_node (node)
|
||||
{
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
explicit LockFreeStackIterator (LockFreeStackIterator <Container, OtherIsConst> const& other)
|
||||
: m_node (other.m_node)
|
||||
{
|
||||
}
|
||||
|
||||
LockFreeStackIterator& operator= (NodePtr node)
|
||||
{
|
||||
m_node = node;
|
||||
return static_cast <LockFreeStackIterator&> (*this);
|
||||
}
|
||||
|
||||
LockFreeStackIterator& operator++ ()
|
||||
{
|
||||
m_node = m_node->m_next;
|
||||
return static_cast <LockFreeStackIterator&> (*this);
|
||||
}
|
||||
|
||||
LockFreeStackIterator operator++ (int)
|
||||
{
|
||||
LockFreeStackIterator result (*this);
|
||||
m_node = m_node->m_next;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
bool operator== (LockFreeStackIterator <Container, OtherIsConst> const& other)
|
||||
{
|
||||
return m_node == other.m_node;
|
||||
}
|
||||
|
||||
template <bool OtherIsConst>
|
||||
bool operator!= (LockFreeStackIterator <Container, OtherIsConst> const& other)
|
||||
{
|
||||
return m_node != other.m_node;
|
||||
}
|
||||
|
||||
reference operator* () const
|
||||
{
|
||||
return *this->operator-> ();
|
||||
}
|
||||
|
||||
pointer operator-> () const
|
||||
{
|
||||
return static_cast <pointer> (m_node);
|
||||
}
|
||||
|
||||
private:
|
||||
NodePtr m_node;
|
||||
};
|
||||
|
||||
/**
|
||||
Multiple Producer, Multiple Consumer (MPMC) intrusive stack.
|
||||
|
||||
@@ -38,7 +126,7 @@ struct LockFreeStackDefaultTag;
|
||||
|
||||
@ingroup beast_core intrusive
|
||||
*/
|
||||
template <class Element, class Tag = LockFreeStackDefaultTag>
|
||||
template <class Element, class Tag = void>
|
||||
class LockFreeStack : public Uncopyable
|
||||
{
|
||||
public:
|
||||
@@ -55,16 +143,32 @@ public:
|
||||
|
||||
private:
|
||||
friend class LockFreeStack;
|
||||
|
||||
template <class Container, bool IsConst>
|
||||
friend class LockFreeStackIterator;
|
||||
|
||||
// VFALCO TODO Use regular Atomic<>
|
||||
AtomicPointer <Node> m_next;
|
||||
};
|
||||
|
||||
public:
|
||||
LockFreeStack () : m_head (0)
|
||||
typedef Element value_type;
|
||||
typedef Element* pointer;
|
||||
typedef Element& reference;
|
||||
typedef Element const* const_pointer;
|
||||
typedef Element const& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef LockFreeStackIterator <
|
||||
LockFreeStack <Element, Tag>, false> iterator;
|
||||
typedef LockFreeStackIterator <
|
||||
LockFreeStack <Element, Tag>, true> const_iterator;
|
||||
|
||||
LockFreeStack () : m_head (nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
#if 0
|
||||
/** Create a LockFreeStack from another stack.
|
||||
|
||||
The contents of the other stack are atomically acquired.
|
||||
@@ -84,6 +188,17 @@ public:
|
||||
|
||||
m_head = head;
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Return the number of elements in the stack.
|
||||
|
||||
Thread safety:
|
||||
Safe to call from any thread but the value may be inaccurate.
|
||||
*/
|
||||
size_type size () const
|
||||
{
|
||||
return m_size.get ();
|
||||
}
|
||||
|
||||
/** Push a node onto the stack.
|
||||
|
||||
@@ -108,6 +223,8 @@ public:
|
||||
}
|
||||
while (!m_head.compareAndSet (node, head));
|
||||
|
||||
++m_size;
|
||||
|
||||
return first;
|
||||
}
|
||||
|
||||
@@ -134,6 +251,8 @@ public:
|
||||
}
|
||||
while (!m_head.compareAndSet (head, node));
|
||||
|
||||
--m_size;
|
||||
|
||||
return node ? static_cast <Element*> (node) : nullptr;
|
||||
}
|
||||
|
||||
@@ -149,17 +268,43 @@ public:
|
||||
Node* temp = other.m_head.get ();
|
||||
other.m_head.set (m_head.get ());
|
||||
m_head.set (temp);
|
||||
|
||||
std::swap (m_size.value, other.m_size.value);
|
||||
}
|
||||
|
||||
iterator begin ()
|
||||
{
|
||||
return iterator (m_head.get ());
|
||||
}
|
||||
|
||||
iterator end ()
|
||||
{
|
||||
return iterator ();
|
||||
}
|
||||
|
||||
const_iterator begin () const
|
||||
{
|
||||
return const_iterator (m_head.get ());
|
||||
}
|
||||
|
||||
const_iterator end () const
|
||||
{
|
||||
return const_iterator ();
|
||||
}
|
||||
|
||||
const_iterator cbegin () const
|
||||
{
|
||||
return const_iterator (m_head.get ());
|
||||
}
|
||||
|
||||
const_iterator cend () const
|
||||
{
|
||||
return const_iterator ();
|
||||
}
|
||||
|
||||
private:
|
||||
Atomic <size_type> m_size;
|
||||
AtomicPointer <Node> m_head;
|
||||
};
|
||||
|
||||
/*============================================================================*/
|
||||
/** Default tag for LockFreeStack
|
||||
|
||||
@ingroup beast_core intrusive
|
||||
*/
|
||||
struct LockFreeStackDefaultTag { };
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user