X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=blobdiff_plain;f=cds%2Fsync%2Fpool_monitor.h;h=43742382adcbb53e4be442d5fe78408923be3b94;hp=21b94a28b0618196377d2b282db8dac9174a9c0d;hb=HEAD;hpb=c34b46ba50daf781053c4cf6e517d94188c802ed diff --git a/cds/sync/pool_monitor.h b/cds/sync/pool_monitor.h index 21b94a28..43742382 100644 --- a/cds/sync/pool_monitor.h +++ b/cds/sync/pool_monitor.h @@ -1,4 +1,32 @@ -//$$CDS-header$$ +/* + This file is a part of libcds - Concurrent Data Structures library + + (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: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ #ifndef CDSLIB_SYNC_POOL_MONITOR_H #define CDSLIB_SYNC_POOL_MONITOR_H @@ -56,7 +84,7 @@ namespace cds { namespace sync { { ++m_nLockAllocation; int nDiff = static_cast( m_nLockAllocation.get() - m_nLockDeallocation.get()); - if ( nDiff > 0 && m_nMaxAllocated.get() < static_cast( nDiff ) ) + if ( nDiff > 0 && m_nMaxAllocated.get() < static_cast( nDiff )) m_nMaxAllocated = static_cast( nDiff ); } void onLockDeallocation() { ++m_nLockDeallocation;} @@ -79,7 +107,7 @@ namespace cds { namespace sync { Template arguments: - \p LockPool - the @ref cds_memory_pool "pool type". The pool must maintain the objects of type \p std::mutex or similar. The access to the pool is not synchronized. - - \p BackOff - back-off strategy for spinning, default is \p cds::backoff::yield + - \p BackOff - back-off strategy for spinning, default is \p cds::backoff::Default - \p Stat - enable (\p true) or disable (\p false, the default) monitor's internal statistics. How to use @@ -88,7 +116,7 @@ namespace cds { namespace sync { typedef cds::sync::pool_monitor< pool_type > sync_monitor; \endcode */ - template + template class pool_monitor { public: @@ -129,9 +157,10 @@ namespace cds { namespace sync { //@cond node_injection() - : m_RefSpin( 0 ) - , m_pLock( nullptr ) - {} + : m_pLock( nullptr ) + { + m_RefSpin.store( 0, atomics::memory_order_release ); + } ~node_injection() { @@ -141,7 +170,7 @@ namespace cds { namespace sync { bool check_free() const { - return m_pLock == nullptr && m_RefSpin.load( atomics::memory_order_acquire ) == 0; + return m_pLock == nullptr && m_RefSpin.load( atomics::memory_order_relaxed ) == 0; } //@endcond }; @@ -167,7 +196,7 @@ namespace cds { namespace sync { // try lock spin and increment reference counter refspin_type cur = p.m_SyncMonitorInjection.m_RefSpin.load( atomics::memory_order_relaxed ) & ~c_nSpinBit; if ( !p.m_SyncMonitorInjection.m_RefSpin.compare_exchange_weak( cur, cur + c_nRefIncrement + c_nSpinBit, - atomics::memory_order_acquire, atomics::memory_order_relaxed ) ) + atomics::memory_order_acq_rel, atomics::memory_order_acquire )) { back_off bkoff; do { @@ -175,7 +204,7 @@ namespace cds { namespace sync { bkoff(); cur &= ~c_nSpinBit; } while ( !p.m_SyncMonitorInjection.m_RefSpin.compare_exchange_weak( cur, cur + c_nRefIncrement + c_nSpinBit, - atomics::memory_order_acquire, atomics::memory_order_relaxed )); + atomics::memory_order_acq_rel, atomics::memory_order_acquire )); } // spin locked @@ -184,6 +213,7 @@ namespace cds { namespace sync { if ( !pLock ) { assert( cur == 0 ); pLock = p.m_SyncMonitorInjection.m_pLock = m_Pool.allocate( 1 ); + assert( pLock != nullptr ); m_Stat.onLockAllocation(); } @@ -208,7 +238,7 @@ namespace cds { namespace sync { // try lock spin refspin_type cur = p.m_SyncMonitorInjection.m_RefSpin.load( atomics::memory_order_relaxed ) & ~c_nSpinBit; if ( !p.m_SyncMonitorInjection.m_RefSpin.compare_exchange_weak( cur, cur | c_nSpinBit, - atomics::memory_order_acquire, atomics::memory_order_relaxed ) ) + atomics::memory_order_acquire, atomics::memory_order_acquire )) { back_off bkoff; do { @@ -216,7 +246,7 @@ namespace cds { namespace sync { bkoff(); cur &= ~c_nSpinBit; } while ( !p.m_SyncMonitorInjection.m_RefSpin.compare_exchange_weak( cur, cur | c_nSpinBit, - atomics::memory_order_acquire, atomics::memory_order_relaxed )); + atomics::memory_order_acquire, atomics::memory_order_acquire )); } // spin locked now