[TSan] Fixed data race: added compiler barriers, tuned memory ordering
[libcds.git] / cds / intrusive / details / split_list_base.h
index f6b410846d6ee759e796c75115e377536397b494..d54f26462f0d0fd22b8d5a9b4fde5131099016c0 100644 (file)
@@ -649,8 +649,9 @@ namespace cds { namespace intrusive {
             /// Allocates auxiliary node; can return \p nullptr if the table exhausted
             aux_node_type* alloc_aux_node()
             {
+                aux_node_segment* aux_segment = m_auxNodeList.load( memory_model::memory_order_acquire );
+
                 for ( ;; ) {
-                    aux_node_segment* aux_segment = m_auxNodeList.load( memory_model::memory_order_relaxed );
                     assert( aux_segment != nullptr );
 
                     // try to allocate from current aux segment
@@ -671,7 +672,9 @@ namespace cds { namespace intrusive {
                     aux_node_segment* new_aux_segment = allocate_aux_segment();
                     new_aux_segment->next_segment = aux_segment;
                     new_aux_segment->aux_node_count.fetch_add( 1, memory_model::memory_order_relaxed );
-                    if ( m_auxNodeList.compare_exchange_strong( aux_segment, new_aux_segment, memory_model::memory_order_relaxed, atomics::memory_order_relaxed ))
+                    CDS_COMPILER_RW_BARRIER;
+
+                    if ( m_auxNodeList.compare_exchange_strong( aux_segment, new_aux_segment, memory_model::memory_order_release, atomics::memory_order_acquire ))
                         return new( new_aux_segment->segment()) aux_node_type();
 
                     free_aux_segment( new_aux_segment );