issue #76: added cds::atomicity::cache_friendly_item_counter to avoid false sharing
authorkhizmax <libcds.dev@gmail.com>
Wed, 10 May 2017 21:01:35 +0000 (00:01 +0300)
committerkhizmax <libcds.dev@gmail.com>
Wed, 10 May 2017 21:01:35 +0000 (00:01 +0300)
issue #76: MichaelHashSet/Map: removed static_assert for empty_item_counter

43 files changed:
cds/algo/atomic.h
cds/container/details/bronson_avltree_base.h
cds/container/details/ellen_bintree_base.h
cds/container/details/iterable_list_base.h
cds/container/details/lazy_list_base.h
cds/container/details/michael_list_base.h
cds/container/michael_map.h
cds/container/michael_map_nogc.h
cds/container/michael_map_rcu.h
cds/container/michael_set.h
cds/container/michael_set_nogc.h
cds/container/michael_set_rcu.h
cds/intrusive/details/ellen_bintree_base.h
cds/intrusive/details/feldman_hashset_base.h
cds/intrusive/details/iterable_list_base.h
cds/intrusive/details/lazy_list_base.h
cds/intrusive/details/michael_list_base.h
cds/intrusive/details/michael_set_base.h
cds/intrusive/details/skip_list_base.h
cds/intrusive/details/split_list_base.h
cds/intrusive/impl/skip_list.h
cds/intrusive/michael_set.h
cds/intrusive/michael_set_nogc.h
cds/intrusive/michael_set_rcu.h
cds/intrusive/skip_list_nogc.h
cds/intrusive/skip_list_rcu.h
cds/intrusive/split_list.h
cds/intrusive/split_list_nogc.h
cds/intrusive/split_list_rcu.h
cds/opt/options.h
test/stress/map/map_type_bronson_avltree.h
test/stress/map/map_type_ellen_bintree.h
test/stress/map/map_type_feldman_hashmap.h
test/stress/map/map_type_michael.h
test/stress/map/map_type_skip_list.h
test/stress/map/map_type_split_list.h
test/stress/set/set_type_ellen_bintree.h
test/stress/set/set_type_feldman_hashset.h
test/stress/set/set_type_michael.h
test/stress/set/set_type_skip_list.h
test/stress/set/set_type_split_list.h
test/unit/intrusive-list/intrusive_michael_dhp.cpp
test/unit/intrusive-list/intrusive_michael_hp.cpp

index 56b54ef7e51960b41ccbe75bdda23e3474be2471..dd8544deb4e2859eedb5122f0f7191c7c9c41b8d 100644 (file)
@@ -32,6 +32,7 @@
 #define CDSLIB_CXX11_ATOMIC_H
 
 #include <cds/details/defs.h>
+#include <cds/user_setup/cache_line.h>
 
 namespace cds {
 
@@ -194,7 +195,9 @@ namespace cds {
         /// Atomic item counter
         /**
             This class is simplified interface around \p std::atomic_size_t.
-            The class supports getting of current value of the counter and increment/decrement its value.
+            The class supports getting current value of the counter and increment/decrement its value.
+
+            See alûo improved version that eliminates false sharing: \p cache_friendly_item_counter.
         */
         class item_counter
         {
@@ -204,7 +207,7 @@ namespace cds {
 
         private:
             //@cond
-            atomic_type                         m_Counter   ;   ///< Atomic item counter
+            atomic_type     m_Counter;   ///< Atomic item counter
             //@endcond
 
         public:
@@ -302,6 +305,121 @@ namespace cds {
             }
         };
 
+        /// Atomic cache-friendly item counter
+        /**
+            Atomic item counter with cache-line padding to avoid false sharing.
+            Adding cache-line padding before and after atomic counter eliminates the contention
+            in read path of many containers and can notably improve search operations in sets/maps.
+        */
+        class cache_friendly_item_counter
+        {
+        public:
+            typedef atomics::atomic_size_t   atomic_type;   ///< atomic type used
+            typedef size_t counter_type;                    ///< Integral item counter type (size_t)
+
+        private:
+            //@cond
+            char            pad1_[cds::c_nCacheLineSize];
+            atomic_type     m_Counter;   ///< Atomic item counter
+            char            pad2_[cds::c_nCacheLineSize - sizeof( atomic_type )];
+            //@endcond
+
+        public:
+            /// Default ctor initializes the counter to zero.
+            cache_friendly_item_counter()
+                : m_Counter(counter_type(0))
+            {}
+
+            /// Returns current value of the counter
+            counter_type value(atomics::memory_order order = atomics::memory_order_relaxed) const
+            {
+                return m_Counter.load( order );
+            }
+
+            /// Same as \ref value() with relaxed memory ordering
+            operator counter_type() const
+            {
+                return value();
+            }
+
+            /// Returns underlying atomic interface
+            atomic_type& getAtomic()
+            {
+                return m_Counter;
+            }
+
+            /// Returns underlying atomic interface (const)
+            const atomic_type& getAtomic() const
+            {
+                return m_Counter;
+            }
+
+            /// Increments the counter. Semantics: postincrement
+            counter_type inc(atomics::memory_order order = atomics::memory_order_relaxed )
+            {
+                return m_Counter.fetch_add( 1, order );
+            }
+
+            /// Increments the counter. Semantics: postincrement
+            counter_type inc( counter_type count, atomics::memory_order order = atomics::memory_order_relaxed )
+            {
+                return m_Counter.fetch_add( count, order );
+            }
+
+            /// Decrements the counter. Semantics: postdecrement
+            counter_type dec(atomics::memory_order order = atomics::memory_order_relaxed)
+            {
+                return m_Counter.fetch_sub( 1, order );
+            }
+
+            /// Decrements the counter. Semantics: postdecrement
+            counter_type dec( counter_type count, atomics::memory_order order = atomics::memory_order_relaxed )
+            {
+                return m_Counter.fetch_sub( count, order );
+            }
+
+            /// Preincrement
+            counter_type operator ++()
+            {
+                return inc() + 1;
+            }
+            /// Postincrement
+            counter_type operator ++(int)
+            {
+                return inc();
+            }
+
+            /// Predecrement
+            counter_type operator --()
+            {
+                return dec() - 1;
+            }
+            /// Postdecrement
+            counter_type operator --(int)
+            {
+                return dec();
+            }
+
+            /// Increment by \p count
+            counter_type operator +=( counter_type count )
+            {
+                return inc( count ) + count;
+            }
+
+            /// Decrement by \p count
+            counter_type operator -=( counter_type count )
+            {
+                return dec( count ) - count;
+            }
+
+            /// Resets count to 0
+            void reset(atomics::memory_order order = atomics::memory_order_relaxed)
+            {
+                m_Counter.store( 0, order );
+            }
+        };
+
+
         /// Empty item counter
         /**
             This class may be used instead of \ref item_counter when you do not need full \ref item_counter interface.
index 49cfb877fceda7b350ec9a88d43bcbbc82af952a..5230164570ada0d0a10b1e1762e5eb73a6f29aac 100644 (file)
@@ -440,7 +440,7 @@ namespace cds { namespace container {
             /// Item counter
             /**
                 The type for item counter, by default it is disabled (\p atomicity::empty_item_counter).
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter.
             */
             typedef atomicity::empty_item_counter     item_counter;
 
@@ -493,7 +493,7 @@ namespace cds { namespace container {
             - \p bronson_avltree::relaxed_insert - enable (\p true) or disable (\p false, the default)
                 @ref bronson_avltree::relaxed_insert "relaxed insertion"
             - \p opt::item_counter - the type of item counting feature, by default it is disabled (\p atomicity::empty_item_counter)
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p opt::stat - internal statistics, by default it is disabled (\p bronson_avltree::empty_stat)
index 91e2e2b25e83f3dab55f4615f8b8b917ada8c359..5daf245ac0f9574b944558e98238e175c1aafda1 100644 (file)
@@ -162,7 +162,7 @@ namespace cds { namespace container {
             /// Item counter
             /**
                 The type for item counter, by default it is disabled (\p atomicity::empty_item_counter).
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             */
             typedef atomicity::empty_item_counter     item_counter;
 
@@ -247,7 +247,7 @@ namespace cds { namespace container {
                 If the option is not specified, \p %opt::less is used.
             - \p opt::less - specifies binary predicate used for key compare. At least \p %opt::compare or \p %opt::less should be defined.
             - \p opt::item_counter - the type of item counter, default is disabled (\p atomicity::empty_item_counter).
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p opt::allocator - the allocator for \ref ellen_bintree::node "leaf nodes" which contains data.
@@ -287,7 +287,7 @@ namespace cds { namespace container {
                 If the option is not specified, \p %opt::less is used.
             - \p opt::less - specifies binary predicate used for key compare. At least \p %opt::compare or \p %opt::less should be defined.
             - \p opt::item_counter - the type of item counter, default is disabled (\p atomicity::empty_item_counter).
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p opt::allocator - the allocator used for \ref ellen_bintree::map_node "leaf nodes" which contains data.
index 8200be395c57e599ccc97a8fdcafc4310765cf59..699180192b39fac32c59f90585a3ab1594ce140d 100644 (file)
@@ -78,7 +78,7 @@ namespace cds { namespace container {
             /// Back-off strategy
             typedef intrusive::iterable_list::traits::back_off back_off;
 
-            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter or \p atomicity::cache_friendly_item_counter to enable item counting
             typedef intrusive::iterable_list::traits::item_counter item_counter;
 
             /// Internal statistics
@@ -118,7 +118,7 @@ namespace cds { namespace container {
             - \p opt::node_allocator - node allocator, default is \p std::allocator.
             - \p opt::back_off - back-off strategy used. If the option is not specified, the \p cds::backoff::Default is used.
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                 To enable item counting use \p atomicity::item_counter.
+                 To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter.
             - \p opt::stat - internal statistics. By default, it is disabled (\p iterable_list::empty_stat).
                 To enable it use \p iterable_list::stat
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
index d454435578d22ef0d1e9184b1a7f457b437119b8..95e6f2f210bb7f90386649c05bfd3c492907bfa4 100644 (file)
@@ -144,7 +144,7 @@ namespace cds { namespace container {
                 Note: unordering feature is not fully supported yet.
             - \p opt::back_off - back-off strategy used. If the option is not specified, \p cds::backoff::Default is used.
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                To enable item counting use \p atomicity::item_counter.
+                To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::stat - internal statistics. By default, it is disabled (\p lazy_list::empty_stat).
                 To enable it use \p lazy_list::stat
             - \p opt::allocator - the allocator used for creating and freeing list's item. Default is \ref CDS_DEFAULT_ALLOCATOR macro.
index fc10857a76c24cebbd8643926401d5a440a8a968..866f4a8fecdce5f51bd62156ebfe8095822d0240 100644 (file)
@@ -74,7 +74,7 @@ namespace cds { namespace container {
             /// Back-off strategy
             typedef cds::backoff::empty             back_off;
 
-            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter or \p atomicity::cache_friendly_item_counter to enable item counting
             typedef atomicity::empty_item_counter     item_counter;
 
             /// Internal statistics
@@ -113,7 +113,7 @@ namespace cds { namespace container {
             - \p opt::allocator - an allocator, default is \p CDS_DEFAULT_ALLOCATOR
             - \p opt::back_off - back-off strategy used. If the option is not specified, the \p cds::backoff::Default is used.
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                 To enable item counting use \p atomicity::item_counter.
+                 To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::stat - internal statistics. By default, it is disabled (\p michael_list::empty_stat).
                 To enable it use \p michael_list::stat
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
index 22b2dccf8ed6898c650b04dc3da83192edab55a6..9f851f696d8fefc1d5d76b350b87b9586245e780 100644 (file)
@@ -171,10 +171,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert( std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert( !std::is_same<item_counter, atomicity::empty_item_counter>::value,
-                        "atomicity::empty_item_counter is not allowed as a item counter");
-
         static CDS_CONSTEXPR const size_t c_nHazardPtrCount = ordered_list::c_nHazardPtrCount; ///< Count of hazard pointer required
 
         //@cond
@@ -194,8 +190,8 @@ namespace cds { namespace container {
         //@cond
         const size_t            m_nHashBitmask;
         internal_bucket_type*   m_Buckets;     ///< bucket table
-        item_counter            m_ItemCounter; ///< Item counter
         hash                    m_HashFunctor; ///< Hash functor
+        item_counter            m_ItemCounter; ///< Item counter
         stat                    m_Stat;        ///< Internal statistics
         //@endcond
 
@@ -920,8 +916,8 @@ namespace cds { namespace container {
 
         /// Checks if the map is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the map is empty.
-            Thus, the correct item counting is an important part of the map implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -929,6 +925,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the map
+        /**
+            If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index 7d3c2e847f93ddb95f0772bcf563cc59a1a94c9f..04299da93a61e64ab3255ab5322b2653f74c18a5 100644 (file)
@@ -79,10 +79,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -107,10 +103,10 @@ namespace cds { namespace container {
     protected:
         //@cond
         const size_t    m_nHashBitmask;
-        item_counter    m_ItemCounter; ///< Item counter
-        hash            m_HashFunctor; ///< Hash functor
+        hash            m_HashFunctor;      ///< Hash functor
         internal_bucket_type*   m_Buckets;  ///< bucket table
-        stat            m_Stat; ///< Internal statistics
+        item_counter    m_ItemCounter;      ///< Item counter
+        stat            m_Stat;             ///< Internal statistics
         //@endcond
 
     protected:
@@ -530,8 +526,8 @@ namespace cds { namespace container {
 
         /// Checks whether the map is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the map is empty.
-            Thus, the correct item counting feature is an important part of Michael's map implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -539,6 +535,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the map
+        /**
+            If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index d036e0ab3352c1a0b2cf3e2e5741ae10312ff824..93198b8d33c82855b8abb3156e81e350065121f9 100644 (file)
@@ -109,10 +109,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, cds::atomicity::empty_item_counter>::value,
-            "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -137,10 +133,10 @@ namespace cds { namespace container {
     protected:
         //@cond
         const size_t    m_nHashBitmask;
-        item_counter    m_ItemCounter; ///< Item counter
-        hash            m_HashFunctor; ///< Hash functor
-        internal_bucket_type *  m_Buckets;  ///< bucket table
-        stat            m_Stat; ///< Internal statistics
+        hash            m_HashFunctor;      ///< Hash functor
+        internal_bucket_type*  m_Buckets;   ///< bucket table
+        item_counter    m_ItemCounter;      ///< Item counter
+        stat            m_Stat;             ///< Internal statistics
         //@endcond
 
     protected:
@@ -791,8 +787,8 @@ namespace cds { namespace container {
 
         /// Checks if the map is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the map is empty.
-            Thus, the correct item counting is an important part of the map implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -800,6 +796,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the map
+        /**
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index cdd383f4694d1831f40945a5288fb903632a3036..fb23c442295181c517e7fa2917fc88a8ecf105ea 100644 (file)
@@ -188,10 +188,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert( std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert( !std::is_same<item_counter, atomicity::empty_item_counter>::value,
-                        "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
 
@@ -213,8 +209,8 @@ namespace cds { namespace container {
         //@cond
         size_t const           m_nHashBitmask;
         internal_bucket_type * m_Buckets;     ///< bucket table
-        item_counter           m_ItemCounter; ///< Item counter
         hash                   m_HashFunctor; ///< Hash functor
+        item_counter           m_ItemCounter; ///< Item counter
         stat                   m_Stat;        ///< Internal statistics
         //@endcond
 
@@ -868,8 +864,8 @@ namespace cds { namespace container {
 
         /// Checks if the set is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -877,6 +873,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the set
+        /**
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index 6f1d293d86f8975e205f73ff2a314fe2f0a56f06..efb6901b38174d9bf9cdf453969013b95cbb2e40 100644 (file)
@@ -76,10 +76,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -115,10 +111,10 @@ namespace cds { namespace container {
     protected:
         //@cond
         const size_t    m_nHashBitmask;
-        item_counter    m_ItemCounter;      ///< Item counter
         hash            m_HashFunctor;      ///< Hash functor
         internal_bucket_type*   m_Buckets;  ///< bucket table
-        stat            m_Stat; ///< Internal statistics
+        item_counter    m_ItemCounter;      ///< Item counter
+        stat            m_Stat;             ///< Internal statistics
         //@endcond
 
     public:
@@ -379,8 +375,8 @@ namespace cds { namespace container {
 
         /// Checks if the set is empty
         /**
-            The emptiness is checked by the item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -388,6 +384,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the set
+        /**
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index 75ab34dae228df8b4ea0982dfeb99fc61223f3a0..34bc0c2bbf33058f4153cdcbffc8a2cb5d6ee947 100644 (file)
@@ -159,9 +159,6 @@ namespace cds { namespace container {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "atomicity::empty_item_counter is not allowed as a item counter");
-
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
 
@@ -192,9 +189,9 @@ namespace cds { namespace container {
         typedef typename allocator::template rebind< internal_bucket_type >::other bucket_table_allocator;
 
         const size_t            m_nHashBitmask;
-        item_counter            m_ItemCounter; ///< Item counter
         hash                    m_HashFunctor; ///< Hash functor
         internal_bucket_type*   m_Buckets;     ///< bucket table
+        item_counter            m_ItemCounter; ///< Item counter
         stat                    m_Stat;        ///< Internal statistics
         //@endcond
 
@@ -743,8 +740,8 @@ namespace cds { namespace container {
 
         /// Checks if the set is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -752,6 +749,10 @@ namespace cds { namespace container {
         }
 
         /// Returns item count in the set
+        /**
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index 75c6da8a103d23d4cdbaa45eea7e78e09bdc3e65..ed03e3b8ca28196aa8df57596503789a432bd18e 100644 (file)
@@ -515,7 +515,7 @@ namespace cds { namespace intrusive {
             /// Item counter
             /**
                 The type for item counter, by default it is disabled (\p atomicity::empty_item_counter).
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             */
             typedef atomicity::empty_item_counter item_counter;
 
@@ -582,7 +582,7 @@ namespace cds { namespace intrusive {
             - \p opt::disposer - the functor used for dispose removed nodes. Default is \p opt::v::empty_disposer. Due the nature
                 of GC schema the disposer may be called asynchronously. The disposer is used only for leaf nodes.
             - \p opt::item_counter - the type of item counting feature, by default it is disabled (\p atomicity::empty_item_counter)
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p ellen_bintree::update_desc_allocator - an allocator of \ref ellen_bintree::update_desc "update descriptors",
index 626e5bc79f2466e9c2b29b8a5ef350fa60a5758f..60b00a629dd133f2156a348c17a7c592dca0bc1e 100644 (file)
@@ -243,7 +243,7 @@ namespace cds { namespace intrusive {
                 the \p empty() member function depends on correct item counting.
                 Therefore, \p atomicity::empty_item_counter is not allowed as a type of the option.
 
-                Default is \p atomicity::item_counter.
+                Default is \p atomicity::item_counter. To avoid false sharing you can aldo use \p atomicity::cache_friendly_item_counter
             */
             typedef cds::atomicity::item_counter item_counter;
 
@@ -301,7 +301,7 @@ namespace cds { namespace intrusive {
                  The item counting is an important part of \p FeldmanHashSet algorithm:
                  the \p empty() member function depends on correct item counting.
                  Therefore, \p atomicity::empty_item_counter is not allowed as a type of the option.
-                 Default is \p atomicity::item_counter.
+                 Default is \p atomicity::item_counter. To avoid false sharing you can use or \p atomicity::cache_friendly_item_counter
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p opt::stat - internal statistics. By default, it is disabled (\p feldman_hashset::empty_stat).
index 3c69cf9fd3ba2e3182975d492a5fc007ade609fa..113b72d660aea915eba19f7289569f27711c51c2 100644 (file)
@@ -212,7 +212,7 @@ namespace cds { namespace intrusive {
             */
             typedef empty_stat                      stat;
 
-            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter or \p atomicity::cache_friendly_item_counter to enable item counting
             typedef atomicity::empty_item_counter   item_counter;
 
             /// C++ memory ordering model
@@ -234,7 +234,7 @@ namespace cds { namespace intrusive {
             - \p opt::disposer - the functor used for disposing removed items. Default is \p opt::v::empty_disposer. Due the nature
                 of GC schema the disposer may be called asynchronously.
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                 To enable item counting use \p atomicity::item_counter.
+                 To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::stat - internal statistics. By default, it is disabled (\p iterable_list::empty_stat).
                 To enable it use \p iterable_list::stat
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
index bda8b449ce9d43ba5e696b4cae4572eacebb6631..bf3731c7e46832b5bb20538fd677d143ef694835 100644 (file)
@@ -352,7 +352,7 @@ namespace cds { namespace intrusive {
             /// Disposer for removing items
             typedef opt::v::empty_disposer          disposer;
 
-            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter or \p atomicity::cache_friendly_item_counter to enable item counting
             typedef atomicity::empty_item_counter     item_counter;
 
             /// Internal statistics
@@ -399,7 +399,7 @@ namespace cds { namespace intrusive {
                 of GC schema the disposer may be called asynchronously.
             - \p opt::link_checker - the type of node's link fields checking. Default is \p opt::debug_check_link
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                 To enable item counting use \p atomicity::item_counter.
+                 To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::stat - internal statistics. By default, it is disabled (\p lazy_list::empty_stat).
                 To enable it use \p lazy_list::stat
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
index 48e63c780821fbd33f65a2f342535d330b7a0c9a..c789be08ce1ab624668cd08391c0a63d541aea2f 100644 (file)
@@ -318,7 +318,7 @@ namespace cds { namespace intrusive {
             /// Disposer for removing items
             typedef opt::v::empty_disposer          disposer;
 
-            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter to enable item counting
+            /// Item counting feature; by default, disabled. Use \p cds::atomicity::item_counter or \p atomicity::cache_friendly_item_counter to enable item counting
             typedef atomicity::empty_item_counter   item_counter;
 
             /// Internal statistics
@@ -361,7 +361,7 @@ namespace cds { namespace intrusive {
                 of GC schema the disposer may be called asynchronously.
             - \p opt::link_checker - the type of node's link fields checking. Default is \p opt::debug_check_link
             - \p opt::item_counter - the type of item counting feature. Default is disabled (\p atomicity::empty_item_counter).
-                 To enable item counting use \p atomicity::item_counter.
+                 To enable item counting use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::stat - internal statistics. By default, it is disabled (\p michael_list::empty_stat).
                 To enable it use \p michael_list::stat
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
index 9bf2cd7368f2601a1a176f0216ecda3e95a75c0b..8e63cf3849b49d5f38382cb7badd601b047d734c 100644 (file)
@@ -58,9 +58,10 @@ namespace cds { namespace intrusive {
             /**
                 The item counting is an important part of \p MichaelHashSet algorithm:
                 the \p empty() member function depends on correct item counting.
-                Therefore, \p atomicity::empty_item_counter is not allowed as a type of the option.
+                You may use \p atomicity::empty_item_counter if don't need \p empty() and \p size()
+                member functions.
 
-                Default is \p atomicity::item_counter.
+                Default is \p atomicity::item_counter; to avoid false sharing you may use \p atomicity::cache_friendly_item_counter
             */
             typedef cds::atomicity::item_counter item_counter;
 
index c902c770f5a473bf82043e88a4d106e624eaf732..e2f4d52d84553705429483552f38a7cc7d05153c 100644 (file)
@@ -613,7 +613,7 @@ namespace cds { namespace intrusive {
             /**
                 The type for item counting feature.
                 By default, item counting is disabled (\p atomicity::empty_item_counter),
-                \p atomicity::item_counter enables it.
+                \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter enables it.
             */
             typedef atomicity::empty_item_counter     item_counter;
 
@@ -680,7 +680,7 @@ namespace cds { namespace intrusive {
             - \p opt::disposer - the functor used for dispose removed items. Default is \p opt::v::empty_disposer. Due the nature
                 of GC schema the disposer may be called asynchronously.
             - \p opt::item_counter - the type of item counting feature. Default is disabled, i.e. \p atomicity::empty_item_counter.
-                To enable it use \p atomicity::item_counter
+                To enable it use \p atomicity::item_counter or \p atomicity::cache_friendly_item_counter
             - \p opt::memory_model - C++ memory ordering model. Can be \p opt::v::relaxed_ordering (relaxed memory model, the default)
                 or \p opt::v::sequential_consistent (sequentially consisnent memory model).
             - \p skip_list::random_level_generator - random level generator. Can be \p skip_list::xor_shift,
index 71d47744a16ee6dc9f71979e3c23a31fe6519f59..e4ef11adf928aa909927a14941bba0ad41a61618 100644 (file)
@@ -257,7 +257,7 @@ namespace cds { namespace intrusive {
                 the <tt>empty()</tt> member function depends on correct item counting.
                 Therefore, \p cds::atomicity::empty_item_counter is not allowed as a type of the option.
 
-                Default is \p cds::atomicity::item_counter.
+                Default is \p cds::atomicity::item_counter; to avoid false sharing you may use \p atomicity::cache_friendly_item_counter
             */
             typedef cds::atomicity::item_counter item_counter;
 
index 8ee2d69e2d88744386a439d35fe7f540932bef04..c8cc11fdc33a60322a47aee11d17ab3b5b920afd 100644 (file)
@@ -1778,9 +1778,9 @@ namespace cds { namespace intrusive {
         //@cond
         skip_list::details::head_node< node_type > m_Head;   ///< head tower (max height)
 
-        item_counter                m_ItemCounter;    ///< item counter
         random_level_generator      m_RandomLevelGen; ///< random level generator instance
         atomics::atomic<unsigned int> m_nHeight;      ///< estimated high level
+        item_counter                m_ItemCounter;    ///< item counter
         mutable stat                m_Stat;           ///< internal statistics
         //@endcond
     };
index 8e21f85f7fe5213fdd4845810d3cbbf8534b88cd..c1daccfc60febc808ab44da0d6613f7168b437b8 100644 (file)
@@ -271,10 +271,6 @@ namespace cds { namespace intrusive {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "cds::atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -929,8 +925,8 @@ namespace cds { namespace intrusive {
 
         /// Checks if the set is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -938,6 +934,10 @@ namespace cds { namespace intrusive {
         }
 
         /// Returns item count in the set
+        /**
+            If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index cd6b675b45ceac8a52f376f600a85a1346fee57b..883e8526bfe048ab3e5aec63d725a62128b737ff 100644 (file)
@@ -77,10 +77,6 @@ namespace cds { namespace intrusive {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -421,8 +417,8 @@ namespace cds { namespace intrusive {
 
         /// Checks if the set is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -430,6 +426,10 @@ namespace cds { namespace intrusive {
         }
 
         /// Returns item count in the set
+        /**
+            If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index b105a8efd16b88ef3bbd95e7dab3cdb49f38c682..43a26138460ddeacce0b46efe27487bcda7ccc9f 100644 (file)
@@ -124,10 +124,6 @@ namespace cds { namespace intrusive {
         // GC and OrderedList::gc must be the same
         static_assert(std::is_same<gc, typename ordered_list::gc>::value, "GC and OrderedList::gc must be the same");
 
-        // atomicity::empty_item_counter is not allowed as a item counter
-        static_assert(!std::is_same<item_counter, atomicity::empty_item_counter>::value,
-            "atomicity::empty_item_counter is not allowed as a item counter");
-
     protected:
         //@cond
         typedef typename ordered_list::template select_stat_wrapper< typename ordered_list::stat > bucket_stat;
@@ -701,8 +697,8 @@ namespace cds { namespace intrusive {
 
         /// Checks if the set is empty
         /**
-            Emptiness is checked by item counting: if item count is zero then the set is empty.
-            Thus, the correct item counting feature is an important part of Michael's set implementation.
+            @warning If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns \p true.
         */
         bool empty() const
         {
@@ -710,6 +706,10 @@ namespace cds { namespace intrusive {
         }
 
         /// Returns item count in the set
+        /**
+            If you use \p atomicity::empty_item_counter in \p traits::item_counter,
+            the function always returns 0.
+        */
         size_t size() const
         {
             return m_ItemCounter;
index a37ec3dd516cb6be4a277aee8a5b3c052e438e43..fc6ae8edf1a0b53f060528079c116835db62009f 100644 (file)
@@ -445,9 +445,9 @@ namespace cds { namespace intrusive {
     protected:
         head_node                   m_Head;   ///< head tower (max height)
 
-        item_counter                m_ItemCounter;    ///< item counter
         random_level_generator      m_RandomLevelGen; ///< random level generator instance
         atomics::atomic<unsigned int>    m_nHeight;   ///< estimated high level
+        item_counter                m_ItemCounter;    ///< item counter
         mutable stat                m_Stat;           ///< internal statistics
 
     protected:
index 2e35c9afc36ea1e62c5627692a69b6ab84e3756f..b153aa809558155d17c1f1d7c51c2a7a3b95475a 100644 (file)
@@ -632,10 +632,10 @@ namespace cds { namespace intrusive {
     protected:
         skip_list::details::head_node< node_type > m_Head;   ///< head tower (max height)
 
-        item_counter                m_ItemCounter;      ///< item counter
         random_level_generator      m_RandomLevelGen;   ///< random level generator instance
         atomics::atomic<unsigned int>    m_nHeight;     ///< estimated high level
         atomics::atomic<node_type *>     m_pDeferredDelChain ;   ///< Deferred deleted node chain
+        item_counter                m_ItemCounter;      ///< item counter
         mutable stat                m_Stat;             ///< internal statistics
 
     protected:
index fe792e06a36827b6a9b77662e6fdd97ed4bccf86..1eadcfe3210c01da41e902b17683f7bdc4e88cb9 100644 (file)
@@ -1453,8 +1453,8 @@ namespace cds { namespace intrusive {
 
         atomics::atomic<size_t> m_nBucketCountLog2; ///< log2( current bucket count )
         atomics::atomic<size_t> m_nMaxItemCount;    ///< number of items container can hold, before we have to resize
-        item_counter            m_ItemCounter;      ///< Item counter
         hash                    m_HashFunctor;      ///< Hash functor
+        item_counter            m_ItemCounter;      ///< Item counter
         stat                    m_Stat;             ///< Internal statistics
         //@endcond
     };
index 10cb04626989b38d9c8c3a03221a34a90f510d92..68c0d250fb294b7187a8cc42b7422f9e7130f5e1 100644 (file)
@@ -732,8 +732,8 @@ namespace cds { namespace intrusive {
 
         atomics::atomic<size_t> m_nBucketCountLog2; ///< log2( current bucket count )
         atomics::atomic<size_t> m_nMaxItemCount;    ///< number of items container can hold, before we have to resize
-        item_counter            m_ItemCounter;      ///< Item counter
         hash                    m_HashFunctor;      ///< Hash functor
+        item_counter            m_ItemCounter;      ///< Item counter
         stat                    m_Stat;             ///< Internal statistics
         //@endcond
     };
index 117e49fc42401c6a07fc38094aa191bb6886176a..64583fe402133f1bcb6f9f4299156ec4cc992ed7 100644 (file)
@@ -1118,8 +1118,8 @@ namespace cds { namespace intrusive {
 
         atomics::atomic<size_t> m_nBucketCountLog2; ///< log2( current bucket count )
         atomics::atomic<size_t> m_nMaxItemCount;    ///< number of items container can hold, before we have to resize
-        item_counter            m_ItemCounter;      ///< Item counter
         hash                    m_HashFunctor;      ///< Hash functor
+        item_counter            m_ItemCounter;      ///< Item counter
         stat                    m_Stat;             ///< Internal statistics accumulator
         //@endcond
     };
index 5ab9c169f22a1c4bc08227b9d32d8567e8e03e91..70faba7178a6c1a36a4630730072d2cc666aeb31 100644 (file)
@@ -304,15 +304,16 @@ namespace opt {
         Predefined option \p Type:
         - \p atomicity::empty_item_counter - no item counting performed. It is default policy for many
             containers
-        - \p atomicity::item_counter - the class that provides atomically item counting
-        - \p opt::v::sequential_item_counter - simple non-atomic item counter. This item counter is not intended for
+        - \p atomicity::item_counter - the class that provides atomic item counting
+        - \p atomicity::cache_friendly_item_counter - cache-friendly atomic item counter
+        - \p opt::v::sequential_item_counter - simple non-atomic item counter. This counter is not intended for
             concurrent containers and may be used only if it is explicitly noted.
 
         You may provide other implementation of \p atomicity::item_counter interface for your needs.
 
         Note, the item counting in lock-free containers cannot be exact; for example, if
         item counter for a container returns zero it is not mean that the container is empty.
-        Thus, the item counter may be used for statistical purposes only.
+        So, the item counter may be used for statistical purposes only.
     */
     template <typename Type>
     struct item_counter {
index 757a11267c4a69fe6cc50512f01bec835b190d64..d12bca6e696baff4a4800539f3f7b68cc65f9ded 100644 (file)
@@ -93,7 +93,7 @@ namespace map {
             cc::bronson_avltree::make_traits<
                 co::less< less >
                 ,cc::bronson_avltree::relaxed_insert< false >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef BronsonAVLTreeMap< rcu_gpi, Key, Value, BronsonAVLTreeMap_less > BronsonAVLTreeMap_rcu_gpi_less;
@@ -106,7 +106,7 @@ namespace map {
             cc::bronson_avltree::make_traits<
                 co::compare< compare >
                 ,cc::bronson_avltree::relaxed_insert< false >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,co::stat< cc::bronson_avltree::stat<>>
             >::type
         {};
index 2e40d85a5ae256a0d2d131228a9f3354de0bea9c..63ec8b63cfe48f85b22ff50e5a0c98420b56cff4 100644 (file)
@@ -121,7 +121,7 @@ namespace map {
         struct traits_EllenBinTreeMap: public cc::ellen_bintree::make_set_traits<
                 co::less< less >
                 ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         struct traits_EllenBinTreeMap_hp : traits_EllenBinTreeMap {
@@ -183,7 +183,7 @@ namespace map {
                 >
                 ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
                 ,co::stat< cc::ellen_bintree::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
 
index c12b73f0bc3f21322543259ec8261685621648e5..164215686b0b1a49ce4183c1a2d434c76d8ff6a0 100644 (file)
@@ -105,6 +105,7 @@ namespace map {
         {
             typedef std::hash< Key >    hash;
             typedef std::less<size_t>   less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
         };
 
         typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_stdhash >    FeldmanHashMap_hp_stdhash;
@@ -137,6 +138,7 @@ namespace map {
         {
             typedef ::cds_test::city64 hash;
             typedef ::cds_test::city64::less less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
         };
         typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_hp_city64;
         typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city64 >    FeldmanHashMap_dhp_city64;
@@ -164,6 +166,7 @@ namespace map {
         {
             typedef ::cds_test::city128 hash;
             typedef ::cds_test::city128::less less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
         };
         typedef FeldmanHashMap< cds::gc::HP,  Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_hp_city128;
         typedef FeldmanHashMap< cds::gc::DHP, Key, Value, traits_FeldmanHashMap_city128 >    FeldmanHashMap_dhp_city128;
@@ -193,6 +196,7 @@ namespace map {
         struct traits_FeldmanHashMap_fixed: public cc::feldman_hashmap::traits
         {
             typedef map::cmp<Key>    compare;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
         };
 
         typedef FeldmanHashMap< cds::gc::HP, Key, Value,  traits_FeldmanHashMap_fixed >    FeldmanHashMap_hp_fixed;
index 988b73803197179d47043613c7b5d8b6cb592b52..bcab5ad256875e346cc79e50b346ceaac0787c70 100644 (file)
@@ -85,6 +85,7 @@ namespace map {
         struct traits_MichaelMap_hash :
             public cc::michael_map::make_traits<
                 co::hash< hash >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
 
index 7802a08c50474d45daef166d6c7b34558f760833..5db6b6e51bf2addcc6ae0610860fa79566a83c7a 100644 (file)
@@ -86,7 +86,7 @@ namespace map {
         class traits_SkipListMap_less_turbo32: public cc::skip_list::make_traits <
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32 > SkipListMap_hp_less_turbo32;
@@ -102,7 +102,7 @@ namespace map {
         class traits_SkipListMap_less_turbo24: public cc::skip_list::make_traits <
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo24 > SkipListMap_hp_less_turbo24;
@@ -118,7 +118,7 @@ namespace map {
         class traits_SkipListMap_less_turbo16: public cc::skip_list::make_traits <
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo16 > SkipListMap_hp_less_turbo16;
@@ -135,7 +135,7 @@ namespace map {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
                 ,co::memory_model< co::v::sequential_consistent >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32_seqcst > SkipListMap_hp_less_turbo32_seqcst;
@@ -152,7 +152,7 @@ namespace map {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo32_stat > SkipListMap_hp_less_turbo32_stat;
@@ -169,7 +169,7 @@ namespace map {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo24_stat > SkipListMap_hp_less_turbo24_stat;
@@ -186,7 +186,7 @@ namespace map {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_turbo16_stat > SkipListMap_hp_less_turbo16_stat;
@@ -202,7 +202,7 @@ namespace map {
         class traits_SkipListMap_cmp_turbo32: public cc::skip_list::make_traits <
                 co::compare< compare >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_turbo32 > SkipListMap_hp_cmp_turbo32;
@@ -219,7 +219,7 @@ namespace map {
                 co::compare< compare >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_turbo32_stat > SkipListMap_hp_cmp_turbo32_stat;
@@ -235,7 +235,7 @@ namespace map {
         class traits_SkipListMap_less_xorshift32: public cc::skip_list::make_traits <
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift32 > SkipListMap_hp_less_xorshift32;
@@ -251,7 +251,7 @@ namespace map {
         class traits_SkipListMap_less_xorshift24: public cc::skip_list::make_traits <
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift24 > SkipListMap_hp_less_xorshift24;
@@ -267,7 +267,7 @@ namespace map {
         class traits_SkipListMap_less_xorshift16: public cc::skip_list::make_traits <
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift16 > SkipListMap_hp_less_xorshift16;
@@ -284,7 +284,7 @@ namespace map {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift32_stat > SkipListMap_hp_less_xorshift32_stat;
@@ -301,7 +301,7 @@ namespace map {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift24_stat > SkipListMap_hp_less_xorshift24_stat;
@@ -318,7 +318,7 @@ namespace map {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_less_xorshift16_stat > SkipListMap_hp_less_xorshift16_stat;
@@ -334,7 +334,7 @@ namespace map {
         class traits_SkipListMap_cmp_xorshift32: public cc::skip_list::make_traits <
                 co::compare< compare >
                 ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_xorshift32 > SkipListMap_hp_cmp_xorshift32;
@@ -351,7 +351,7 @@ namespace map {
                 co::compare< compare >
                 ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListMap< cds::gc::HP, Key, Value, traits_SkipListMap_cmp_xorshift32_stat > SkipListMap_hp_cmp_xorshift32_stat;
index f9265b2a0f6f5c5cbfe20ae7a724efecfd892098..1efd127f4323e5b92c6086e02dfa183499aff3f3 100644 (file)
@@ -146,6 +146,7 @@ namespace map {
         struct traits_SplitList_Michael_dyn_cmp: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::compare< compare >
@@ -198,6 +199,7 @@ namespace map {
         struct traits_SplitList_Michael_dyn_cmp_seqcst: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
@@ -221,6 +223,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::compare< compare >
@@ -242,6 +245,7 @@ namespace map {
         struct traits_SplitList_Michael_dyn_less: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::less< less >
@@ -264,6 +268,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::less< less >
@@ -308,6 +313,7 @@ namespace map {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::compare< compare >
@@ -347,6 +353,7 @@ namespace map {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
@@ -371,6 +378,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::compare< compare >
@@ -393,6 +401,7 @@ namespace map {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::less< less >
@@ -415,6 +424,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::less< less >
@@ -456,6 +466,7 @@ namespace map {
         struct traits_SplitList_Iterable_dyn_cmp: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::compare< compare >
@@ -480,6 +491,7 @@ namespace map {
         struct traits_SplitList_Iterable_dyn_cmp_seqcst: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
@@ -496,6 +508,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::compare< compare >
@@ -510,6 +523,7 @@ namespace map {
         struct traits_SplitList_Iterable_dyn_less: public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::less< less >
@@ -524,6 +538,7 @@ namespace map {
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter< cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::less< less >
index 09f2d9a869c6cd5fffa8825d43e75af43da57c34..90c01e5432046c610f5c013439fbc1991df16956 100644 (file)
@@ -136,6 +136,7 @@ namespace set {
             cc::ellen_bintree::key_extractor< typename ellen_bintree_props::key_extractor >
             ,co::less< typename ellen_bintree_props::less >
             ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
+            ,co::item_counter<cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
 
@@ -208,6 +209,7 @@ namespace set {
             ,co::less< typename ellen_bintree_props::less >
             ,co::node_allocator< ellen_bintree_pool::internal_node_allocator< int > >
             ,co::stat< cc::ellen_bintree::stat<> >
+            ,co::item_counter<cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
 
index bfb9abebb61fe99e478bd25d63e0396964204a59..d9fcbbd1ab4d2fc82a37f98499396aceb579a970 100644 (file)
@@ -186,6 +186,7 @@ namespace set {
                     return kv.hash;
                 }
             };
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
         };
 
         typedef FeldmanHashSet< cds::gc::HP,  key_val<std::hash<key_type>>, default_traits >    FeldmanHashSet_hp_stdhash;
@@ -323,6 +324,7 @@ namespace set {
                 };
 
                 typedef set::cmp<Key>   compare;
+                typedef cds::atomicity::cache_friendly_item_counter item_counter;
             };
 
             struct traits_stat : public traits
index c14381333d96491c9b024ec853888d8bc57edc25..9934904ae34620a6250b6e26058c0c86dbdc6b05 100644 (file)
@@ -93,6 +93,7 @@ namespace set {
         struct traits_MichaelSet :
             public cc::michael_set::make_traits<
                 co::hash< hash >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef MichaelHashSet< cds::gc::HP,  typename ml::MichaelList_HP_cmp,  traits_MichaelSet > MichaelSet_HP_cmp;
index 02232098e1db70814f59f269287d1c44989585d9..648663f914d0ac26d839955b4e7cf0221ee1c338 100644 (file)
@@ -70,7 +70,7 @@ namespace set {
         class traits_SkipListSet_less_turbo32: public cc::skip_list::make_traits <
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo32 > SkipListSet_hp_less_turbo32;
@@ -85,7 +85,7 @@ namespace set {
         class traits_SkipListSet_less_turbo24: public cc::skip_list::make_traits <
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo24 > SkipListSet_hp_less_turbo24;
@@ -100,7 +100,7 @@ namespace set {
         class traits_SkipListSet_less_turbo16: public cc::skip_list::make_traits <
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo16 > SkipListSet_hp_less_turbo16;
@@ -116,7 +116,7 @@ namespace set {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
                 ,co::memory_model< co::v::sequential_consistent >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo32_seqcst > SkipListSet_hp_less_turbo32_seqcst;
@@ -132,7 +132,7 @@ namespace set {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo32_stat > SkipListSet_hp_less_turbo32_stat;
@@ -148,7 +148,7 @@ namespace set {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo24 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo24_stat > SkipListSet_hp_less_turbo24_stat;
@@ -164,7 +164,7 @@ namespace set {
                 co::less< less >
                 ,cc::skip_list::random_level_generator< cc::skip_list::turbo16 >
                 ,co::stat< cc::skip_list::stat<> >
-                ,co::item_counter< cds::atomicity::item_counter >
+                ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
             >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_turbo16_stat > SkipListSet_hp_less_turbo16_stat;
@@ -179,7 +179,7 @@ namespace set {
         class traits_SkipListSet_cmp_turbo32: public cc::skip_list::make_traits <
             co::compare< compare >
             ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_cmp_turbo32 > SkipListSet_hp_cmp_turbo32;
@@ -195,7 +195,7 @@ namespace set {
             co::compare< compare >
             ,cc::skip_list::random_level_generator< cc::skip_list::turbo32 >
             ,co::stat< cc::skip_list::stat<> >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_cmp_turbo32_stat > SkipListSet_hp_cmp_turbo32_stat;
@@ -210,7 +210,7 @@ namespace set {
         class traits_SkipListSet_less_xorshift32: public cc::skip_list::make_traits <
             co::less< less >
             ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift32 > SkipListSet_hp_less_xorshift32;
@@ -225,7 +225,7 @@ namespace set {
         class traits_SkipListSet_less_xorshift24: public cc::skip_list::make_traits <
             co::less< less >
             ,cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift24 > SkipListSet_hp_less_xorshift24;
@@ -240,7 +240,7 @@ namespace set {
         class traits_SkipListSet_less_xorshift16: public cc::skip_list::make_traits <
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift16 > SkipListSet_hp_less_xorshift16;
@@ -256,7 +256,7 @@ namespace set {
             co::less< less >
             ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
             ,co::stat< cc::skip_list::stat<> >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift32_stat > SkipListSet_hp_less_xorshift32_stat;
@@ -272,7 +272,7 @@ namespace set {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift24 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift24_stat > SkipListSet_hp_less_xorshift24_stat;
@@ -288,7 +288,7 @@ namespace set {
             co::less< less >
             , cc::skip_list::random_level_generator< cc::skip_list::xorshift16 >
             , co::stat< cc::skip_list::stat<> >
-            , co::item_counter< cds::atomicity::item_counter >
+            , co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_less_xorshift16_stat > SkipListSet_hp_less_xorshift16_stat;
@@ -303,7 +303,7 @@ namespace set {
         class traits_SkipListSet_cmp_xorshift32: public cc::skip_list::make_traits <
             co::compare< compare >
             ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_cmp_xorshift32 > SkipListSet_hp_cmp_xorshift32;
@@ -319,7 +319,7 @@ namespace set {
             co::compare< compare >
             ,cc::skip_list::random_level_generator< cc::skip_list::xorshift32 >
             ,co::stat< cc::skip_list::stat<> >
-            ,co::item_counter< cds::atomicity::item_counter >
+            ,co::item_counter< cds::atomicity::cache_friendly_item_counter >
         >::type
         {};
         typedef SkipListSet< cds::gc::HP, key_val, traits_SkipListSet_cmp_xorshift32_stat > SkipListSet_hp_cmp_xorshift32_stat;
index b0bddaccbb8e114bbaa15c32aab58df964510269..ed9317c3802765bcbeb18376611d6085c5a3947a 100644 (file)
@@ -100,6 +100,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                ,co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::compare< compare >
@@ -133,6 +134,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::stat< cc::split_list::stat<> >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
@@ -155,6 +157,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                ,co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
@@ -178,6 +181,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                ,co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::compare< compare >
@@ -199,6 +203,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::less< less >
@@ -220,6 +225,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
                         co::less< less >
@@ -241,6 +247,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::michael_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::stat< cc::split_list::stat<>>
                 ,cc::split_list::ordered_list_traits<
                     typename cc::michael_list::make_traits<
@@ -266,6 +273,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::compare< compare >
@@ -303,6 +311,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
@@ -326,6 +335,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::compare< compare >
@@ -346,6 +356,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::less< less >
@@ -367,6 +378,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::lazy_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::lazy_list::make_traits<
                         co::less< less >
@@ -407,6 +419,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::compare< compare >
@@ -421,6 +434,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::stat< cc::split_list::stat<> >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
@@ -437,6 +451,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::memory_model< co::v::sequential_consistent >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
@@ -454,6 +469,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::compare< compare >
@@ -469,6 +485,7 @@ namespace set {
             public cc::split_list::make_traits<
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::less< less >
@@ -484,6 +501,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
                         co::less< less >
@@ -499,6 +517,7 @@ namespace set {
                 cc::split_list::ordered_list<cc::iterable_list_tag>
                 ,cc::split_list::dynamic_bucket_table< false >
                 ,co::hash< hash >
+                , co::item_counter<cds::atomicity::cache_friendly_item_counter >
                 ,co::stat< cc::split_list::stat<>>
                 ,cc::split_list::ordered_list_traits<
                     typename cc::iterable_list::make_traits<
index 8f19c84ce999b299c747f1c707ee72bf824aa929..ae694ea706d5c22c0e30765bc4463d3207502823 100644 (file)
@@ -229,6 +229,23 @@ namespace {
         test_hp( l );
     }
 
+    TEST_F( IntrusiveMichaelList_DHP, member_hook_cache_friendly_item_counting )
+    {
+        struct traits: public ci::michael_list::traits {
+            typedef ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >> hook;
+            typedef mock_disposer disposer;
+            typedef cmp< member_item > compare;
+            typedef intrusive_list_common::less< member_item > less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+        typedef ci::MichaelList< gc_type, member_item, traits > list_type;
+
+        list_type l;
+        test_common( l );
+        test_ordered_iterator( l );
+        test_hp( l );
+    }
+
     TEST_F( IntrusiveMichaelList_DHP, member_hook_seqcst )
     {
         struct traits : public ci::michael_list::traits {
index 3ad0802b413c52feefd5b02e37e8d4f14a23280b..608040be1fb421bc9c258f443b0d931557e52154 100644 (file)
@@ -111,6 +111,23 @@ namespace {
         test_hp( l );
     }
 
+    TEST_F( IntrusiveMichaelList_HP, base_hook_cache_friendly_item_counting )
+    {
+        struct traits: public ci::michael_list::traits {
+            typedef ci::michael_list::base_hook< cds::opt::gc< gc_type >> hook;
+            typedef mock_disposer disposer;
+            typedef cmp< base_item > compare;
+            typedef intrusive_list_common::less< base_item > less;
+            typedef cds::atomicity::cache_friendly_item_counter item_counter;
+        };
+        typedef ci::MichaelList< gc_type, base_item, traits > list_type;
+
+        list_type l;
+        test_common( l );
+        test_ordered_iterator( l );
+        test_hp( l );
+    }
+
     TEST_F( IntrusiveMichaelList_HP, base_hook_backoff )
     {
         struct traits : public ci::michael_list::traits {