X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=cds%2Furcu%2Fdetails%2Fgp.h;h=b8173c4c1c65590dc1fc45c3048ecd75490fb777;hb=HEAD;hp=ad2fb01a26fdeb066c62896e3a34a5f300611465;hpb=dcfc955eac8d172e1da77d150edc6e17b54ef5a0;p=libcds.git diff --git a/cds/urcu/details/gp.h b/cds/urcu/details/gp.h index ad2fb01a..b8173c4c 100644 --- a/cds/urcu/details/gp.h +++ b/cds/urcu/details/gp.h @@ -1,7 +1,7 @@ /* 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/ @@ -43,7 +43,7 @@ namespace cds { namespace urcu { namespace details { template inline gp_thread_gc::gp_thread_gc() { - if ( !threading::Manager::isThreadAttached() ) + if ( !threading::Manager::isThreadAttached()) cds::threading::Manager::attachThread(); } @@ -68,12 +68,13 @@ namespace cds { namespace urcu { namespace details { uint32_t tmp = pRec->m_nAccessControl.load( atomics::memory_order_relaxed ); if ( (tmp & rcu_class::c_nNestMask) == 0 ) { pRec->m_nAccessControl.store( gp_singleton::instance()->global_control_word(atomics::memory_order_relaxed), - atomics::memory_order_release ); - atomics::atomic_thread_fence( atomics::memory_order_acquire ); - CDS_COMPILER_RW_BARRIER; + atomics::memory_order_relaxed ); + + atomics::atomic_thread_fence( atomics::memory_order_seq_cst ); } else { - pRec->m_nAccessControl.fetch_add( 1, atomics::memory_order_relaxed ); + // nested lock + pRec->m_nAccessControl.store( tmp + 1, atomics::memory_order_relaxed ); } } @@ -83,8 +84,15 @@ namespace cds { namespace urcu { namespace details { thread_record * pRec = get_thread_record(); assert( pRec != nullptr ); + uint32_t tmp = pRec->m_nAccessControl.load( atomics::memory_order_relaxed ); + assert( (tmp & rcu_class::c_nNestMask) > 0 ); + +#if CDS_COMPILER == CDS_COMPILER_CLANG && CDS_COMPILER_VERSION < 30800 + // CLang 3.6-3.7: some tests of intrusive::FeldmanHashSet based on general-purpose RCU + // are failed even in single-threaded mode (unit tests) without magic compiler barrier below CDS_COMPILER_RW_BARRIER; - pRec->m_nAccessControl.fetch_sub( 1, atomics::memory_order_release ); +#endif + pRec->m_nAccessControl.store( tmp - 1, atomics::memory_order_release ); } template @@ -114,7 +122,7 @@ namespace cds { namespace urcu { namespace details { m_nGlobalControl.fetch_xor( general_purpose_rcu::c_nControlBit, atomics::memory_order_seq_cst ); for ( thread_record * pRec = m_ThreadList.head( atomics::memory_order_acquire ); pRec; pRec = pRec->m_list.m_pNext ) { - while ( pRec->m_list.m_idOwner.load( atomics::memory_order_acquire ) != nullThreadId && check_grace_period( pRec ) ) { + while ( pRec->m_list.m_idOwner.load( atomics::memory_order_acquire ) != nullThreadId && check_grace_period( pRec )) { bkoff(); CDS_COMPILER_RW_BARRIER; }