Uses different pass count for different parallel queue test cases
[libcds.git] / cds / sync / pool_monitor.h
index 21b94a28b0618196377d2b282db8dac9174a9c0d..43742382adcbb53e4be442d5fe78408923be3b94 100644 (file)
@@ -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
 
 #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<int>( m_nLockAllocation.get() - m_nLockDeallocation.get());
             {
                 ++m_nLockAllocation;
                 int nDiff = static_cast<int>( m_nLockAllocation.get() - m_nLockDeallocation.get());
-                if ( nDiff > 0 && m_nMaxAllocated.get() < static_cast<typename event_counter::value_type>( nDiff ) )
+                if ( nDiff > 0 && m_nMaxAllocated.get() < static_cast<typename event_counter::value_type>( nDiff ))
                     m_nMaxAllocated = static_cast<typename event_counter::value_type>( nDiff );
             }
             void onLockDeallocation()   { ++m_nLockDeallocation;}
                     m_nMaxAllocated = static_cast<typename event_counter::value_type>( 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.
         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.
 
         <b>How to use</b>
         - \p Stat - enable (\p true) or disable (\p false, the default) monitor's internal statistics.
 
         <b>How to use</b>
@@ -88,7 +116,7 @@ namespace cds { namespace sync {
         typedef cds::sync::pool_monitor< pool_type > sync_monitor;
         \endcode
     */
         typedef cds::sync::pool_monitor< pool_type > sync_monitor;
         \endcode
     */
-    template <class LockPool, typename BackOff = cds::backoff::yield, bool Stat = false >
+    template <class LockPool, typename BackOff = cds::backoff::Default, bool Stat = false >
     class pool_monitor
     {
     public:
     class pool_monitor
     {
     public:
@@ -129,9 +157,10 @@ namespace cds { namespace sync {
 
             //@cond
             node_injection()
 
             //@cond
             node_injection()
-                : m_RefSpin( 0 )
-                , m_pLock( nullptr )
-            {}
+                : m_pLock( nullptr )
+            {
+                m_RefSpin.store( 0, atomics::memory_order_release );
+            }
 
             ~node_injection()
             {
 
             ~node_injection()
             {
@@ -141,7 +170,7 @@ namespace cds { namespace sync {
 
             bool check_free() const
             {
 
             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
         };
             }
             //@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,
             // 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 {
             {
                 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,
                     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
             }
 
             // 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 );
             if ( !pLock ) {
                 assert( cur == 0 );
                 pLock = p.m_SyncMonitorInjection.m_pLock = m_Pool.allocate( 1 );
+                assert( pLock != nullptr );
                 m_Stat.onLockAllocation();
             }
 
                 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,
             // 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 {
             {
                 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,
                     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
             }
 
             // spin locked now