From 277e32bb1e4b3910ebdd4a6b2052d5bd3fad28b0 Mon Sep 17 00:00:00 2001 From: Vinnie Falco Date: Sat, 14 Sep 2013 16:04:28 -0700 Subject: [PATCH] Add LockFreeStack iterators --- .../containers/beast_LockFreeStack.h | 163 +++++++++++++++++- 1 file changed, 154 insertions(+), 9 deletions(-) diff --git a/modules/beast_core/containers/beast_LockFreeStack.h b/modules/beast_core/containers/beast_LockFreeStack.h index f09261d02..734a7d2dd 100644 --- a/modules/beast_core/containers/beast_LockFreeStack.h +++ b/modules/beast_core/containers/beast_LockFreeStack.h @@ -23,6 +23,94 @@ struct LockFreeStackDefaultTag; /*============================================================================*/ + +template +class LockFreeStackIterator + : public std::iterator < + std::forward_iterator_tag, + typename Container::value_type, + typename Container::difference_type, + typename mpl::IfCond ::type, + typename mpl::IfCond ::type> +{ +protected: + typedef typename Container::Node Node; + typedef typename mpl::IfCond ::type NodePtr; + +public: + typedef typename Container::value_type value_type; + typedef typename mpl::IfCond ::type pointer; + typedef typename mpl::IfCond ::type reference; + + LockFreeStackIterator () + : m_node () + { + } + + LockFreeStackIterator (NodePtr node) + : m_node (node) + { + } + + template + explicit LockFreeStackIterator (LockFreeStackIterator const& other) + : m_node (other.m_node) + { + } + + LockFreeStackIterator& operator= (NodePtr node) + { + m_node = node; + return static_cast (*this); + } + + LockFreeStackIterator& operator++ () + { + m_node = m_node->m_next; + return static_cast (*this); + } + + LockFreeStackIterator operator++ (int) + { + LockFreeStackIterator result (*this); + m_node = m_node->m_next; + return result; + } + + template + bool operator== (LockFreeStackIterator const& other) + { + return m_node == other.m_node; + } + + template + bool operator!= (LockFreeStackIterator const& other) + { + return m_node != other.m_node; + } + + reference operator* () const + { + return *this->operator-> (); + } + + pointer operator-> () const + { + return static_cast (m_node); + } + +private: + NodePtr m_node; +}; + /** Multiple Producer, Multiple Consumer (MPMC) intrusive stack. @@ -38,7 +126,7 @@ struct LockFreeStackDefaultTag; @ingroup beast_core intrusive */ -template +template class LockFreeStack : public Uncopyable { public: @@ -55,16 +143,32 @@ public: private: friend class LockFreeStack; + + template + friend class LockFreeStackIterator; // VFALCO TODO Use regular Atomic<> AtomicPointer 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 , false> iterator; + typedef LockFreeStackIterator < + LockFreeStack , 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 (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 m_size; AtomicPointer m_head; }; -/*============================================================================*/ -/** Default tag for LockFreeStack - - @ingroup beast_core intrusive -*/ -struct LockFreeStackDefaultTag { }; - #endif