Moved stress test for intrusive stack to gtest framework
authorkhizmax <khizmax@gmail.com>
Wed, 24 Feb 2016 14:16:30 +0000 (17:16 +0300)
committerkhizmax <khizmax@gmail.com>
Wed, 24 Feb 2016 14:16:30 +0000 (17:16 +0300)
projects/Win/vc14/stress-stack.vcxproj
projects/Win/vc14/stress-stack.vcxproj.filters
test/stress/stack/CMakeLists.txt
test/stress/stack/intrusive_push_pop.cpp [new file with mode: 0644]
test/stress/stack/intrusive_stack_push_pop.h [new file with mode: 0644]
test/stress/stack/intrusive_stack_type.h [new file with mode: 0644]

index f63eb1a08a9a269fdbe976111626cc2fcc92b151..abd5845d703c6f5939011de4d64395bedc2666fa 100644 (file)
   </ItemGroup>\r
   <ItemGroup>\r
     <ClCompile Include="..\..\..\test\stress\main.cpp" />\r
+    <ClCompile Include="..\..\..\test\stress\stack\intrusive_push_pop.cpp" />\r
     <ClCompile Include="..\..\..\test\stress\stack\push.cpp" />\r
     <ClCompile Include="..\..\..\test\stress\stack\push_pop.cpp" />\r
   </ItemGroup>\r
   <ItemGroup>\r
+    <ClInclude Include="..\..\..\test\stress\stack\intrusive_stack_push_pop.h" />\r
+    <ClInclude Include="..\..\..\test\stress\stack\intrusive_stack_type.h" />\r
     <ClInclude Include="..\..\..\test\stress\stack\stack_type.h" />\r
   </ItemGroup>\r
   <PropertyGroup Label="Globals">\r
index 361b821f3cf83f5c4ba4bb35ac03d4c27a876272..5d4e437eaea4aff8ec25174e9aeacd5adae6f745 100644 (file)
     <ClCompile Include="..\..\..\test\stress\stack\push.cpp">\r
       <Filter>Source Files</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="..\..\..\test\stress\stack\intrusive_push_pop.cpp">\r
+      <Filter>Source Files</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="..\..\..\test\stress\stack\stack_type.h">\r
       <Filter>Header Files</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="..\..\..\test\stress\stack\intrusive_stack_type.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="..\..\..\test\stress\stack\intrusive_stack_push_pop.h">\r
+      <Filter>Header Files</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
 </Project>
\ No newline at end of file
index 460bdee573b1da4f2654959c1eee19d7f611b559..8a62e6c2d71b11cb67e6b9b46599682e44cef727 100644 (file)
@@ -2,6 +2,7 @@ set(PACKAGE_NAME stress-stack)
 
 set(CDSSTRESS_STACK_SOURCES
     ../main.cpp
+    intrusive_push_pop.cpp
     push.cpp
     push_pop.cpp
 )
diff --git a/test/stress/stack/intrusive_push_pop.cpp b/test/stress/stack/intrusive_push_pop.cpp
new file mode 100644 (file)
index 0000000..3b89e7b
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
+*/
+
+#include "intrusive_stack_push_pop.h"
+
+namespace cds_test {
+    /*static*/ size_t intrusive_stack_push_pop::s_nPushThreadCount = 4;
+    /*static*/ size_t intrusive_stack_push_pop::s_nPopThreadCount = 4;
+    /*static*/ size_t intrusive_stack_push_pop::s_nStackSize = 10000000;
+    /*static*/ size_t intrusive_stack_push_pop::s_nEliminationSize = 4;
+    /*static*/ bool intrusive_stack_push_pop::s_bFCIterative = false;
+    /*static*/ unsigned int intrusive_stack_push_pop::s_nFCCombinePassCount = 64;
+    /*static*/ unsigned int intrusive_stack_push_pop::s_nFCCompactFactor = 1024;
+
+    /*static*/ atomics::atomic<size_t> intrusive_stack_push_pop::s_nWorkingProducers( 0 );
+
+    /*static*/ void intrusive_stack_push_pop::SetUpTestCase()
+    {
+        cds_test::config const& cfg = get_config( "IntrusiveStack_PushPop" );
+
+        s_nPushThreadCount = cfg.get_size_t( "PushThreadCount", s_nPushThreadCount );
+        s_nPopThreadCount = cfg.get_size_t( "PopThreadCount", s_nPopThreadCount );
+        s_nStackSize = cfg.get_size_t( "StackSize", s_nStackSize );
+        s_nEliminationSize = cfg.get_size_t( "EliminationSize", s_nEliminationSize );
+        s_bFCIterative = cfg.get_bool( "FCIterate", s_bFCIterative );
+        s_nFCCombinePassCount = cfg.get_uint( "FCCombinePassCount", s_nFCCombinePassCount );
+        s_nFCCompactFactor = cfg.get_uint( "FCCompactFactor", s_nFCCompactFactor );
+
+        if ( s_nPushThreadCount == 0 )
+            s_nPushThreadCount = 1;
+        if ( s_nPopThreadCount == 0 )
+            s_nPopThreadCount = 1;
+        if ( s_nEliminationSize == 0 )
+            s_nEliminationSize = 1;
+    }
+} // namespace cds_test
+
+namespace {
+    class intrusive_stack_push_pop : public cds_test::intrusive_stack_push_pop
+    {
+        typedef cds_test::intrusive_stack_push_pop base_class;
+    protected:
+        typedef base_class::value_type<> value_type;
+        typedef base_class::value_type< cds::intrusive::treiber_stack::node< cds::gc::HP >> hp_value_type;
+        typedef base_class::value_type< cds::intrusive::treiber_stack::node< cds::gc::DHP >> dhp_value_type;
+
+        template <typename Stack>
+        void test()
+        {
+            value_array<typename Stack::value_type> arrValue( s_nStackSize );
+            {
+                Stack stack;
+                do_test( stack, arrValue );
+            }
+            Stack::gc::force_dispose();
+        }
+
+        void check_elimination_stat( cds::intrusive::treiber_stack::empty_stat const& )
+        {}
+
+        void check_elimination_stat( cds::intrusive::treiber_stack::stat<> const& s )
+        {
+            EXPECT_EQ( s.m_PushCount.get() + s.m_ActivePushCollision.get() + s.m_PassivePushCollision.get(), s_nStackSize );
+            EXPECT_EQ( s.m_PopCount.get() + s.m_ActivePopCollision.get() + s.m_PassivePopCollision.get(), s_nStackSize );
+            EXPECT_EQ( s.m_PushCount.get(), s.m_PopCount.get() );
+            EXPECT_EQ( s.m_ActivePopCollision.get(), s.m_PassivePushCollision.get() );
+            EXPECT_EQ( s.m_ActivePushCollision.get(), s.m_PassivePopCollision.get() );
+        }
+
+        template <typename Stack>
+        void test_elimination()
+        {
+            value_array<typename Stack::value_type> arrValue( s_nStackSize );
+            {
+                Stack stack( s_nEliminationSize );
+                do_test( stack, arrValue );
+                check_elimination_stat( stack.statistics() );
+            }
+            Stack::gc::force_dispose();
+        }
+
+        template <typename Stack>
+        void test_std()
+        {
+            value_array<typename Stack::value_type> arrValue( s_nStackSize );
+            Stack stack;
+            do_test( stack, arrValue );
+        }
+    };
+
+    // TreiberStack<cds::gc::HP>
+#define CDSSTRESS_Stack_F( test_fixture, stack_impl ) \
+    TEST_F( test_fixture, stack_impl ) \
+    { \
+        typedef typename istack::Types<hp_value_type>::stack_impl stack_type; \
+        test< stack_type >(); \
+    }
+
+    CDSSTRESS_TreiberStack_HP( intrusive_stack_push_pop )
+
+#undef CDSSTRESS_Stack_F
+
+    // TreiberStack<cds::gc::DHP>
+#define CDSSTRESS_Stack_F( test_fixture, stack_impl ) \
+    TEST_F( test_fixture, stack_impl ) \
+    { \
+        typedef typename istack::Types<dhp_value_type>::stack_impl stack_type; \
+        test< stack_type >(); \
+    }
+
+    CDSSTRESS_TreiberStack_DHP( intrusive_stack_push_pop )
+
+#undef CDSSTRESS_Stack_F
+
+    // TreiberStack<cds::gc::HP> + elimination enabled
+#define CDSSTRESS_Stack_F( test_fixture, stack_impl ) \
+    TEST_F( test_fixture, stack_impl ) \
+    { \
+        typedef typename istack::Types<hp_value_type>::stack_impl stack_type; \
+        test_elimination< stack_type >(); \
+    }
+
+    CDSSTRESS_EliminationStack_HP( intrusive_stack_push_pop )
+
+#undef CDSSTRESS_Stack_F
+
+
+    // TreiberStack<cds::gc::DHP> + elimination enabled
+#define CDSSTRESS_Stack_F( test_fixture, stack_impl ) \
+    TEST_F( test_fixture, stack_impl ) \
+    { \
+        typedef typename istack::Types<dhp_value_type>::stack_impl stack_type; \
+        test_elimination< stack_type >(); \
+    }
+
+    CDSSTRESS_EliminationStack_DHP( intrusive_stack_push_pop )
+
+#undef CDSSTRESS_Stack_F
+
+
+    // StdStack
+#define CDSSTRESS_Stack_F( test_fixture, stack_impl ) \
+    TEST_F( test_fixture, stack_impl ) \
+    { \
+        typedef typename istack::Types<value_type>::stack_impl stack_type; \
+        test_std< stack_type >(); \
+    }
+
+    CDSSTRESS_StdStack( intrusive_stack_push_pop )
+
+#undef CDSSTRESS_Stack_F
+
+} // namespace
diff --git a/test/stress/stack/intrusive_stack_push_pop.h b/test/stress/stack/intrusive_stack_push_pop.h
new file mode 100644 (file)
index 0000000..c919a61
--- /dev/null
@@ -0,0 +1,295 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
+*/
+
+#include "intrusive_stack_type.h"
+
+namespace cds_test {
+
+    class intrusive_stack_push_pop : public cds_test::stress_fixture
+    {
+    protected:
+        static size_t s_nPushThreadCount;
+        static size_t s_nPopThreadCount;
+        static size_t s_nStackSize;
+        static size_t s_nEliminationSize;
+        static bool s_bFCIterative;
+        static unsigned int s_nFCCombinePassCount;
+        static unsigned int s_nFCCompactFactor;
+
+        static atomics::atomic<size_t>  s_nWorkingProducers;
+
+        static CDS_CONSTEXPR const size_t c_nValArraySize = 1024;
+        static CDS_CONSTEXPR const size_t c_nBadConsumer = 0xbadc0ffe;
+
+        enum thread_type
+        {
+            producer_thread,
+            consumer_thread
+        };
+
+        struct empty
+        {};
+
+        template <typename Base = empty >
+        struct value_type : public Base
+        {
+            atomics::atomic<size_t> nNo;
+            size_t      nProducer;
+            size_t      nConsumer;
+
+            value_type() {}
+            value_type( size_t n ) : nNo( n ) {}
+        };
+
+
+        template <class Stack>
+        class Producer : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+        public:
+            Stack&              m_Stack;
+            size_t              m_nPushError;
+            size_t              m_arrPush[c_nValArraySize];
+
+            // Interval in m_arrValue
+            typename Stack::value_type *       m_pStart;
+            typename Stack::value_type *       m_pEnd;
+
+        public:
+            Producer( cds_test::thread_pool& pool, Stack& s )
+                : base_class( pool, producer_thread )
+                , m_Stack( s )
+                , m_nPushError( 0 )
+                , m_pStart( nullptr )
+                , m_pEnd( nullptr )
+            {}
+
+            Producer( Producer& src )
+                : base_class( src )
+                , m_Stack( src.m_Stack )
+                , m_nPushError( 0 )
+                , m_pStart( nullptr )
+                , m_pEnd( nullptr )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Producer( *this );
+            }
+
+            virtual void test()
+            {
+                m_nPushError = 0;
+                memset( m_arrPush, 0, sizeof( m_arrPush ) );
+
+                size_t i = 0;
+                for ( typename Stack::value_type * p = m_pStart; p < m_pEnd; ++p, ++i ) {
+                    p->nProducer = id();
+                    size_t no;
+                    p->nNo.store( no = i % c_nValArraySize, atomics::memory_order_release );
+                    if ( m_Stack.push( *p ) )
+                        ++m_arrPush[no];
+                    else
+                        ++m_nPushError;
+                }
+
+                s_nWorkingProducers.fetch_sub( 1, atomics::memory_order_release );
+            }
+        };
+
+        template <class Stack>
+        class Consumer : public cds_test::thread
+        {
+            typedef cds_test::thread base_class;
+        public:
+            Stack&              m_Stack;
+            size_t              m_nPopCount;
+            size_t              m_nPopEmpty;
+            size_t              m_arrPop[c_nValArraySize];
+            size_t              m_nDirtyPop;
+        public:
+            Consumer( cds_test::thread_pool& pool, Stack& s )
+                : base_class( pool, consumer_thread )
+                , m_Stack( s )
+                , m_nPopCount( 0 )
+                , m_nPopEmpty( 0 )
+                , m_nDirtyPop( 0 )
+            {}
+
+            Consumer( Consumer& src )
+                : base_class( src )
+                , m_Stack( src.m_Stack )
+                , m_nPopCount( 0 )
+                , m_nPopEmpty( 0 )
+                , m_nDirtyPop( 0 )
+            {}
+
+            virtual thread * clone()
+            {
+                return new Consumer( *this );
+            }
+
+            virtual void test()
+            {
+                m_nPopEmpty = 0;
+                m_nPopCount = 0;
+                m_nDirtyPop = 0;
+                memset( m_arrPop, 0, sizeof( m_arrPop ) );
+
+                while ( !(s_nWorkingProducers.load( atomics::memory_order_acquire ) == 0 && m_Stack.empty()) ) {
+                    typename Stack::value_type * p = m_Stack.pop();
+                    if ( p ) {
+                        p->nConsumer = id();
+                        ++m_nPopCount;
+                        size_t no = p->nNo.load( atomics::memory_order_acquire );
+                        if ( no < sizeof( m_arrPop ) / sizeof( m_arrPop[0] ) )
+                            ++m_arrPop[no];
+                        else
+                            ++m_nDirtyPop;
+                    }
+                    else
+                        ++m_nPopEmpty;
+                }
+            }
+        };
+
+        template <typename T>
+        class value_array
+        {
+            std::unique_ptr< T[] > m_pArr;
+
+        public:
+            value_array( size_t nSize )
+                : m_pArr( new T[nSize] )
+            {}
+
+            T * get() const { return m_pArr.get(); }
+        };
+
+    protected:
+        static void SetUpTestCase();
+        //static void TearDownTestCase();
+
+        template <class Stack>
+        void analyze( Stack& stack )
+        {
+            cds_test::thread_pool& pool = get_pool();
+
+            size_t nPushError = 0;
+            size_t nPopEmpty = 0;
+            size_t nPopCount = 0;
+            size_t arrVal[c_nValArraySize];
+            memset( arrVal, 0, sizeof( arrVal ) );
+            size_t nDirtyPop = 0;
+
+            for ( size_t threadNo = 0; threadNo < pool.size(); ++threadNo ) {
+                cds_test::thread& thread = pool.get( threadNo );
+                if ( thread.type() == producer_thread ) {
+                    Producer<Stack>& producer = static_cast<Producer<Stack>&>(thread);
+                    nPushError += producer.m_nPushError;
+                    for ( size_t i = 0; i < sizeof( arrVal ) / sizeof( arrVal[0] ); ++i )
+                        arrVal[i] += producer.m_arrPush[i];
+                }
+                else {
+                    ASSERT_TRUE( thread.type() == consumer_thread );
+                    Consumer<Stack>& consumer = static_cast<Consumer<Stack>&>(thread);
+                    nPopEmpty += consumer.m_nPopEmpty;
+                    nPopCount += consumer.m_nPopCount;
+                    nDirtyPop += consumer.m_nDirtyPop;
+                    for ( size_t i = 0; i < sizeof( arrVal ) / sizeof( arrVal[0] ); ++i )
+                        arrVal[i] -= consumer.m_arrPop[i];
+                }
+            }
+
+            EXPECT_EQ( nPopCount, s_nStackSize );
+            EXPECT_EQ( nDirtyPop, 0 );
+            EXPECT_EQ( nPushError, 0 );
+
+            for ( size_t i = 0; i < sizeof( arrVal ) / sizeof( arrVal[0] ); ++i ) {
+                EXPECT_EQ( arrVal[i], 0 ) << "i=" << i;
+            }
+
+            propout() << std::make_pair( "push_count", s_nStackSize )
+                << std::make_pair( "push_error", nPushError )
+                << std::make_pair( "pop_count", nPopCount )
+                << std::make_pair( "pop_empty", nPopEmpty )
+                << std::make_pair( "dirty_pop", nDirtyPop )
+                ;
+
+        }
+
+        template <typename Stack>
+        void do_test( Stack& stack, value_array<typename Stack::value_type>& arrValue )
+        {
+            cds_test::thread_pool& pool = get_pool();
+
+            s_nWorkingProducers.store( s_nPushThreadCount, atomics::memory_order_release );
+            size_t const nPushCount = s_nStackSize / s_nPushThreadCount;
+
+            typename Stack::value_type * pValStart = arrValue.get();
+            typename Stack::value_type * pValEnd = pValStart + s_nStackSize;
+
+            pool.add( new Producer<Stack>( pool, stack ), s_nPushThreadCount );
+            {
+                for ( typename Stack::value_type * it = pValStart; it != pValEnd; ++it )
+                    it->nConsumer = c_nBadConsumer;
+
+                typename Stack::value_type * pStart = pValStart;
+                for ( size_t thread_no = 0; thread_no < pool.size(); ++thread_no ) {
+                    static_cast<Producer<Stack>&>(pool.get( thread_no )).m_pStart = pStart;
+                    pStart += nPushCount;
+                    static_cast<Producer<Stack>&>(pool.get( thread_no )).m_pEnd = pStart;
+                }
+            }
+            pool.add( new Consumer<Stack>( pool, stack ), s_nPopThreadCount );
+
+            propout() << std::make_pair( "producer_thread_count", s_nPushThreadCount )
+                << std::make_pair( "consumer_thread_count", s_nPopThreadCount )
+                << std::make_pair( "push_count", nPushCount * s_nPushThreadCount )
+                ;
+
+            std::chrono::milliseconds duration = pool.run();
+
+            propout() << std::make_pair( "duration", duration );
+
+            s_nStackSize = nPushCount * s_nPushThreadCount;
+
+            {
+                typename Stack::value_type * pEnd = pValStart + s_nStackSize;
+                for ( typename Stack::value_type * it = pValStart; it != pEnd; ++it )
+                    EXPECT_NE( it->nConsumer, c_nBadConsumer );
+            }
+
+            analyze( stack );
+
+            propout() << stack.statistics();
+        }
+    };
+} // namespace cds_test
\ No newline at end of file
diff --git a/test/stress/stack/intrusive_stack_type.h b/test/stress/stack/intrusive_stack_type.h
new file mode 100644 (file)
index 0000000..89f6a8e
--- /dev/null
@@ -0,0 +1,497 @@
+/*
+    This file is a part of libcds - Concurrent Data Structures library
+
+    (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
+
+    Source code repo: http://github.com/khizmax/libcds/
+    Download: http://sourceforge.net/projects/libcds/files/
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this
+      list of conditions and the following disclaimer.
+
+    * Redistributions in binary form must reproduce the above copyright notice,
+      this list of conditions and the following disclaimer in the documentation
+      and/or other materials provided with the distribution.
+
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+    DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+    FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+    DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+    SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+    OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     
+*/
+
+#ifndef CDSSTRESS_INTRUSIVE_STACK_TYPES_H
+#define CDSSTRESS_INTRUSIVE_STACK_TYPES_H
+
+#include <cds/intrusive/treiber_stack.h>
+#include <cds/intrusive/fcstack.h>
+
+#include <cds/gc/hp.h>
+#include <cds/gc/dhp.h>
+
+#include <mutex>
+#include <cds/sync/spinlock.h>
+#include <stack>
+#include <list>
+#include <vector>
+#include <boost/intrusive/list.hpp>
+
+#include <cds_test/stress_test.h>
+
+
+namespace istack {
+
+    namespace details {
+
+        template < typename T, typename Stack, typename Lock>
+        class StdStack
+        {
+            Stack   m_Impl;
+            mutable Lock    m_Lock;
+            cds::intrusive::treiber_stack::empty_stat m_stat;
+
+            typedef std::unique_lock<Lock>  unique_lock;
+
+        public:
+            typedef T value_type;
+
+            bool push( T& v )
+            {
+                unique_lock l( m_Lock );
+                m_Impl.push( &v );
+                return true;
+            }
+
+            T * pop()
+            {
+                unique_lock l( m_Lock );
+                if ( !m_Impl.empty() ) {
+                     T * v = m_Impl.top();
+                    m_Impl.pop();
+                    return v;
+                }
+                return nullptr;
+            }
+
+            bool empty() const
+            {
+                unique_lock l( m_Lock );
+                return m_Impl.empty();
+            }
+
+            cds::intrusive::treiber_stack::empty_stat const& statistics() const
+            {
+                return m_stat;
+            }
+        };
+    }
+
+    template <typename T>
+    struct Types {
+
+        template <class GC>
+        using base_hook = cds::intrusive::treiber_stack::base_hook < cds::opt::gc< GC > >;
+
+    // TreiberStack
+        typedef cds::intrusive::TreiberStack< cds::gc::HP, T > Treiber_HP;
+        struct traits_Treiber_DHP: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<cds::gc::DHP> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_DHP >Treiber_DHP;
+
+        template <class GC> struct traits_Treiber_seqcst : public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::memory_model<cds::opt::v::sequential_consistent>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Treiber_seqcst<cds::gc::HP>  > Treiber_HP_seqcst;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_seqcst<cds::gc::DHP> > Treiber_DHP_seqcst;
+
+        template <class GC> struct traits_Treiber_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Treiber_stat<cds::gc::HP>  > Treiber_HP_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_stat<cds::gc::DHP> > Treiber_DHP_stat;
+
+        template <class GC> struct traits_Treiber_yield: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::back_off<cds::backoff::yield>
+                , cds::opt::memory_model<cds::opt::v::relaxed_ordering>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Treiber_yield<cds::gc::HP>  > Treiber_HP_yield;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_yield<cds::gc::DHP> > Treiber_DHP_yield;
+
+        template <class GC> struct traits_Treiber_pause: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::back_off<cds::backoff::pause>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Treiber_pause<cds::gc::HP>  > Treiber_HP_pause;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_pause<cds::gc::DHP> > Treiber_DHP_pause;
+
+        template <class GC> struct traits_Treiber_exp: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                ,cds::opt::back_off<
+                    cds::backoff::exponential<
+                        cds::backoff::pause,
+                        cds::backoff::yield
+                    >
+                >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Treiber_exp<cds::gc::HP>  > Treiber_HP_exp;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Treiber_exp<cds::gc::DHP> > Treiber_DHP_exp;
+
+
+    // Elimination stack
+        template <class GC> struct traits_Elimination_on : public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_on<cds::gc::HP>  > Elimination_HP;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_on<cds::gc::DHP> > Elimination_DHP;
+
+        template <class GC> struct traits_Elimination_seqcst : public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_seqcst<cds::gc::HP>  > Elimination_HP_seqcst;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_seqcst<cds::gc::DHP> > Elimination_DHP_seqcst;
+
+        template <class GC> struct traits_Elimination_2ms: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<2> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_2ms<cds::gc::HP>  > Elimination_HP_2ms;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_2ms<cds::gc::DHP> > Elimination_DHP_2ms;
+
+        template <class GC> struct traits_Elimination_2ms_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<2> >
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_2ms_stat<cds::gc::HP>  > Elimination_HP_2ms_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_2ms_stat<cds::gc::DHP> > Elimination_DHP_2ms_stat;
+
+        template <class GC> struct traits_Elimination_5ms: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<5> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_5ms<cds::gc::HP>  > Elimination_HP_5ms;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_5ms<cds::gc::DHP> > Elimination_DHP_5ms;
+
+        template <class GC> struct traits_Elimination_5ms_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<5> >
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_5ms_stat<cds::gc::HP>  > Elimination_HP_5ms_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_5ms_stat<cds::gc::DHP> > Elimination_DHP_5ms_stat;
+
+        template <class GC> struct traits_Elimination_10ms: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<10> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_10ms<cds::gc::HP>  > Elimination_HP_10ms;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_10ms<cds::gc::DHP> > Elimination_DHP_10ms;
+
+        template <class GC> struct traits_Elimination_10ms_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::elimination_backoff< cds::backoff::delay_of<10> >
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_10ms_stat<cds::gc::HP>  > Elimination_HP_10ms_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_10ms_stat<cds::gc::DHP> > Elimination_DHP_10ms_stat;
+
+        template <class GC> struct traits_Elimination_dyn: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::buffer< cds::opt::v::dynamic_buffer<int> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_dyn<cds::gc::HP>  > Elimination_HP_dyn;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_dyn<cds::gc::DHP> > Elimination_DHP_dyn;
+
+        template <class GC> struct traits_Elimination_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_stat<cds::gc::HP>  > Elimination_HP_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_stat<cds::gc::DHP> > Elimination_DHP_stat;
+
+        template <class GC> struct traits_Elimination_dyn_stat: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::buffer< cds::opt::v::dynamic_buffer<int> >
+                , cds::opt::stat<cds::intrusive::treiber_stack::stat<> >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_dyn_stat<cds::gc::HP>  > Elimination_HP_dyn_stat;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_dyn_stat<cds::gc::DHP> > Elimination_DHP_dyn_stat;
+
+        template <class GC> struct traits_Elimination_yield: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::back_off<cds::backoff::yield>
+                , cds::opt::memory_model<cds::opt::v::relaxed_ordering>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_yield<cds::gc::HP>  > Elimination_HP_yield;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_yield<cds::gc::DHP> > Elimination_DHP_yield;
+
+        template <class GC> struct traits_Elimination_pause: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                , cds::opt::back_off<cds::backoff::pause>
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_pause<cds::gc::HP>  > Elimination_HP_pause;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_pause<cds::gc::DHP> > Elimination_DHP_pause;
+
+        template <class GC> struct traits_Elimination_exp: public
+            cds::intrusive::treiber_stack::make_traits <
+                cds::intrusive::opt::hook< base_hook<GC> >
+                , cds::opt::enable_elimination<true>
+                ,cds::opt::back_off<
+                    cds::backoff::exponential<
+                        cds::backoff::pause,
+                        cds::backoff::yield
+                    >
+                >
+            > ::type
+        {};
+        typedef cds::intrusive::TreiberStack< cds::gc::HP,  T, traits_Elimination_exp<cds::gc::HP>  > Elimination_HP_exp;
+        typedef cds::intrusive::TreiberStack< cds::gc::DHP, T, traits_Elimination_exp<cds::gc::DHP> > Elimination_DHP_exp;
+
+    // FCStack
+        typedef cds::intrusive::FCStack< T > FCStack_slist;
+
+        struct traits_FCStack_stat:
+            public cds::intrusive::fcstack::make_traits<
+                cds::opt::stat< cds::intrusive::fcstack::stat<> >
+            >::type
+        {};
+        struct traits_FCStack_elimination:
+            public cds::intrusive::fcstack::make_traits<
+            cds::opt::enable_elimination< true >
+            >::type
+        {};
+        struct traits_FCStack_elimination_stat:
+            public cds::intrusive::fcstack::make_traits<
+                cds::opt::stat< cds::intrusive::fcstack::stat<> >,
+                cds::opt::enable_elimination< true >
+            >::type
+        {};
+
+        struct traits_FCStack_mutex_stat:
+            public cds::intrusive::fcstack::make_traits<
+                cds::opt::stat< cds::intrusive::fcstack::stat<> >
+                ,cds::opt::lock_type< std::mutex >
+            >::type
+        {};
+        struct traits_FCStack_mutex_elimination:
+            public cds::intrusive::fcstack::make_traits<
+                cds::opt::enable_elimination< true >
+                ,cds::opt::lock_type< std::mutex >
+            >::type
+        {};
+        struct traits_FCStack_mutex_elimination_stat:
+            public cds::intrusive::fcstack::make_traits<
+                cds::opt::stat< cds::intrusive::fcstack::stat<> >
+                ,cds::opt::enable_elimination< true >
+                ,cds::opt::lock_type< std::mutex >
+            >::type
+        {};
+
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_stat > FCStack_slist_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_elimination > FCStack_slist_elimination;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_elimination_stat > FCStack_slist_elimination_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_mutex_stat > FCStack_slist_mutex_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_mutex_elimination > FCStack_slist_mutex_elimination;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::slist< T >, traits_FCStack_mutex_elimination_stat > FCStack_slist_mutex_elimination_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T > > FCStack_list;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_stat > FCStack_list_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_elimination > FCStack_list_elimination;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_elimination_stat > FCStack_list_elimination_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_mutex_stat > FCStack_list_mutex_stat;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_mutex_elimination > FCStack_list_mutex_elimination;
+        typedef cds::intrusive::FCStack< T, boost::intrusive::list< T >, traits_FCStack_mutex_elimination_stat > FCStack_list_mutex_elimination_stat;
+
+
+        // std::stack
+        typedef details::StdStack< T, std::stack< T* >, std::mutex >  StdStack_Deque_Mutex;
+        typedef details::StdStack< T, std::stack< T* >, cds::sync::spin > StdStack_Deque_Spin;
+        typedef details::StdStack< T, std::stack< T*, std::vector<T*> >, std::mutex >  StdStack_Vector_Mutex;
+        typedef details::StdStack< T, std::stack< T*, std::vector<T*> >, cds::sync::spin > StdStack_Vector_Spin;
+        typedef details::StdStack< T, std::stack< T*, std::list<T*> >, std::mutex >  StdStack_List_Mutex;
+        typedef details::StdStack< T, std::stack< T*, std::list<T*> >, cds::sync::spin > StdStack_List_Spin;
+
+    };
+} // namespace istack
+
+namespace cds_test {
+
+    static inline property_stream& operator <<( property_stream& o, cds::intrusive::treiber_stack::empty_stat const& )
+    {
+        return o;
+    }
+
+    static inline property_stream& operator <<( property_stream& o, cds::intrusive::treiber_stack::stat<> const& s )
+    {
+        return o
+            << CDSSTRESS_STAT_OUT( s, m_PushCount )
+            << CDSSTRESS_STAT_OUT( s, m_PopCount )
+            << CDSSTRESS_STAT_OUT( s, m_PushRace )
+            << CDSSTRESS_STAT_OUT( s, m_PopRace )
+            << CDSSTRESS_STAT_OUT( s, m_ActivePushCollision )
+            << CDSSTRESS_STAT_OUT( s, m_PassivePopCollision )
+            << CDSSTRESS_STAT_OUT( s, m_ActivePopCollision )
+            << CDSSTRESS_STAT_OUT( s, m_PassivePushCollision )
+            << CDSSTRESS_STAT_OUT( s, m_EliminationFailed );
+    }
+
+
+    static inline property_stream& operator <<( property_stream& o, cds::intrusive::fcstack::empty_stat const& )
+    {
+        return o;
+    }
+
+    static inline property_stream& operator <<( property_stream& o, cds::intrusive::fcstack::stat<> const& s )
+    {
+        return o
+            << CDSSTRESS_STAT_OUT( s, m_nPush )
+            << CDSSTRESS_STAT_OUT( s, m_nPop )
+            << CDSSTRESS_STAT_OUT( s, m_nFailedPop )
+            << CDSSTRESS_STAT_OUT( s, m_nCollided )
+            << CDSSTRESS_STAT_OUT_( "combining_factor", s.combining_factor() )
+            << CDSSTRESS_STAT_OUT( s, m_nOperationCount )
+            << CDSSTRESS_STAT_OUT( s, m_nCombiningCount )
+            << CDSSTRESS_STAT_OUT( s, m_nCompactPublicationList )
+            << CDSSTRESS_STAT_OUT( s, m_nDeactivatePubRecord )
+            << CDSSTRESS_STAT_OUT( s, m_nActivatePubRecord )
+            << CDSSTRESS_STAT_OUT( s, m_nPubRecordCreated )
+            << CDSSTRESS_STAT_OUT( s, m_nPubRecordDeteted )
+            << CDSSTRESS_STAT_OUT( s, m_nAcquirePubRecCount )
+            << CDSSTRESS_STAT_OUT( s, m_nReleasePubRecCount );
+    }
+
+} // namespace cds_test
+
+#define CDSSTRESS_TreiberStack_HP( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_HP        ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_HP_seqcst ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_HP_pause  ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_HP_exp    ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_HP_stat   ) \
+
+#define CDSSTRESS_TreiberStack_DHP( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_DHP       ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_DHP_pause ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_DHP_exp   ) \
+    CDSSTRESS_Stack_F( test_fixture, Treiber_DHP_stat  )
+
+
+#define CDSSTRESS_EliminationStack_HP( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_2ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_2ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_5ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_5ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_10ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_10ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_seqcst ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_pause ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_exp ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_dyn ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_HP_dyn_stat ) \
+
+
+#define CDSSTRESS_EliminationStack_DHP( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_seqcst ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_2ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_2ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_5ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_5ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_10ms ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_10ms_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_pause ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_exp ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_dyn ) \
+    CDSSTRESS_Stack_F( test_fixture, Elimination_DHP_dyn_stat )
+
+#define CDSSTRESS_FCStack( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_elimination ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_elimination_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_mutex_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_mutex_elimination ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_slist_mutex_elimination_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_elimination ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_elimination_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_mutex_stat ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_mutex_elimination ) \
+    CDSSTRESS_Stack_F( test_fixture, FCStack_list_mutex_elimination_stat )
+
+#define CDSSTRESS_StdStack( test_fixture ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_Deque_Mutex  ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_Deque_Spin   ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_Vector_Mutex ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_Vector_Spin  ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_List_Mutex   ) \
+    CDSSTRESS_Stack_F( test_fixture, StdStack_List_Spin    )
+
+#endif // #ifndef CDSSTRESS_INTRUSIVE_STACK_TYPES_H