typedef typename gc::template guarded_ptr< value_type > guarded_ptr; ///< Guarded pointer
+ static CDS_CONSTEXPR const size_t c_nHazardPtrCount = 4; ///< Count of hazard pointer required for the algorithm
+
//@cond
// Rebind traits (split-list support)
template <typename... Options>
marked_node_ptr cur(pos.pCur);
pNode->m_pNext.store( cur, memory_model::memory_order_release );
- return pos.pPrev->compare_exchange_strong( cur, marked_node_ptr(pNode), memory_model::memory_order_release, atomics::memory_order_relaxed );
+ if ( pos.pPrev->compare_exchange_strong( cur, marked_node_ptr(pNode), memory_model::memory_order_release, atomics::memory_order_relaxed ))
+ return true;
+
+ pNode->m_pNext.store( marked_node_ptr(), memory_model::memory_order_relaxed );
+ return false;
}
static bool unlink_node( position& pos )
//@endcond
public:
+ ///@name Forward iterators (only for debugging purpose)
+ //@{
/// Forward iterator
/**
The forward iterator for Michael's list has some features:
may be thrown if the limit of guard count per thread is exceeded.
- The iterator cannot be moved across thread boundary since it contains thread-private GC's guard.
- Iterator ensures thread-safety even if you delete the item the iterator points to. However, in case of concurrent
- deleting operations there is no guarantee that you iterate all item in the list.
+ deleting operations there is no guarantee that you iterate all item in the list.
+ Moreover, a crash is possible when you try to iterate the next element that has been deleted by concurrent thread.
- Therefore, the use of iterators in concurrent environment is not good idea. Use the iterator on the concurrent container
- for debug purpose only.
+ @warning Use this iterator on the concurrent container for debugging purpose only.
The iterator interface:
\code
{
return const_iterator();
}
+ //@}
public:
/// Default constructor initializes empty list
bool insert_at( atomic_node_ptr& refHead, value_type& val )
{
node_type * pNode = node_traits::to_node_ptr( val );
- link_checker::is_empty( pNode );
position pos;
while ( true ) {
bool insert_at( atomic_node_ptr& refHead, value_type& val, Func f )
{
node_type * pNode = node_traits::to_node_ptr( val );
- link_checker::is_empty( pNode );
position pos;
while ( true ) {