Fixed IterableList ordering violation
[libcds.git] / cds / intrusive / details / iterable_list_base.h
index 7ef00bdcd8846ddba37667b082a74de45297ac69..e9c27fd7f4f66aa330720a7a4dcc95f6fd903440 100644 (file)
@@ -5,7 +5,7 @@
 
     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:
 
@@ -50,9 +50,10 @@ namespace cds { namespace intrusive {
         struct node
         {
             typedef T value_type; ///< Value type
+            typedef cds::details::marked_ptr<T, 1>   marked_data_ptr; ///< marked pointer to the value
 
-            atomics::atomic< node* >  next;       ///< pointer to next node in the list
-            atomics::atomic< value_type* > data; ///< pointer to user data, \p nullptr if the node is free
+            atomics::atomic< node* >            next;  ///< pointer to next node in the list
+            atomics::atomic< marked_data_ptr >  data;  ///< pointer to user data, \p nullptr if the node is free
 
             //@cond
             node()
@@ -75,6 +76,8 @@ namespace cds { namespace intrusive {
             event_counter   m_nInsertSuccess;   ///< Number of success \p insert() operations
             event_counter   m_nInsertFailed;    ///< Number of failed \p insert() operations
             event_counter   m_nInsertRetry;     ///< Number of attempts to insert new item
+            event_counter   m_nInsertReuse;     ///< Number of reusing empty node when inserting
+            event_counter   m_nInsertReuseFailed;   ///< Number of failed attempsof reusing free node when inserting
             event_counter   m_nUpdateNew;       ///< Number of new item inserted for \p update()
             event_counter   m_nUpdateExisting;  ///< Number of existing item updates
             event_counter   m_nUpdateFailed;    ///< Number of failed \p update() call
@@ -92,6 +95,8 @@ namespace cds { namespace intrusive {
             void onInsertSuccess()      { ++m_nInsertSuccess;   }
             void onInsertFailed()       { ++m_nInsertFailed;    }
             void onInsertRetry()        { ++m_nInsertRetry;     }
+            void onInsertReuse()        { ++m_nInsertReuse;     }
+            void onInsertReuseFailed()  { ++m_nInsertReuseFailed; }
             void onUpdateNew()          { ++m_nUpdateNew;       }
             void onUpdateExisting()     { ++m_nUpdateExisting;  }
             void onUpdateFailed()       { ++m_nUpdateFailed;    }
@@ -113,6 +118,8 @@ namespace cds { namespace intrusive {
             void onInsertSuccess()              const {}
             void onInsertFailed()               const {}
             void onInsertRetry()                const {}
+            void onInsertReuse()                const {}
+            void onInsertReuseFailed()          const {}
             void onUpdateNew()                  const {}
             void onUpdateExisting()             const {}
             void onUpdateFailed()               const {}
@@ -140,6 +147,8 @@ namespace cds { namespace intrusive {
             void onInsertSuccess()   { m_stat.onInsertSuccess(); }
             void onInsertFailed()    { m_stat.onInsertFailed();  }
             void onInsertRetry()     { m_stat.onInsertRetry();   }
+            void onInsertReuse()     { m_stat.onInsertReuse();   }
+            void onInsertReuseFailed() { m_stat.onInsertReuseFailed(); }
             void onUpdateNew()       { m_stat.onUpdateNew();     }
             void onUpdateExisting()  { m_stat.onUpdateExisting();}
             void onUpdateFailed()    { m_stat.onUpdateFailed();  }
@@ -190,7 +199,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
-            typedef atomicity::empty_item_counter     item_counter;
+            typedef atomicity::empty_item_counter   item_counter;
 
             /// C++ memory ordering model
             /**
@@ -237,6 +246,33 @@ namespace cds { namespace intrusive {
 #   endif
         };
 
+
+        //@cond
+        template <typename Stat>
+        struct select_stat_wrapper
+        {
+            typedef Stat stat;
+            typedef iterable_list::wrapped_stat<Stat> wrapped_stat;
+            enum {
+                empty = false
+            };
+        };
+
+        template <>
+        struct select_stat_wrapper< empty_stat >
+        {
+            typedef empty_stat stat;
+            typedef empty_stat wrapped_stat;
+            enum {
+                empty = true
+            };
+        };
+
+        template <typename Stat>
+        struct select_stat_wrapper< iterable_list::wrapped_stat<Stat>>: public select_stat_wrapper<Stat>
+        {};
+        //@endcond
+
     } // namespace iterable_list
 
     //@cond
@@ -245,6 +281,14 @@ namespace cds { namespace intrusive {
     class IterableList;
     //@endcond
 
+    //@cond
+    template <typename GC, typename T, typename Traits>
+    struct is_iterable_list< IterableList< GC, T, Traits >> {
+        enum {
+            value = true
+        };
+    };
+    //@endcond
 
 }}   // namespace cds::intrusive