/*
This file is a part of libcds - Concurrent Data Structures library
- (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+ (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2017
Source code repo: http://github.com/khizmax/libcds/
Download: http://sourceforge.net/projects/libcds/files/
-
+
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
namespace cds { namespace intrusive {
/// Lock-free free list based on tagged pointers (required double-width CAS)
- /** @ingroup cds_intrusive_helper
+ /** @ingroup cds_intrusive_freelist
+
This variant of \p FreeList is intended for processor architectures that support double-width CAS.
It uses <a href="https://en.wikipedia.org/wiki/Tagged_pointer">tagged pointer</a> technique to solve ABA problem.
atomics::atomic<node *> m_freeListNext;
node()
- : m_freeListNext( nullptr )
- {}
+ {
+ m_freeListNext.store( nullptr, atomics::memory_order_release );
+ }
//@endcond
};
*/
~TaggedFreeList()
{
- assert( empty() );
+ assert( empty());
}
/// Puts \p pNode to the free list
do {
newHead.tag = currentHead.tag + 1;
pNode->m_freeListNext.store( currentHead.ptr, atomics::memory_order_relaxed );
- } while ( cds_unlikely( !m_Head.compare_exchange_weak( currentHead, newHead, atomics::memory_order_release, atomics::memory_order_relaxed )));
+ CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( &pNode->m_freeListNext );
+ } while ( cds_unlikely( !m_Head.compare_exchange_weak( currentHead, newHead, atomics::memory_order_release, atomics::memory_order_acquire )));
}
/// Gets a node from the free list. If the list is empty, returns \p nullptr
tagged_ptr currentHead = m_Head.load( atomics::memory_order_acquire );
tagged_ptr newHead;
while ( currentHead.ptr != nullptr ) {
+ CDS_TSAN_ANNOTATE_HAPPENS_AFTER( ¤tHead.ptr->m_freeListNext );
newHead.ptr = currentHead.ptr->m_freeListNext.load( atomics::memory_order_relaxed );
newHead.tag = currentHead.tag + 1;
if ( cds_likely( m_Head.compare_exchange_weak( currentHead, newHead, atomics::memory_order_release, atomics::memory_order_acquire )))
private:
//@cond
atomics::atomic<tagged_ptr> m_Head;
- //@endcond
+ //@endcond
};
}} // namespace cds::intrusive