From: khizmax Date: Mon, 3 Oct 2016 06:04:29 +0000 (+0300) Subject: Splitted unit-list test X-Git-Tag: v2.2.0~105 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=b0bddeb92d4b860d97ffea8655113673a9adfaba;p=libcds.git Splitted unit-list test --- diff --git a/projects/Win/vc14/cds.sln b/projects/Win/vc14/cds.sln index decb0e12..4d76bb34 100644 --- a/projects/Win/vc14/cds.sln +++ b/projects/Win/vc14/cds.sln @@ -239,6 +239,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-freelist", "stress-f {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-intrusive-list", "gtest-intrusive-list.vcxproj", "{43563014-EE75-4855-87B5-A2F59762F413}" + ProjectSection(ProjectDependencies) = postProject + {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -633,6 +638,18 @@ Global {79A6845E-85BF-4000-94FF-9DF2473460D4}.Release|Win32.Build.0 = Release|Win32 {79A6845E-85BF-4000-94FF-9DF2473460D4}.Release|x64.ActiveCfg = Release|x64 {79A6845E-85BF-4000-94FF-9DF2473460D4}.Release|x64.Build.0 = Release|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.Debug|Win32.ActiveCfg = Debug|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.Debug|Win32.Build.0 = Debug|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.Debug|x64.ActiveCfg = Debug|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.Debug|x64.Build.0 = Debug|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.DebugVLD|Win32.Build.0 = DebugVLD|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.DebugVLD|x64.ActiveCfg = DebugVLD|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.DebugVLD|x64.Build.0 = DebugVLD|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.Release|Win32.ActiveCfg = Release|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.Release|Win32.Build.0 = Release|Win32 + {43563014-EE75-4855-87B5-A2F59762F413}.Release|x64.ActiveCfg = Release|x64 + {43563014-EE75-4855-87B5-A2F59762F413}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -673,6 +690,7 @@ Global {24DF3B87-387E-4EFC-BDE0-8DAD279FE19A} = {7D3EE35B-185D-40B5-88C2-7F9933426978} {31952FA8-A303-4A0B-94C4-ABA5A8A6DBCE} = {0D83E8C7-97D1-4BA1-928A-6846E7089652} {79A6845E-85BF-4000-94FF-9DF2473460D4} = {10E1FAF2-904D-405E-8AB5-6878A1B03346} + {43563014-EE75-4855-87B5-A2F59762F413} = {810490B7-31E5-49AE-8455-CAF99A9658B6} EndGlobalSection GlobalSection(DPCodeReviewSolutionGUID) = preSolution DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} diff --git a/projects/Win/vc14/gtest-deque.vcxproj.filters b/projects/Win/vc14/gtest-deque.vcxproj.filters index f8df4a76..ae4487bd 100644 --- a/projects/Win/vc14/gtest-deque.vcxproj.filters +++ b/projects/Win/vc14/gtest-deque.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - diff --git a/projects/Win/vc14/gtest-intrusive-list.vcxproj b/projects/Win/vc14/gtest-intrusive-list.vcxproj new file mode 100644 index 00000000..8e6171ae --- /dev/null +++ b/projects/Win/vc14/gtest-intrusive-list.vcxproj @@ -0,0 +1,270 @@ + + + + + DebugVLD + Win32 + + + DebugVLD + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {43563014-EE75-4855-87B5-A2F59762F413} + Win32Proj + intrusive_list + 8.1 + + + + Application + true + v140 + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + Application + true + v140 + Unicode + + + Application + true + v140 + Unicode + + + Application + false + v140 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + $(ProjectName)_d + + + true + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + $(ProjectName)_d + + + true + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + $(ProjectName)_d + + + true + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + $(ProjectName)_d + + + false + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + + + false + $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\ + $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ + + + + NotUsing + Level3 + Disabled + _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + $(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtestd.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + $(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtestd.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + $(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtestd.lib;%(AdditionalDependencies) + + + + + NotUsing + Level3 + Disabled + _ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + $(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtestd.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + true + true + _ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + true + true + $(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtest.lib;%(AdditionalDependencies) + + + + + Level3 + NotUsing + MaxSpeed + true + true + _ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + $(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories) + 4503 + + + Console + true + true + true + $(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir) + gtest.lib;%(AdditionalDependencies) + + + + + + \ No newline at end of file diff --git a/projects/Win/vc14/gtest-intrusive-list.vcxproj.filters b/projects/Win/vc14/gtest-intrusive-list.vcxproj.filters new file mode 100644 index 00000000..6ec8874e --- /dev/null +++ b/projects/Win/vc14/gtest-intrusive-list.vcxproj.filters @@ -0,0 +1,107 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {f6bc2494-0971-483b-98b2-7675d2aee7c9} + + + {b975977c-e055-46d0-95ea-bc94c66c6d50} + + + {edd852ff-4431-4c46-9592-dbbba4d9846e} + + + + + Source Files + + + Source Files\iterable_list + + + Source Files\iterable_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\lazy_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + Source Files\michael_list + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + \ No newline at end of file diff --git a/projects/Win/vc14/gtest-list.vcxproj b/projects/Win/vc14/gtest-list.vcxproj index 24ab1e1f..0d8f91d9 100644 --- a/projects/Win/vc14/gtest-list.vcxproj +++ b/projects/Win/vc14/gtest-list.vcxproj @@ -27,14 +27,6 @@ - - - - - - - - @@ -53,52 +45,6 @@ - - - - - - - 4503 - 4503 - 4503 - 4503 - 4503 - 4503 - - - - 4503 - 4503 - 4503 - 4503 - 4503 - 4503 - - - - - - - 4503 - 4503 - 4503 - 4503 - 4503 - 4503 - - - - 4503 - 4503 - 4503 - 4503 - 4503 - 4503 - - - - diff --git a/projects/Win/vc14/gtest-list.vcxproj.filters b/projects/Win/vc14/gtest-list.vcxproj.filters index eec2b0e6..ba6182e3 100644 --- a/projects/Win/vc14/gtest-list.vcxproj.filters +++ b/projects/Win/vc14/gtest-list.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - {f6bc2494-0971-483b-98b2-7675d2aee7c9} @@ -24,24 +20,6 @@ - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - Header Files @@ -78,12 +56,6 @@ Header Files - - Header Files - - - Header Files - Header Files @@ -101,60 +73,6 @@ Source Files - - Source Files\iterable_list - - - Source Files\iterable_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\lazy_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - - - Source Files\michael_list - Source Files\lazy_list diff --git a/projects/Win/vc14/gtest-striped-map.vcxproj.filters b/projects/Win/vc14/gtest-striped-map.vcxproj.filters index 97797d16..cd872963 100644 --- a/projects/Win/vc14/gtest-striped-map.vcxproj.filters +++ b/projects/Win/vc14/gtest-striped-map.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - diff --git a/projects/Win/vc14/gtest-tree.vcxproj.filters b/projects/Win/vc14/gtest-tree.vcxproj.filters index fabcd1c4..b909eb12 100644 --- a/projects/Win/vc14/gtest-tree.vcxproj.filters +++ b/projects/Win/vc14/gtest-tree.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - {5e28703f-0f92-4c6c-b3a6-3bd837deb8f6} diff --git a/projects/Win/vc14/stress-framework.vcxproj.filters b/projects/Win/vc14/stress-framework.vcxproj.filters index 9599b06f..00de287f 100644 --- a/projects/Win/vc14/stress-framework.vcxproj.filters +++ b/projects/Win/vc14/stress-framework.vcxproj.filters @@ -9,10 +9,6 @@ {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hh;hpp;hxx;hm;inl;inc;xsd - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index 46432de6..884e429b 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,4 +1,5 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deque) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/intrusive-list) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/list) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/map) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/misc) @@ -14,6 +15,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/tree) add_custom_target(unit-all DEPENDS unit-deque + unit-intrusive-list unit-list unit-map unit-misc diff --git a/test/unit/intrusive-list/CMakeLists.txt b/test/unit/intrusive-list/CMakeLists.txt new file mode 100644 index 00000000..8b11444f --- /dev/null +++ b/test/unit/intrusive-list/CMakeLists.txt @@ -0,0 +1,36 @@ +set(PACKAGE_NAME unit-intrusive-list) + +set(CDSGTEST_INTRUSIVE_LIST_SOURCES + ../main.cpp + intrusive_lazy_hp.cpp + intrusive_lazy_dhp.cpp + intrusive_lazy_nogc.cpp + intrusive_lazy_rcu_gpb.cpp + intrusive_lazy_rcu_gpi.cpp + intrusive_lazy_rcu_gpt.cpp + intrusive_lazy_rcu_shb.cpp + intrusive_lazy_rcu_sht.cpp + intrusive_michael_hp.cpp + intrusive_michael_dhp.cpp + intrusive_michael_nogc.cpp + intrusive_michael_rcu_gpb.cpp + intrusive_michael_rcu_gpi.cpp + intrusive_michael_rcu_gpt.cpp + intrusive_michael_rcu_shb.cpp + intrusive_michael_rcu_sht.cpp +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(${PACKAGE_NAME} ${CDSGTEST_INTRUSIVE_LIST_SOURCES}) +target_link_libraries(${PACKAGE_NAME} + ${CDS_SHARED_LIBRARY} + ${GTEST_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} +) + +add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) \ No newline at end of file diff --git a/test/unit/intrusive-list/intrusive_iterable_dhp.cpp b/test/unit/intrusive-list/intrusive_iterable_dhp.cpp new file mode 100644 index 00000000..38d8c527 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_iterable_dhp.cpp @@ -0,0 +1,172 @@ +/* + 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 "test_intrusive_iterable_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::DHP gc_type; + + class IntrusiveIterableList_DHP : public cds_test::intrusive_iterable_list_hp + { + protected: + void SetUp() + { + typedef ci::IterableList< gc_type, item_type > list_type; + + // +1 - for guarded_ptr + // +3 - for iterator test + cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::dhp::GarbageCollector::Destruct(); + } + }; + + TEST_F( IntrusiveIterableList_DHP, less ) + { + typedef ci::IterableList< gc_type, item_type, + typename ci::iterable_list::make_traits< + ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< item_type >> + , cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, compare ) + { + typedef ci::IterableList< gc_type, item_type, + typename ci::iterable_list::make_traits< + ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< item_type >> + , cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, item_counting ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef cmp< item_type > compare; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, backoff ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef cmp< item_type > compare; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, seqcst ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, stat ) + { + struct traits: public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::iterable_list::stat<> stat; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_DHP, wrapped_stat ) + { + struct traits: public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::iterable_list::wrapped_stat<> stat; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + traits::stat::stat_type st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_iterable_hp.cpp b/test/unit/intrusive-list/intrusive_iterable_hp.cpp new file mode 100644 index 00000000..1e253580 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_iterable_hp.cpp @@ -0,0 +1,174 @@ +/* + 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 "test_intrusive_iterable_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::HP gc_type; + + class IntrusiveIterableList_HP : public cds_test::intrusive_iterable_list_hp + { + protected: + void SetUp() + { + typedef ci::IterableList< gc_type, item_type > list_type; + + // +1 - for guarded_ptr + // +3 - for iterator test + cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 3, 1, 16 ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::hp::GarbageCollector::Destruct( true ); + } + }; + + TEST_F( IntrusiveIterableList_HP, less ) + { + typedef ci::IterableList< gc_type, item_type, + typename ci::iterable_list::make_traits< + ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< item_type >> + ,cds::opt::item_counter< cds::atomicity::item_counter > + + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, compare ) + { + typedef ci::IterableList< gc_type, item_type, + typename ci::iterable_list::make_traits< + ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< item_type >> + , cds::opt::item_counter< cds::atomicity::item_counter > + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, item_counting ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef cmp< item_type > compare; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, backoff ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef cmp< item_type > compare; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, seqcst ) + { + struct traits : public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, stat ) + { + struct traits: public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::iterable_list::stat<> stat; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveIterableList_HP, wrapped_stat ) + { + struct traits: public ci::iterable_list::traits { + typedef mock_disposer disposer; + typedef intrusive_iterable_list::less< item_type > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::iterable_list::wrapped_stat<> stat; + }; + typedef ci::IterableList< gc_type, item_type, traits > list_type; + + traits::stat::stat_type st; + + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_lazy_dhp.cpp b/test/unit/intrusive-list/intrusive_lazy_dhp.cpp new file mode 100644 index 00000000..73246179 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_dhp.cpp @@ -0,0 +1,345 @@ +/* + 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 "test_intrusive_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::DHP gc_type; + + class IntrusiveLazyList_DHP : public cds_test::intrusive_list_hp + { + public: + typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type>> member_item; + + typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; + typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; + + protected: + void SetUp() + { + struct traits: public ci::lazy_list::traits + { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::dhp::GarbageCollector::Destruct(); + } + }; + + TEST_F( IntrusiveLazyList_DHP, base_hook ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_cmp ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; + typedef mock_disposer disposer; + typedef cmp< base_mutex_item > compare; + typedef intrusive_list_common::less< base_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_backoff ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, base_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef intrusive_list_common::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_cmp ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; + typedef mock_disposer disposer; + typedef cmp< member_mutex_item > compare; + typedef intrusive_list_common::less< member_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_back_off ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_DHP, member_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_lazy_hp.cpp b/test/unit/intrusive-list/intrusive_lazy_hp.cpp new file mode 100644 index 00000000..bf3d49b5 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_hp.cpp @@ -0,0 +1,343 @@ +/* + 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 "test_intrusive_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::HP gc_type; + + class IntrusiveLazyList_HP : public cds_test::intrusive_list_hp + { + public: + typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type>> member_item; + + typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; + typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; + + protected: + void SetUp() + { + struct traits: public ci::lazy_list::traits + { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + // +1 - for guarded_ptr + cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 1, 1, 16 ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::hp::GarbageCollector::Destruct( true ); + } + }; + + TEST_F( IntrusiveLazyList_HP, base_hook ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_cmp ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; + typedef mock_disposer disposer; + typedef cmp< base_mutex_item > compare; + typedef intrusive_list_common::less< base_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_backoff ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, base_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_cmp ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; + typedef mock_disposer disposer; + typedef cmp< member_mutex_item > compare; + typedef intrusive_list_common::less< member_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_back_off ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveLazyList_HP, member_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< member_item > compare; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_lazy_nogc.cpp b/test/unit/intrusive-list/intrusive_lazy_nogc.cpp new file mode 100644 index 00000000..10039d1d --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_nogc.cpp @@ -0,0 +1,309 @@ +/* + 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 "test_intrusive_list_nogc.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::nogc gc_type; + + class IntrusiveLazyList_NOGC : public cds_test::intrusive_list_nogc + { + public: + typedef cds_test::intrusive_list_nogc::base_item< ci::lazy_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_nogc::member_item< ci::lazy_list::node< gc_type>> member_item; + + typedef cds_test::intrusive_list_nogc::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; + typedef cds_test::intrusive_list_nogc::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; + }; + + TEST_F( IntrusiveLazyList_NOGC, base_hook ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_cmp ) + { + typedef ci::LazyList< gc_type, base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef intrusive_list_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; + typedef mock_disposer disposer; + typedef cmp< base_mutex_item > compare; + typedef intrusive_list_nogc::less< base_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_backoff ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef intrusive_list_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef intrusive_list_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef intrusive_list_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, base_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; + typedef mock_disposer disposer; + typedef cmp< base_item > compare; + typedef intrusive_list_nogc::less< base_item > less; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, base_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_cmp ) + { + typedef ci::LazyList< gc_type, member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_item_counting ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_seqcst ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_mutex ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; + typedef mock_disposer disposer; + typedef cmp< member_mutex_item > compare; + typedef intrusive_list_nogc::less< member_mutex_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_back_off ) + { + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveLazyList_NOGC, member_hook_wrapped_stat ) + { + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_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_nogc::less< member_item > less; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< gc_type, member_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_lazy_rcu_gpb.cpp b/test/unit/intrusive-list/intrusive_lazy_rcu_gpb.cpp new file mode 100644 index 00000000..3b3ff318 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_rcu_gpb.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_lazy_rcu.h" + +namespace { + + typedef cds::urcu::general_buffered<> rcu_implementation; + typedef cds::urcu::general_buffered_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB, IntrusiveLazyList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_lazy_rcu_gpi.cpp b/test/unit/intrusive-list/intrusive_lazy_rcu_gpi.cpp new file mode 100644 index 00000000..6807c48c --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_rcu_gpi.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_lazy_rcu.h" + +namespace { + + typedef cds::urcu::general_instant<> rcu_implementation; + typedef cds::urcu::general_instant_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI, IntrusiveLazyList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_lazy_rcu_gpt.cpp b/test/unit/intrusive-list/intrusive_lazy_rcu_gpt.cpp new file mode 100644 index 00000000..e0d943c5 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_rcu_gpt.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_lazy_rcu.h" + +namespace { + + typedef cds::urcu::general_threaded<> rcu_implementation; + typedef cds::urcu::general_threaded_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT, IntrusiveLazyList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_lazy_rcu_shb.cpp b/test/unit/intrusive-list/intrusive_lazy_rcu_shb.cpp new file mode 100644 index 00000000..490b0afd --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_rcu_shb.cpp @@ -0,0 +1,47 @@ +/* + 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 + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_lazy_rcu.h" + +namespace { + + typedef cds::urcu::signal_buffered<> rcu_implementation; + typedef cds::urcu::signal_buffered_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB, IntrusiveLazyList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB_stripped, IntrusiveLazyList, rcu_implementation_stripped ); + +#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/intrusive-list/intrusive_lazy_rcu_sht.cpp b/test/unit/intrusive-list/intrusive_lazy_rcu_sht.cpp new file mode 100644 index 00000000..905cf2d4 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_lazy_rcu_sht.cpp @@ -0,0 +1,47 @@ +/* + 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 + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_lazy_rcu.h" + +namespace { + + typedef cds::urcu::signal_threaded<> rcu_implementation; + typedef cds::urcu::signal_threaded_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT, IntrusiveLazyList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT_stripped, IntrusiveLazyList, rcu_implementation_stripped ); + +#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/intrusive-list/intrusive_michael_dhp.cpp b/test/unit/intrusive-list/intrusive_michael_dhp.cpp new file mode 100644 index 00000000..cbc0d20e --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_dhp.cpp @@ -0,0 +1,302 @@ +/* + 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 "test_intrusive_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::DHP gc_type; + + class IntrusiveMichaelList_DHP : public cds_test::intrusive_list_hp + { + public: + typedef cds_test::intrusive_list_hp::base_item< ci::michael_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_hp::member_item< ci::michael_list::node< gc_type>> member_item; + + protected: + void SetUp() + { + struct traits: public ci::michael_list::traits + { + typedef ci::michael_list::base_hook< cds::opt::gc< gc_type >> hook; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::dhp::GarbageCollector::Destruct(); + } + }; + + TEST_F( IntrusiveMichaelList_DHP, base_hook ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_DHP, base_hook_cmp ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_DHP, base_hook_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::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_DHP, base_hook_backoff ) + { + 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::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + 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_DHP, base_hook_seqcst ) + { + 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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + 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_DHP, base_hook_stat ) + { + 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::intrusive::michael_list::stat<> stat; + }; + 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_DHP, base_hook_wrapped_stat ) + { + 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 cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + + TEST_F( IntrusiveMichaelList_DHP, member_hook ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_DHP, member_hook_cmp ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_DHP, member_hook_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::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 { + 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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + 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_back_off ) + { + 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::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + 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_stat ) + { + 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::intrusive::michael_list::stat<> stat; + }; + 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_wrapped_stat ) + { + 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 cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< gc_type, member_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_michael_hp.cpp b/test/unit/intrusive-list/intrusive_michael_hp.cpp new file mode 100644 index 00000000..693a0bfb --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_hp.cpp @@ -0,0 +1,303 @@ +/* + 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 "test_intrusive_list_hp.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::HP gc_type; + + class IntrusiveMichaelList_HP : public cds_test::intrusive_list_hp + { + public: + typedef cds_test::intrusive_list_hp::base_item< ci::michael_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_hp::member_item< ci::michael_list::node< gc_type>> member_item; + + protected: + void SetUp() + { + struct traits: public ci::michael_list::traits + { + typedef ci::michael_list::base_hook< cds::opt::gc< gc_type >> hook; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + // +1 - for guarded_ptr + cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 1, 1, 16 ); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + cds::gc::hp::GarbageCollector::Destruct( true ); + } + }; + + TEST_F( IntrusiveMichaelList_HP, base_hook ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_HP, base_hook_cmp ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_HP, base_hook_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::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 { + 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::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + 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_seqcst ) + { + 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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + 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_stat ) + { + 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::intrusive::michael_list::stat<> stat; + }; + 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_wrapped_stat ) + { + 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 cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_HP, member_hook ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_HP, member_hook_cmp ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + + TEST_F( IntrusiveMichaelList_HP, member_hook_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::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_HP, member_hook_seqcst ) + { + 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::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + 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_HP, member_hook_back_off ) + { + 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::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + 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_HP, member_hook_stat ) + { + 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::intrusive::michael_list::stat<> stat; + }; + 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_HP, member_hook_wrapped_stat ) + { + 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 cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< gc_type, member_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + test_common( l ); + test_ordered_iterator( l ); + test_hp( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_michael_nogc.cpp b/test/unit/intrusive-list/intrusive_michael_nogc.cpp new file mode 100644 index 00000000..21a3ff21 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_nogc.cpp @@ -0,0 +1,205 @@ +/* + 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 "test_intrusive_list_nogc.h" +#include + +namespace { + namespace ci = cds::intrusive; + typedef cds::gc::nogc gc_type; + + class IntrusiveMichaelList_NOGC : public cds_test::intrusive_list_nogc + { + public: + typedef cds_test::intrusive_list_nogc::base_item< ci::michael_list::node< gc_type>> base_item; + typedef cds_test::intrusive_list_nogc::member_item< ci::michael_list::node< gc_type>> member_item; + }; + + TEST_F( IntrusiveMichaelList_NOGC, base_hook ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, base_hook_cmp ) + { + typedef ci::MichaelList< gc_type, base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> + , ci::opt::disposer< mock_disposer > + , cds::opt::compare< cmp< base_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, base_hook_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_nogc::less< base_item > less; + typedef cds::atomicity::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_F( IntrusiveMichaelList_NOGC, base_hook_backoff ) + { + 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_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, base_hook_seqcst ) + { + 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_nogc::less< base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::MichaelList< gc_type, base_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, member_hook ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::less< less< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, member_hook_cmp ) + { + typedef ci::MichaelList< gc_type, member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> + ,ci::opt::disposer< mock_disposer > + ,cds::opt::compare< cmp< member_item >> + >::type + > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, member_hook_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_nogc::less< member_item > less; + typedef cds::atomicity::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_F( IntrusiveMichaelList_NOGC, member_hook_seqcst ) + { + 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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::MichaelList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + + TEST_F( IntrusiveMichaelList_NOGC, member_hook_back_off ) + { + 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_nogc::less< member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::MichaelList< gc_type, member_item, traits > list_type; + + list_type l; + test_common( l ); + test_ordered_iterator( l ); + } + +} // namespace diff --git a/test/unit/intrusive-list/intrusive_michael_rcu_gpb.cpp b/test/unit/intrusive-list/intrusive_michael_rcu_gpb.cpp new file mode 100644 index 00000000..d2b0b277 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_rcu_gpb.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_michael_rcu.h" + +namespace { + + typedef cds::urcu::general_buffered<> rcu_implementation; + typedef cds::urcu::general_buffered_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB, IntrusiveMichaelList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_michael_rcu_gpi.cpp b/test/unit/intrusive-list/intrusive_michael_rcu_gpi.cpp new file mode 100644 index 00000000..edaeaf3a --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_rcu_gpi.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_michael_rcu.h" + +namespace { + + typedef cds::urcu::general_instant<> rcu_implementation; + typedef cds::urcu::general_instant_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI, IntrusiveMichaelList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_michael_rcu_gpt.cpp b/test/unit/intrusive-list/intrusive_michael_rcu_gpt.cpp new file mode 100644 index 00000000..75c4a4e6 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_rcu_gpt.cpp @@ -0,0 +1,43 @@ +/* + 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 + +#include "test_intrusive_michael_rcu.h" + +namespace { + + typedef cds::urcu::general_threaded<> rcu_implementation; + typedef cds::urcu::general_threaded_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT, IntrusiveMichaelList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/intrusive-list/intrusive_michael_rcu_shb.cpp b/test/unit/intrusive-list/intrusive_michael_rcu_shb.cpp new file mode 100644 index 00000000..fea8656b --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_rcu_shb.cpp @@ -0,0 +1,47 @@ +/* + 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 + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_michael_rcu.h" + +namespace { + + typedef cds::urcu::signal_buffered<> rcu_implementation; + typedef cds::urcu::signal_buffered_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB, IntrusiveMichaelList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); + +#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/intrusive-list/intrusive_michael_rcu_sht.cpp b/test/unit/intrusive-list/intrusive_michael_rcu_sht.cpp new file mode 100644 index 00000000..c75db4d6 --- /dev/null +++ b/test/unit/intrusive-list/intrusive_michael_rcu_sht.cpp @@ -0,0 +1,47 @@ +/* + 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 + +#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED + +#include "test_intrusive_michael_rcu.h" + +namespace { + + typedef cds::urcu::signal_threaded<> rcu_implementation; + typedef cds::urcu::signal_threaded_stripped rcu_implementation_stripped; + +} // namespace + +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT, IntrusiveMichaelList, rcu_implementation ); +INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); + +#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/intrusive-list/test_intrusive_iterable_list.h b/test/unit/intrusive-list/test_intrusive_iterable_list.h new file mode 100644 index 00000000..1db06f9c --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_iterable_list.h @@ -0,0 +1,554 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H + +#include +#include + +namespace cds_test { + + class intrusive_iterable_list : public fixture + { + public: + struct stat { + int nDisposeCount; + int nUpdateExistsCall; + int nUpdateNewCall; + int nFindCall; + int nEraseCall; + int nInsertCall; + + stat() + : nDisposeCount( 0 ) + , nUpdateExistsCall( 0 ) + , nUpdateNewCall( 0 ) + , nFindCall( 0 ) + , nEraseCall( 0 ) + , nInsertCall( 0 ) + {} + + stat( const stat& s ) + { + *this = s; + } + + stat& operator =( const stat& s ) + { + memcpy( this, &s, sizeof( s ) ); + return *this; + } + }; + + struct item_type + { + int nKey; + int nVal; + + mutable stat s; + + item_type() + {} + + item_type( int key, int val ) + : nKey( key ) + , nVal( val ) + , s() + {} + + item_type( const item_type& v ) + : nKey( v.nKey ) + , nVal( v.nVal ) + , s() + {} + + const int& key() const + { + return nKey; + } + + item_type& operator=( item_type const& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + + item_type& operator=( item_type&& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + }; + + template + struct less + { + bool operator ()( const T& v1, const T& v2 ) const + { + return v1.key() < v2.key(); + } + + template + bool operator ()( const T& v1, const Q& v2 ) const + { + return v1.key() < v2; + } + + template + bool operator ()( const Q& v1, const T& v2 ) const + { + return v1 < v2.key(); + } + }; + + struct other_item { + int nKey; + + other_item( int n ) + : nKey( n ) + {} + }; + + struct other_less { + template + bool operator()( T const& i1, Q const& i2 ) const + { + return i1.nKey < i2.nKey; + } + }; + + template + struct cmp { + int operator ()( const T& v1, const T& v2 ) const + { + if ( v1.key() < v2.key() ) + return -1; + return v1.key() > v2.key() ? 1 : 0; + } + + template + int operator ()( const T& v1, const Q& v2 ) const + { + if ( v1.key() < v2 ) + return -1; + return v1.key() > v2 ? 1 : 0; + } + + template + int operator ()( const Q& v1, const T& v2 ) const + { + if ( v1 < v2.key() ) + return -1; + return v1 > v2.key() ? 1 : 0; + } + }; + + struct mock_disposer + { + template + void operator ()( T * p ) + { + ++p->s.nDisposeCount; + } + }; + + struct update_functor + { + template + void operator()( T& item, T * old ) + { + if ( !old ) + ++item.s.nUpdateNewCall; + else + ++item.s.nUpdateExistsCall; + } + }; + + struct find_functor + { + template + void operator ()( T& item, Q& /*val*/ ) + { + ++item.s.nFindCall; + } + }; + + struct erase_functor + { + template + void operator()( T const& item ) + { + item.s.nEraseCall++; + } + }; + + protected: + template + void test_common( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[ nSize ]; + value_type arr2[ nSize ]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast( i ); + arr[i].nVal = arr[i].nKey * 10; + + arr2[i] = arr[i]; + } + shuffle( arr, arr + nSize ); + shuffle( arr2, arr2 + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + typedef typename List::iterator iterator; + + // insert / find + for ( auto& i : arr ) { + EXPECT_FALSE( l.contains( i.nKey )); + EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + + switch ( i.nKey % 4 ) { + case 0: + EXPECT_TRUE( l.insert( i )); + break; + case 1: + EXPECT_EQ( i.s.nInsertCall, 0 ); + EXPECT_TRUE( l.insert( i, []( value_type& i ) { ++i.s.nInsertCall; } )); + EXPECT_EQ( i.s.nInsertCall, 1 ); + break; + case 2: + { + std::pair ret = l.update( i, []( value_type& i, value_type * old ) { + EXPECT_TRUE( old == nullptr ); + EXPECT_EQ( i.s.nUpdateNewCall, 0 ); + ++i.s.nUpdateNewCall; + }, false ); + EXPECT_EQ( i.s.nUpdateNewCall, 0 ); + EXPECT_EQ( ret.first, false ); + EXPECT_EQ( ret.second, false ); + + ret = l.update( i, []( value_type& i, value_type * old ) { + EXPECT_TRUE( old == nullptr ); + EXPECT_EQ( i.s.nUpdateNewCall, 0 ); + ++i.s.nUpdateNewCall; + }, true ); + EXPECT_EQ( i.s.nUpdateNewCall, 1 ); + EXPECT_EQ( ret.first, true ); + EXPECT_EQ( ret.second, true ); + } + break; + case 3: + { + std::pair ret = l.upsert( i, false ); + EXPECT_EQ( ret.first, false ); + EXPECT_EQ( ret.second, false ); + + ret = l.upsert( i ); + EXPECT_EQ( ret.first, true ); + EXPECT_EQ( ret.second, true ); + } + break; + } + + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 1 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 2 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 3 ); + + EXPECT_FALSE( l.insert( i ) ); + ASSERT_FALSE( l.empty() ); + + int const ckey = i.nKey; + iterator it = l.find( ckey ); + ASSERT_FALSE( it == l.end() ); + EXPECT_EQ( it->nKey, i.nKey ); + EXPECT_EQ( (*it).nVal, i.nVal ); + check_ordered( it, l.end() ); + + it = l.find( i.nKey ); + ASSERT_FALSE( it == l.end() ); + EXPECT_EQ( it->nKey, i.nKey ); + EXPECT_EQ( (*it).nVal, i.nVal ); + check_ordered( it, l.end() ); + + it = l.find_with( other_item( i.nKey ), other_less() ); + ASSERT_FALSE( it == l.end() ); + EXPECT_EQ( it->nKey, i.nKey ); + EXPECT_EQ( it->nVal, i.nVal ); + check_ordered( it, l.end() ); + + } + ASSERT_CONTAINER_SIZE( l, nSize ); + + // check all items + for ( auto const& i : arr ) { + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 4 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 5 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 6 ); + } + ASSERT_FALSE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, nSize ); + + // update existing test + for ( auto& i : arr2 ) { + EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); + std::pair ret = l.update( i, update_functor() ); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + } + + // update with the same value must be empty - no functor is called + for ( auto& i : arr2 ) { + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + std::pair ret = l.update( i, update_functor() ); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + } + + // Apply retired pointer to clean links + List::gc::force_dispose(); + + for ( auto& i : arr ) { + EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); + std::pair ret = l.update( i, []( value_type& i, value_type * old ) { + EXPECT_FALSE( old == nullptr ); + EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); + ++i.s.nUpdateExistsCall; + }); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + } + + // erase test + for ( auto const& i : arr ) { + if ( i.nKey & 1 ) + EXPECT_TRUE( l.erase( i.nKey )); + else + EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less() )); + + EXPECT_FALSE( l.contains( i )); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + + for ( auto const& i : arr ) + EXPECT_EQ( i.s.nDisposeCount, 2 ); + for ( auto const& i : arr2 ) + EXPECT_EQ( i.s.nDisposeCount, 1 ); + + // erase with functor + for ( auto& i : arr ) { + int const updateNewCall = i.s.nUpdateNewCall; + std::pair ret = l.update( i, update_functor(), false ); + EXPECT_FALSE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateNewCall, updateNewCall ); + + ret = l.update( i, update_functor(), true ); + EXPECT_TRUE( ret.first ); + EXPECT_TRUE( ret.second ); + EXPECT_EQ( i.s.nUpdateNewCall, updateNewCall + 1 ); + } + EXPECT_FALSE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, nSize ); + + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nEraseCall, 0 ); + if ( i.nKey & 1 ) { + EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); + EXPECT_FALSE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); + } + else { + EXPECT_TRUE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); + EXPECT_FALSE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); + } + EXPECT_EQ( i.s.nEraseCall, 1 ); + EXPECT_FALSE( l.contains( i.nKey )); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + + for ( auto const& i : arr ) + EXPECT_EQ( i.s.nDisposeCount, 3 ); + + // clear test + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i )); + + EXPECT_FALSE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, nSize ); + + l.clear(); + + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 4 ); + EXPECT_FALSE( l.contains( i )); + } + + // unlink test + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + for ( auto& i : arr ) { + value_type val( i ); + EXPECT_TRUE( l.contains( val )); + EXPECT_FALSE( l.unlink( val )); + EXPECT_TRUE( l.contains( val ) ); + EXPECT_TRUE( l.unlink( i )); + EXPECT_FALSE( l.unlink( i )); + EXPECT_FALSE( l.contains( i ) ); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 5 ); + EXPECT_FALSE( l.contains( i ) ); + } + + // Iterators on empty list + { + auto it = l.begin(); + auto itEnd = l.end(); + auto cit = l.cbegin(); + auto citEnd = l.cend(); + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + + ++it; + ++cit; + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + } + } + + template + void test_ordered_iterator( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[nSize]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast(i); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + + int key = 0; + for ( auto it = l.begin(); it != l.end(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + key = 0; + for ( auto it = l.cbegin(); it != l.cend(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + l.clear(); + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + + template + void check_ordered( Iterator first, Iterator last ) + { + while ( first != last ) { + Iterator it = first; + if ( ++it != last ) { + EXPECT_LT( first->nKey, it->nKey ); + } + first = it; + } + } + + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H diff --git a/test/unit/intrusive-list/test_intrusive_iterable_list_hp.h b/test/unit/intrusive-list/test_intrusive_iterable_list_hp.h new file mode 100644 index 00000000..4fbb63db --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_iterable_list_hp.h @@ -0,0 +1,110 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H + +#include "test_intrusive_iterable_list.h" + +namespace cds_test { + + class intrusive_iterable_list_hp : public intrusive_iterable_list + { + protected: + template + void test_hp( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[nSize]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast(i); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + typedef typename List::guarded_ptr guarded_ptr; + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + guarded_ptr gp; + + // get() test + for ( auto& i : arr ) { + gp = l.get( i.nKey ); + EXPECT_TRUE( !gp ); + gp = l.get_with( other_item( i.nKey ), other_less() ); + EXPECT_TRUE( !gp ); + + EXPECT_TRUE( l.insert( i ) ); + + gp = l.get( i.nKey ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i.nKey ); + EXPECT_EQ( gp->nVal, i.nVal ); + gp = l.get_with( other_item( i.nKey ), other_less() ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i.nKey ); + EXPECT_EQ( gp->nVal, i.nVal ); + } + + // extract() test + for ( int i = 0; i < static_cast(nSize); ++i ) { + if ( i & 1 ) + gp = l.extract( i ); + else + gp = l.extract_with( other_item( i ), other_less() ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i ); + + gp = l.extract( i ); + EXPECT_TRUE( !gp ); + gp = l.extract_with( other_item( i ), other_less() ); + EXPECT_TRUE( !gp ); + } + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H diff --git a/test/unit/intrusive-list/test_intrusive_lazy_rcu.h b/test/unit/intrusive-list/test_intrusive_lazy_rcu.h new file mode 100644 index 00000000..bb8e5fcb --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_lazy_rcu.h @@ -0,0 +1,310 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H + +#include "test_intrusive_list_rcu.h" +#include + +namespace ci = cds::intrusive; + +template +class IntrusiveLazyList : public cds_test::intrusive_list_rcu +{ + typedef cds_test::intrusive_list_rcu base_class; +public: + typedef cds::urcu::gc rcu_type; + typedef typename base_class::base_item< ci::lazy_list::node< rcu_type >> base_item; + typedef typename base_class::member_item< ci::lazy_list::node< rcu_type >> member_item; + +protected: + void SetUp() + { + RCU::Construct(); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + RCU::Destruct(); + } +}; + +TYPED_TEST_CASE_P( IntrusiveLazyList ); + +TYPED_TEST_P( IntrusiveLazyList, base_hook ) +{ + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> + , ci::opt::disposer< typename TestFixture::mock_disposer > + , cds::opt::less< typename TestFixture::template less< typename TestFixture::base_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_cmp ) +{ + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> + , ci::opt::disposer< typename TestFixture::mock_disposer > + , cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::base_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_item_counting ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef typename TestFixture::template less< typename TestFixture::base_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_backoff ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef typename TestFixture::template less< typename TestFixture::base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_seqcst ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_stat ) +{ + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, base_hook_wrapped_stat ) +{ + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook ) +{ + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> + ,ci::opt::disposer< typename TestFixture::mock_disposer > + ,cds::opt::less< typename TestFixture::template less< typename TestFixture::member_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_cmp ) +{ + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, + typename ci::lazy_list::make_traits< + ci::opt::hook< ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> + ,ci::opt::disposer< typename TestFixture::mock_disposer > + ,cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::member_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_item_counting ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_seqcst ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_back_off ) +{ + struct traits : public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_stat ) +{ + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::stat<> stat; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveLazyList, member_hook_wrapped_stat ) +{ + struct traits: public ci::lazy_list::traits { + typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef cds::atomicity::item_counter item_counter; + typedef cds::intrusive::lazy_list::wrapped_stat<> stat; + }; + typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + cds::intrusive::lazy_list::stat<> st; + list_type l( st ); + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as +// "No test named can be found in this test case" +REGISTER_TYPED_TEST_CASE_P( IntrusiveLazyList, + base_hook, base_hook_cmp, base_hook_item_counting, base_hook_backoff, base_hook_seqcst, base_hook_stat, base_hook_wrapped_stat, member_hook, member_hook_cmp, member_hook_item_counting, member_hook_seqcst, member_hook_back_off, member_hook_stat, member_hook_wrapped_stat +); + + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H + diff --git a/test/unit/intrusive-list/test_intrusive_list.h b/test/unit/intrusive-list/test_intrusive_list.h new file mode 100644 index 00000000..fc3fe801 --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_list.h @@ -0,0 +1,506 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H + +#include +#include + +namespace cds_test { + + class intrusive_list_common : public fixture + { + public: + struct stat { + int nDisposeCount; + int nUpdateExistsCall; + int nUpdateNewCall; + int nFindCall; + int nEraseCall; + int nInsertCall; + + stat() + : nDisposeCount( 0 ) + , nUpdateExistsCall( 0 ) + , nUpdateNewCall( 0 ) + , nFindCall( 0 ) + , nEraseCall( 0 ) + , nInsertCall( 0 ) + {} + + stat( const stat& s ) + { + *this = s; + } + + stat& operator =( const stat& s ) + { + memcpy( this, &s, sizeof( s ) ); + return *this; + } + }; + + template + struct base_item : public Node + { + int nKey; + int nVal; + + mutable stat s; + + base_item() + {} + + base_item( int key, int val ) + : nKey( key ) + , nVal( val ) + , s() + {} + + base_item( const base_item& v ) + : nKey( v.nKey ) + , nVal( v.nVal ) + , s() + {} + + const int& key() const + { + return nKey; + } + + base_item& operator=( base_item const& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + + base_item& operator=( base_item&& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + }; + + template + struct member_item + { + int nKey; + int nVal; + Node hMember; + mutable stat s; + + member_item() + {} + + member_item( int key, int val ) + : nKey( key ) + , nVal( val ) + , s() + {} + + member_item( const member_item& v ) + : nKey( v.nKey ) + , nVal( v.nVal ) + , s() + {} + + const int& key() const + { + return nKey; + } + + member_item& operator =( member_item const& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + + member_item& operator=( member_item&& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + }; + + template + struct less + { + bool operator ()( const T& v1, const T& v2 ) const + { + return v1.key() < v2.key(); + } + + template + bool operator ()( const T& v1, const Q& v2 ) const + { + return v1.key() < v2; + } + + template + bool operator ()( const Q& v1, const T& v2 ) const + { + return v1 < v2.key(); + } + }; + + struct other_item { + int nKey; + + other_item( int n ) + : nKey( n ) + {} + }; + + struct other_less { + template + bool operator()( T const& i1, Q const& i2 ) const + { + return i1.nKey < i2.nKey; + } + }; + + template + struct cmp { + int operator ()( const T& v1, const T& v2 ) const + { + if ( v1.key() < v2.key() ) + return -1; + return v1.key() > v2.key() ? 1 : 0; + } + + template + int operator ()( const T& v1, const Q& v2 ) const + { + if ( v1.key() < v2 ) + return -1; + return v1.key() > v2 ? 1 : 0; + } + + template + int operator ()( const Q& v1, const T& v2 ) const + { + if ( v1 < v2.key() ) + return -1; + return v1 > v2.key() ? 1 : 0; + } + }; + + struct mock_disposer + { + template + void operator ()( T * p ) + { + ++p->s.nDisposeCount; + } + }; + + struct update_functor + { + template + void operator ()( bool bNew, T& item, T& /*val*/ ) + { + if ( bNew ) + ++item.s.nUpdateNewCall; + else + ++item.s.nUpdateExistsCall; + } + }; + + struct find_functor + { + template + void operator ()( T& item, Q& /*val*/ ) + { + ++item.s.nFindCall; + } + }; + + struct erase_functor + { + template + void operator()( T const& item ) + { + item.s.nEraseCall++; + } + }; + + protected: + template + void test_common( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[ nSize ]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast( i ); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + // insert / find + for ( auto& i : arr ) { + EXPECT_FALSE( l.contains( i.nKey )); + EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + + if ( i.nKey & 1 ) + EXPECT_TRUE( l.insert( i )); + else { + EXPECT_EQ( i.s.nInsertCall, 0 ); + EXPECT_TRUE( l.insert( i, []( value_type& i ) { ++i.s.nInsertCall; } )); + EXPECT_EQ( i.s.nInsertCall, 1 ); + } + + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 1 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 2 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 3 ); + + EXPECT_FALSE( l.insert( i ) ); + ASSERT_FALSE( l.empty() ); + } + ASSERT_CONTAINER_SIZE( l, nSize ); + + // check all items + for ( auto const& i : arr ) { + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 4 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 5 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 6 ); + } + ASSERT_FALSE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, nSize ); + + // update existing test + for ( auto& i : arr ) { + EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); + std::pair ret = l.update( i, update_functor() ); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + + ret = l.update( i, []( bool bNew, value_type& i, value_type& arg ) { + EXPECT_FALSE( bNew ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + EXPECT_TRUE( &i == &arg ); + ++i.s.nUpdateExistsCall; + }); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 2 ); + } + + // erase test + for ( auto const& i : arr ) { + if ( i.nKey & 1 ) + EXPECT_TRUE( l.erase( i.nKey )); + else + EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less() )); + + EXPECT_FALSE( l.contains( i )); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + + for ( auto const& i : arr ) + EXPECT_EQ( i.s.nDisposeCount, 1 ); + + // erase with functor + for ( auto& i : arr ) { + std::pair ret = l.update( i, update_functor(), false ); + EXPECT_FALSE( ret.first ); + EXPECT_FALSE( ret.second ); + + ret = l.update( i, update_functor(), true ); + EXPECT_TRUE( ret.first ); + EXPECT_TRUE( ret.second ); + EXPECT_EQ( i.s.nUpdateNewCall, 1 ); + } + EXPECT_FALSE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, nSize ); + + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nEraseCall, 0 ); + if ( i.nKey & 1 ) { + EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); + EXPECT_FALSE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); + } + else { + EXPECT_TRUE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); + EXPECT_FALSE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); + } + EXPECT_EQ( i.s.nEraseCall, 1 ); + EXPECT_FALSE( l.contains( i.nKey )); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + + for ( auto const& i : arr ) + EXPECT_EQ( i.s.nDisposeCount, 2 ); + + // clear test + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i )); + + EXPECT_FALSE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, nSize ); + + l.clear(); + + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 3 ); + EXPECT_FALSE( l.contains( i )); + } + + // unlink test + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + for ( auto& i : arr ) { + value_type val( i ); + EXPECT_TRUE( l.contains( val )); + EXPECT_FALSE( l.unlink( val )); + EXPECT_TRUE( l.contains( val ) ); + EXPECT_TRUE( l.unlink( i )); + EXPECT_FALSE( l.unlink( i )); + EXPECT_FALSE( l.contains( i ) ); + } + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 4 ); + EXPECT_FALSE( l.contains( i ) ); + } + + // Iterators on empty list + { + auto it = l.begin(); + auto itEnd = l.end(); + auto cit = l.cbegin(); + auto citEnd = l.cend(); + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + + ++it; + ++cit; + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + } + } + + template + void test_ordered_iterator( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[nSize]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast(i); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + + int key = 0; + for ( auto it = l.begin(); it != l.end(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + key = 0; + for ( auto it = l.cbegin(); it != l.cend(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + l.clear(); + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H diff --git a/test/unit/intrusive-list/test_intrusive_list_hp.h b/test/unit/intrusive-list/test_intrusive_list_hp.h new file mode 100644 index 00000000..b5a95814 --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_list_hp.h @@ -0,0 +1,110 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H + +#include "test_intrusive_list.h" + +namespace cds_test { + + class intrusive_list_hp : public intrusive_list_common + { + protected: + template + void test_hp( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[ nSize ]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast( i ); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + typedef typename List::guarded_ptr guarded_ptr; + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + guarded_ptr gp; + + // get() test + for ( auto& i : arr ) { + gp = l.get( i.nKey ); + EXPECT_TRUE( !gp ); + gp = l.get_with( other_item( i.nKey ), other_less()); + EXPECT_TRUE( !gp ); + + EXPECT_TRUE( l.insert( i )); + + gp = l.get( i.nKey ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i.nKey ); + EXPECT_EQ( gp->nVal, i.nVal ); + gp = l.get_with( other_item( i.nKey ), other_less() ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i.nKey ); + EXPECT_EQ( gp->nVal, i.nVal ); + } + + // extract() test + for ( int i = 0; i < static_cast(nSize); ++i ) { + if ( i & 1 ) + gp = l.extract( i ); + else + gp = l.extract_with( other_item(i), other_less()); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i ); + + gp = l.extract( i ); + EXPECT_TRUE( !gp ); + gp = l.extract_with( other_item( i ), other_less() ); + EXPECT_TRUE( !gp ); + } + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H diff --git a/test/unit/intrusive-list/test_intrusive_list_nogc.h b/test/unit/intrusive-list/test_intrusive_list_nogc.h new file mode 100644 index 00000000..c9298c8b --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_list_nogc.h @@ -0,0 +1,493 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H + +#include +#include + +namespace cds_test { + + class intrusive_list_nogc : public fixture + { + public: + struct stat { + int nDisposeCount; + int nUpdateExistsCall; + int nUpdateNewCall; + int nFindCall; + + stat() + : nDisposeCount( 0 ) + , nUpdateExistsCall( 0 ) + , nUpdateNewCall( 0 ) + , nFindCall( 0 ) + {} + + stat( const stat& s ) + { + *this = s; + } + + stat& operator =( const stat& s ) + { + memcpy( this, &s, sizeof( s ) ); + return *this; + } + }; + + template + struct base_item : public Node + { + int nKey; + int nVal; + + mutable stat s; + + base_item() + {} + + base_item( int key, int val ) + : nKey( key ) + , nVal( val ) + , s() + {} + + base_item( const base_item& v ) + : nKey( v.nKey ) + , nVal( v.nVal ) + , s() + {} + + const int& key() const + { + return nKey; + } + + base_item& operator=( base_item const& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + + base_item& operator=( base_item&& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + }; + + template + struct member_item + { + int nKey; + int nVal; + Node hMember; + mutable stat s; + + member_item() + {} + + member_item( int key, int val ) + : nKey( key ) + , nVal( val ) + , s() + {} + + member_item( const member_item& v ) + : nKey( v.nKey ) + , nVal( v.nVal ) + , s() + {} + + const int& key() const + { + return nKey; + } + + member_item& operator =( member_item const& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + + member_item& operator=( member_item&& src ) + { + nKey = src.nKey; + nVal = src.nVal; + return *this; + } + }; + + template + struct less + { + bool operator ()( const T& v1, const T& v2 ) const + { + return v1.key() < v2.key(); + } + + template + bool operator ()( const T& v1, const Q& v2 ) const + { + return v1.key() < v2; + } + + template + bool operator ()( const Q& v1, const T& v2 ) const + { + return v1 < v2.key(); + } + }; + + struct other_item { + int nKey; + + other_item( int n ) + : nKey( n ) + {} + }; + + struct other_less { + template + bool operator()( T const& i1, Q const& i2 ) const + { + return i1.nKey < i2.nKey; + } + }; + + template + struct cmp { + int operator ()( const T& v1, const T& v2 ) const + { + if ( v1.key() < v2.key() ) + return -1; + return v1.key() > v2.key() ? 1 : 0; + } + + template + int operator ()( const T& v1, const Q& v2 ) const + { + if ( v1.key() < v2 ) + return -1; + return v1.key() > v2 ? 1 : 0; + } + + template + int operator ()( const Q& v1, const T& v2 ) const + { + if ( v1 < v2.key() ) + return -1; + return v1 > v2.key() ? 1 : 0; + } + }; + + struct mock_disposer + { + template + void operator ()( T * p ) + { + ++p->s.nDisposeCount; + } + }; + + struct mock_disposer2 + { + template + void operator ()( T * p ) + { + p->s.nDisposeCount += 10; + } + }; + + struct update_functor + { + template + void operator ()( bool bNew, T& item, T& /*val*/ ) + { + if ( bNew ) + ++item.s.nUpdateNewCall; + else + ++item.s.nUpdateExistsCall; + } + }; + + struct find_functor + { + template + void operator ()( T& item, Q& /*val*/ ) + { + ++item.s.nFindCall; + } + }; + + struct erase_functor + { + template + void operator()( T const& item ) + { + item.s.nEraseCall++; + } + }; + + protected: + template + void test_common( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[ nSize ]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast( i ); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + // insert / find + for ( auto& i : arr ) { + EXPECT_FALSE( l.contains( i.nKey )); + EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 0 ); + + EXPECT_TRUE( l.insert( i )); + + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 1 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 2 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 3 ); + + EXPECT_FALSE( l.insert( i ) ); + ASSERT_FALSE( l.empty() ); + } + ASSERT_CONTAINER_SIZE( l, nSize ); + + // check all items + for ( auto const& i : arr ) { + EXPECT_TRUE( l.contains( i.nKey )); + EXPECT_TRUE( l.contains( i )); + EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); + EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 4 ); + EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 5 ); + EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); + EXPECT_EQ( i.s.nFindCall, 6 ); + } + ASSERT_FALSE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, nSize ); + + // update existing test + for ( auto& i : arr ) { + EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); + std::pair ret = l.update( i, update_functor() ); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + + ret = l.update( i, []( bool bNew, value_type& i, value_type& arg ) { + EXPECT_FALSE( bNew ); + EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); + EXPECT_TRUE( &i == &arg ); + ++i.s.nUpdateExistsCall; + }); + EXPECT_TRUE( ret.first ); + EXPECT_FALSE( ret.second ); + EXPECT_EQ( i.s.nUpdateExistsCall, 2 ); + } + + // clear() test + l.clear(); + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + + + for ( auto& i : arr ) { + std::pair ret = l.update( i, update_functor(), false ); + EXPECT_FALSE( ret.first ); + EXPECT_FALSE( ret.second ); + + ret = l.update( i, update_functor(), true ); + EXPECT_TRUE( ret.first ); + EXPECT_TRUE( ret.second ); + EXPECT_EQ( i.s.nUpdateNewCall, 1 ); + } + + EXPECT_FALSE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, nSize ); + + l.clear( mock_disposer2()); + + EXPECT_TRUE( l.empty() ); + EXPECT_CONTAINER_SIZE( l, 0 ); + + // Apply retired pointer to clean links + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 11 ); + EXPECT_FALSE( l.contains( i )); + } + + // Iterators on empty list + { + auto it = l.begin(); + auto itEnd = l.end(); + auto cit = l.cbegin(); + auto citEnd = l.cend(); + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + + ++it; + ++cit; + + EXPECT_TRUE( it == itEnd ); + EXPECT_TRUE( it == cit ); + EXPECT_TRUE( cit == citEnd ); + } + } + + template + void test_ordered_iterator( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[nSize]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast(i); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + + int key = 0; + for ( auto it = l.begin(); it != l.end(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + key = 0; + for ( auto it = l.cbegin(); it != l.cend(); ++it ) { + EXPECT_EQ( it->nKey, key ); + EXPECT_EQ( (*it).nKey, key ); + ++key; + } + + l.clear(); + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + + template + void test_unordered_iterator( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[nSize]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast(i); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + for ( auto& i : arr ) + EXPECT_TRUE( l.insert( i ) ); + + size_t idx = 0; + for ( auto it = l.begin(); it != l.end(); ++it, ++idx ) { + ASSERT_LT( idx, nSize ); + EXPECT_EQ( it->nKey, arr[idx].nKey ); + EXPECT_EQ( (*it).nKey, arr[idx].nKey ); + } + + idx = 0; + for ( auto it = l.cbegin(); it != l.cend(); ++it, ++idx ) { + ASSERT_LT( idx, nSize ); + EXPECT_EQ( it->nKey, arr[idx].nKey ); + EXPECT_EQ( (*it).nKey, arr[idx].nKey ); + } + + l.clear(); + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H diff --git a/test/unit/intrusive-list/test_intrusive_list_rcu.h b/test/unit/intrusive-list/test_intrusive_list_rcu.h new file mode 100644 index 00000000..9df70379 --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_list_rcu.h @@ -0,0 +1,146 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H + +#include "test_intrusive_list.h" + +namespace cds_test { + + class intrusive_list_rcu : public intrusive_list_common + { + protected: + template + void test_rcu( List& l ) + { + // Precondition: list is empty + // Postcondition: list is empty + + static const size_t nSize = 20; + typedef typename List::value_type value_type; + value_type arr[ nSize ]; + + for ( size_t i = 0; i < nSize; ++i ) { + arr[i].nKey = static_cast( i ); + arr[i].nVal = arr[i].nKey * 10; + } + shuffle( arr, arr + nSize ); + + typedef typename List::exempt_ptr exempt_ptr; + typedef typename List::raw_ptr raw_ptr; + typedef typename List::rcu_lock rcu_lock; + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + // get() test + for ( auto& i : arr ) { + { + rcu_lock lock; + raw_ptr rp = l.get( i.nKey ); + EXPECT_TRUE( !rp ); + rp = l.get_with( other_item( i.nKey ), other_less()); + EXPECT_TRUE( !rp ); + } + + EXPECT_TRUE( l.insert( i )); + + { + rcu_lock lock; + raw_ptr rp = l.get( i.nKey ); + ASSERT_FALSE( !rp ); + EXPECT_EQ( rp->nKey, i.nKey ); + EXPECT_EQ( rp->nVal, i.nVal ); + } + { + rcu_lock lock; + raw_ptr rp = l.get_with( other_item( i.nKey ), other_less() ); + ASSERT_FALSE( !rp ); + EXPECT_EQ( rp->nKey, i.nKey ); + EXPECT_EQ( rp->nVal, i.nVal ); + } + } + + exempt_ptr gp; + + // extract() test + if ( List::c_bExtractLockExternal ) { + for ( int i = 0; i < static_cast(nSize); ++i ) { + { + rcu_lock lock; + + if ( i & 1 ) + gp = l.extract( i ); + else + gp = l.extract_with( other_item(i), other_less()); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i ); + } + gp.release(); + { + rcu_lock lock; + + gp = l.extract( i ); + EXPECT_TRUE( !gp ); + gp = l.extract_with( other_item( i ), other_less() ); + EXPECT_TRUE( !gp ); + } + } + } + else { + for ( int i = 0; i < static_cast(nSize); ++i ) { + if ( i & 1 ) + gp = l.extract( i ); + else + gp = l.extract_with( other_item( i ), other_less() ); + ASSERT_FALSE( !gp ); + EXPECT_EQ( gp->nKey, i ); + + gp = l.extract( i ); + EXPECT_TRUE( !gp ); + gp = l.extract_with( other_item( i ), other_less() ); + EXPECT_TRUE( !gp ); + } + } + + ASSERT_TRUE( l.empty() ); + ASSERT_CONTAINER_SIZE( l, 0 ); + + List::gc::force_dispose(); + for ( auto const& i : arr ) { + EXPECT_EQ( i.s.nDisposeCount, 1 ); + EXPECT_FALSE( l.contains( i ) ); + } + } + }; + +} // namespace cds_test + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H diff --git a/test/unit/intrusive-list/test_intrusive_michael_rcu.h b/test/unit/intrusive-list/test_intrusive_michael_rcu.h new file mode 100644 index 00000000..1105b022 --- /dev/null +++ b/test/unit/intrusive-list/test_intrusive_michael_rcu.h @@ -0,0 +1,306 @@ +/* + 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 CDSUNIT_LIST_TEST_INTRUSIVE_MICHAEL_LIST_RCU_H +#define CDSUNIT_LIST_TEST_INTRUSIVE_MICHAEL_LIST_RCU_H + +#include "test_intrusive_list_rcu.h" +#include + +namespace ci = cds::intrusive; + +template +class IntrusiveMichaelList : public cds_test::intrusive_list_rcu +{ + typedef cds_test::intrusive_list_rcu base_class; +public: + typedef cds::urcu::gc rcu_type; + typedef typename base_class::base_item< ci::michael_list::node< rcu_type >> base_item; + typedef typename base_class::member_item< ci::michael_list::node< rcu_type >> member_item; + +protected: + void SetUp() + { + RCU::Construct(); + cds::threading::Manager::attachThread(); + } + + void TearDown() + { + cds::threading::Manager::detachThread(); + RCU::Destruct(); + } +}; + +TYPED_TEST_CASE_P( IntrusiveMichaelList ); + +TYPED_TEST_P( IntrusiveMichaelList, base_hook ) +{ + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> + , ci::opt::disposer< typename TestFixture::mock_disposer > + , cds::opt::less< typename TestFixture::template less< typename TestFixture::base_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_cmp ) +{ + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> + , ci::opt::disposer< typename TestFixture::mock_disposer > + , cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::base_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_item_counting ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef typename TestFixture::template less< typename TestFixture::base_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_backoff ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef typename TestFixture::template less< typename TestFixture::base_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::pause back_off; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_seqcst ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_stat ) +{ + struct traits: public ci::michael_list::traits { + typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::intrusive::michael_list::stat<> stat; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, base_hook_wrapped_stat ) +{ + struct traits: public ci::michael_list::traits { + typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; + typedef cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook ) +{ + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> + ,ci::opt::disposer< typename TestFixture::mock_disposer > + ,cds::opt::less< typename TestFixture::template less< typename TestFixture::member_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_cmp ) +{ + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, + typename ci::michael_list::make_traits< + ci::opt::hook< ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> + ,ci::opt::disposer< typename TestFixture::mock_disposer > + ,cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::member_item >> + >::type + > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_item_counting ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_seqcst ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::opt::v::sequential_consistent memory_model; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_back_off ) +{ + struct traits : public ci::michael_list::traits { + typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef typename TestFixture::template less< typename TestFixture::member_item > less; + typedef cds::atomicity::item_counter item_counter; + typedef cds::backoff::empty back_off; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_stat ) +{ + struct traits: public ci::michael_list::traits { + typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef cds::intrusive::michael_list::stat<> stat; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + list_type l; + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + +TYPED_TEST_P( IntrusiveMichaelList, member_hook_wrapped_stat ) +{ + struct traits: public ci::michael_list::traits { + typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; + typedef typename TestFixture::mock_disposer disposer; + typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; + typedef cds::intrusive::michael_list::wrapped_stat<> stat; + }; + typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; + + cds::intrusive::michael_list::stat<> st; + list_type l( st ); + this->test_common( l ); + this->test_ordered_iterator( l ); + this->test_rcu( l ); +} + + +// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as +// "No test named can be found in this test case" +REGISTER_TYPED_TEST_CASE_P( IntrusiveMichaelList, + base_hook, base_hook_cmp, base_hook_item_counting, base_hook_backoff, base_hook_seqcst, base_hook_stat, base_hook_wrapped_stat, member_hook, member_hook_cmp, member_hook_item_counting, member_hook_seqcst, member_hook_back_off, member_hook_stat, member_hook_wrapped_stat +); + + +#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H + diff --git a/test/unit/list/CMakeLists.txt b/test/unit/list/CMakeLists.txt index 36d8dc53..e94c5a62 100644 --- a/test/unit/list/CMakeLists.txt +++ b/test/unit/list/CMakeLists.txt @@ -2,24 +2,6 @@ set(PACKAGE_NAME unit-list) set(CDSGTEST_LIST_SOURCES ../main.cpp - intrusive_iterable_dhp.cpp - intrusive_iterable_hp.cpp - intrusive_lazy_hp.cpp - intrusive_lazy_dhp.cpp - intrusive_lazy_nogc.cpp - intrusive_lazy_rcu_gpb.cpp - intrusive_lazy_rcu_gpi.cpp - intrusive_lazy_rcu_gpt.cpp - intrusive_lazy_rcu_shb.cpp - intrusive_lazy_rcu_sht.cpp - intrusive_michael_hp.cpp - intrusive_michael_dhp.cpp - intrusive_michael_nogc.cpp - intrusive_michael_rcu_gpb.cpp - intrusive_michael_rcu_gpi.cpp - intrusive_michael_rcu_gpt.cpp - intrusive_michael_rcu_shb.cpp - intrusive_michael_rcu_sht.cpp iterable_hp.cpp iterable_dhp.cpp kv_iterable_hp.cpp diff --git a/test/unit/list/intrusive_iterable_dhp.cpp b/test/unit/list/intrusive_iterable_dhp.cpp deleted file mode 100644 index 38d8c527..00000000 --- a/test/unit/list/intrusive_iterable_dhp.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - 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 "test_intrusive_iterable_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::DHP gc_type; - - class IntrusiveIterableList_DHP : public cds_test::intrusive_iterable_list_hp - { - protected: - void SetUp() - { - typedef ci::IterableList< gc_type, item_type > list_type; - - // +1 - for guarded_ptr - // +3 - for iterator test - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); - } - }; - - TEST_F( IntrusiveIterableList_DHP, less ) - { - typedef ci::IterableList< gc_type, item_type, - typename ci::iterable_list::make_traits< - ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< item_type >> - , cds::opt::item_counter< cds::atomicity::item_counter > - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, compare ) - { - typedef ci::IterableList< gc_type, item_type, - typename ci::iterable_list::make_traits< - ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< item_type >> - , cds::opt::item_counter< cds::atomicity::item_counter > - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, item_counting ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef cmp< item_type > compare; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, backoff ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef cmp< item_type > compare; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, seqcst ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, stat ) - { - struct traits: public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::iterable_list::stat<> stat; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_DHP, wrapped_stat ) - { - struct traits: public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::iterable_list::wrapped_stat<> stat; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - traits::stat::stat_type st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_iterable_hp.cpp b/test/unit/list/intrusive_iterable_hp.cpp deleted file mode 100644 index 1e253580..00000000 --- a/test/unit/list/intrusive_iterable_hp.cpp +++ /dev/null @@ -1,174 +0,0 @@ -/* - 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 "test_intrusive_iterable_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::HP gc_type; - - class IntrusiveIterableList_HP : public cds_test::intrusive_iterable_list_hp - { - protected: - void SetUp() - { - typedef ci::IterableList< gc_type, item_type > list_type; - - // +1 - for guarded_ptr - // +3 - for iterator test - cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 3, 1, 16 ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::hp::GarbageCollector::Destruct( true ); - } - }; - - TEST_F( IntrusiveIterableList_HP, less ) - { - typedef ci::IterableList< gc_type, item_type, - typename ci::iterable_list::make_traits< - ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< item_type >> - ,cds::opt::item_counter< cds::atomicity::item_counter > - - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, compare ) - { - typedef ci::IterableList< gc_type, item_type, - typename ci::iterable_list::make_traits< - ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< item_type >> - , cds::opt::item_counter< cds::atomicity::item_counter > - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, item_counting ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef cmp< item_type > compare; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, backoff ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef cmp< item_type > compare; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, seqcst ) - { - struct traits : public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, stat ) - { - struct traits: public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::iterable_list::stat<> stat; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveIterableList_HP, wrapped_stat ) - { - struct traits: public ci::iterable_list::traits { - typedef mock_disposer disposer; - typedef intrusive_iterable_list::less< item_type > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::iterable_list::wrapped_stat<> stat; - }; - typedef ci::IterableList< gc_type, item_type, traits > list_type; - - traits::stat::stat_type st; - - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_lazy_dhp.cpp b/test/unit/list/intrusive_lazy_dhp.cpp deleted file mode 100644 index 73246179..00000000 --- a/test/unit/list/intrusive_lazy_dhp.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - 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 "test_intrusive_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::DHP gc_type; - - class IntrusiveLazyList_DHP : public cds_test::intrusive_list_hp - { - public: - typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type>> member_item; - - typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; - typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; - - protected: - void SetUp() - { - struct traits: public ci::lazy_list::traits - { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); - } - }; - - TEST_F( IntrusiveLazyList_DHP, base_hook ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_cmp ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; - typedef mock_disposer disposer; - typedef cmp< base_mutex_item > compare; - typedef intrusive_list_common::less< base_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_backoff ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, base_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef intrusive_list_common::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_cmp ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; - typedef mock_disposer disposer; - typedef cmp< member_mutex_item > compare; - typedef intrusive_list_common::less< member_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_back_off ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_DHP, member_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_lazy_hp.cpp b/test/unit/list/intrusive_lazy_hp.cpp deleted file mode 100644 index bf3d49b5..00000000 --- a/test/unit/list/intrusive_lazy_hp.cpp +++ /dev/null @@ -1,343 +0,0 @@ -/* - 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 "test_intrusive_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::HP gc_type; - - class IntrusiveLazyList_HP : public cds_test::intrusive_list_hp - { - public: - typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type>> member_item; - - typedef cds_test::intrusive_list_hp::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; - typedef cds_test::intrusive_list_hp::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; - - protected: - void SetUp() - { - struct traits: public ci::lazy_list::traits - { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - // +1 - for guarded_ptr - cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 1, 1, 16 ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::hp::GarbageCollector::Destruct( true ); - } - }; - - TEST_F( IntrusiveLazyList_HP, base_hook ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_cmp ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; - typedef mock_disposer disposer; - typedef cmp< base_mutex_item > compare; - typedef intrusive_list_common::less< base_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_backoff ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, base_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_cmp ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; - typedef mock_disposer disposer; - typedef cmp< member_mutex_item > compare; - typedef intrusive_list_common::less< member_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_back_off ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveLazyList_HP, member_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< member_item > compare; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_lazy_nogc.cpp b/test/unit/list/intrusive_lazy_nogc.cpp deleted file mode 100644 index 10039d1d..00000000 --- a/test/unit/list/intrusive_lazy_nogc.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* - 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 "test_intrusive_list_nogc.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::nogc gc_type; - - class IntrusiveLazyList_NOGC : public cds_test::intrusive_list_nogc - { - public: - typedef cds_test::intrusive_list_nogc::base_item< ci::lazy_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_nogc::member_item< ci::lazy_list::node< gc_type>> member_item; - - typedef cds_test::intrusive_list_nogc::base_item< ci::lazy_list::node< gc_type, std::mutex>> base_mutex_item; - typedef cds_test::intrusive_list_nogc::member_item< ci::lazy_list::node< gc_type, std::mutex>> member_mutex_item; - }; - - TEST_F( IntrusiveLazyList_NOGC, base_hook ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_cmp ) - { - typedef ci::LazyList< gc_type, base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef intrusive_list_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex>> hook; - typedef mock_disposer disposer; - typedef cmp< base_mutex_item > compare; - typedef intrusive_list_nogc::less< base_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, base_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_backoff ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef intrusive_list_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef intrusive_list_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef intrusive_list_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, base_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< gc_type >> hook; - typedef mock_disposer disposer; - typedef cmp< base_item > compare; - typedef intrusive_list_nogc::less< base_item > less; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, base_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_cmp ) - { - typedef ci::LazyList< gc_type, member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_item_counting ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_seqcst ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_mutex ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( member_mutex_item, hMember ), cds::opt::gc< gc_type >, cds::opt::lock_type< std::mutex >> hook; - typedef mock_disposer disposer; - typedef cmp< member_mutex_item > compare; - typedef intrusive_list_nogc::less< member_mutex_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< gc_type, member_mutex_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_back_off ) - { - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveLazyList_NOGC, member_hook_wrapped_stat ) - { - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_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_nogc::less< member_item > less; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< gc_type, member_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_lazy_rcu_gpb.cpp b/test/unit/list/intrusive_lazy_rcu_gpb.cpp deleted file mode 100644 index 3b3ff318..00000000 --- a/test/unit/list/intrusive_lazy_rcu_gpb.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_lazy_rcu.h" - -namespace { - - typedef cds::urcu::general_buffered<> rcu_implementation; - typedef cds::urcu::general_buffered_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB, IntrusiveLazyList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_lazy_rcu_gpi.cpp b/test/unit/list/intrusive_lazy_rcu_gpi.cpp deleted file mode 100644 index 6807c48c..00000000 --- a/test/unit/list/intrusive_lazy_rcu_gpi.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_lazy_rcu.h" - -namespace { - - typedef cds::urcu::general_instant<> rcu_implementation; - typedef cds::urcu::general_instant_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI, IntrusiveLazyList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_lazy_rcu_gpt.cpp b/test/unit/list/intrusive_lazy_rcu_gpt.cpp deleted file mode 100644 index e0d943c5..00000000 --- a/test/unit/list/intrusive_lazy_rcu_gpt.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_lazy_rcu.h" - -namespace { - - typedef cds::urcu::general_threaded<> rcu_implementation; - typedef cds::urcu::general_threaded_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT, IntrusiveLazyList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT_stripped, IntrusiveLazyList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_lazy_rcu_shb.cpp b/test/unit/list/intrusive_lazy_rcu_shb.cpp deleted file mode 100644 index 490b0afd..00000000 --- a/test/unit/list/intrusive_lazy_rcu_shb.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - -#include "test_intrusive_lazy_rcu.h" - -namespace { - - typedef cds::urcu::signal_buffered<> rcu_implementation; - typedef cds::urcu::signal_buffered_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB, IntrusiveLazyList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB_stripped, IntrusiveLazyList, rcu_implementation_stripped ); - -#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/list/intrusive_lazy_rcu_sht.cpp b/test/unit/list/intrusive_lazy_rcu_sht.cpp deleted file mode 100644 index 905cf2d4..00000000 --- a/test/unit/list/intrusive_lazy_rcu_sht.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - -#include "test_intrusive_lazy_rcu.h" - -namespace { - - typedef cds::urcu::signal_threaded<> rcu_implementation; - typedef cds::urcu::signal_threaded_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT, IntrusiveLazyList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT_stripped, IntrusiveLazyList, rcu_implementation_stripped ); - -#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/list/intrusive_michael_dhp.cpp b/test/unit/list/intrusive_michael_dhp.cpp deleted file mode 100644 index cbc0d20e..00000000 --- a/test/unit/list/intrusive_michael_dhp.cpp +++ /dev/null @@ -1,302 +0,0 @@ -/* - 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 "test_intrusive_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::DHP gc_type; - - class IntrusiveMichaelList_DHP : public cds_test::intrusive_list_hp - { - public: - typedef cds_test::intrusive_list_hp::base_item< ci::michael_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_hp::member_item< ci::michael_list::node< gc_type>> member_item; - - protected: - void SetUp() - { - struct traits: public ci::michael_list::traits - { - typedef ci::michael_list::base_hook< cds::opt::gc< gc_type >> hook; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - cds::gc::dhp::GarbageCollector::Construct( 16, list_type::c_nHazardPtrCount ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::dhp::GarbageCollector::Destruct(); - } - }; - - TEST_F( IntrusiveMichaelList_DHP, base_hook ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_DHP, base_hook_cmp ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_DHP, base_hook_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::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_DHP, base_hook_backoff ) - { - 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::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - 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_DHP, base_hook_seqcst ) - { - 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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - 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_DHP, base_hook_stat ) - { - 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::intrusive::michael_list::stat<> stat; - }; - 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_DHP, base_hook_wrapped_stat ) - { - 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 cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - - TEST_F( IntrusiveMichaelList_DHP, member_hook ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_DHP, member_hook_cmp ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_DHP, member_hook_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::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 { - 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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - 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_back_off ) - { - 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::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - 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_stat ) - { - 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::intrusive::michael_list::stat<> stat; - }; - 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_wrapped_stat ) - { - 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 cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< gc_type, member_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_michael_hp.cpp b/test/unit/list/intrusive_michael_hp.cpp deleted file mode 100644 index 693a0bfb..00000000 --- a/test/unit/list/intrusive_michael_hp.cpp +++ /dev/null @@ -1,303 +0,0 @@ -/* - 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 "test_intrusive_list_hp.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::HP gc_type; - - class IntrusiveMichaelList_HP : public cds_test::intrusive_list_hp - { - public: - typedef cds_test::intrusive_list_hp::base_item< ci::michael_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_hp::member_item< ci::michael_list::node< gc_type>> member_item; - - protected: - void SetUp() - { - struct traits: public ci::michael_list::traits - { - typedef ci::michael_list::base_hook< cds::opt::gc< gc_type >> hook; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - // +1 - for guarded_ptr - cds::gc::hp::GarbageCollector::Construct( list_type::c_nHazardPtrCount + 1, 1, 16 ); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - cds::gc::hp::GarbageCollector::Destruct( true ); - } - }; - - TEST_F( IntrusiveMichaelList_HP, base_hook ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_HP, base_hook_cmp ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_HP, base_hook_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::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 { - 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::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - 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_seqcst ) - { - 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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - 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_stat ) - { - 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::intrusive::michael_list::stat<> stat; - }; - 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_wrapped_stat ) - { - 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 cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_HP, member_hook ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_HP, member_hook_cmp ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - - TEST_F( IntrusiveMichaelList_HP, member_hook_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::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_HP, member_hook_seqcst ) - { - 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::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - 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_HP, member_hook_back_off ) - { - 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::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - 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_HP, member_hook_stat ) - { - 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::intrusive::michael_list::stat<> stat; - }; - 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_HP, member_hook_wrapped_stat ) - { - 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 cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< gc_type, member_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - test_common( l ); - test_ordered_iterator( l ); - test_hp( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_michael_nogc.cpp b/test/unit/list/intrusive_michael_nogc.cpp deleted file mode 100644 index 21a3ff21..00000000 --- a/test/unit/list/intrusive_michael_nogc.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* - 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 "test_intrusive_list_nogc.h" -#include - -namespace { - namespace ci = cds::intrusive; - typedef cds::gc::nogc gc_type; - - class IntrusiveMichaelList_NOGC : public cds_test::intrusive_list_nogc - { - public: - typedef cds_test::intrusive_list_nogc::base_item< ci::michael_list::node< gc_type>> base_item; - typedef cds_test::intrusive_list_nogc::member_item< ci::michael_list::node< gc_type>> member_item; - }; - - TEST_F( IntrusiveMichaelList_NOGC, base_hook ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, base_hook_cmp ) - { - typedef ci::MichaelList< gc_type, base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< gc_type >>> - , ci::opt::disposer< mock_disposer > - , cds::opt::compare< cmp< base_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, base_hook_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_nogc::less< base_item > less; - typedef cds::atomicity::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_F( IntrusiveMichaelList_NOGC, base_hook_backoff ) - { - 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_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, base_hook_seqcst ) - { - 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_nogc::less< base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::MichaelList< gc_type, base_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, member_hook ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::less< less< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, member_hook_cmp ) - { - typedef ci::MichaelList< gc_type, member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( member_item, hMember ), cds::opt::gc< gc_type >>> - ,ci::opt::disposer< mock_disposer > - ,cds::opt::compare< cmp< member_item >> - >::type - > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, member_hook_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_nogc::less< member_item > less; - typedef cds::atomicity::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_F( IntrusiveMichaelList_NOGC, member_hook_seqcst ) - { - 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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::MichaelList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - - TEST_F( IntrusiveMichaelList_NOGC, member_hook_back_off ) - { - 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_nogc::less< member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::MichaelList< gc_type, member_item, traits > list_type; - - list_type l; - test_common( l ); - test_ordered_iterator( l ); - } - -} // namespace diff --git a/test/unit/list/intrusive_michael_rcu_gpb.cpp b/test/unit/list/intrusive_michael_rcu_gpb.cpp deleted file mode 100644 index d2b0b277..00000000 --- a/test/unit/list/intrusive_michael_rcu_gpb.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_michael_rcu.h" - -namespace { - - typedef cds::urcu::general_buffered<> rcu_implementation; - typedef cds::urcu::general_buffered_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB, IntrusiveMichaelList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPB_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_michael_rcu_gpi.cpp b/test/unit/list/intrusive_michael_rcu_gpi.cpp deleted file mode 100644 index edaeaf3a..00000000 --- a/test/unit/list/intrusive_michael_rcu_gpi.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_michael_rcu.h" - -namespace { - - typedef cds::urcu::general_instant<> rcu_implementation; - typedef cds::urcu::general_instant_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI, IntrusiveMichaelList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPI_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_michael_rcu_gpt.cpp b/test/unit/list/intrusive_michael_rcu_gpt.cpp deleted file mode 100644 index 75c4a4e6..00000000 --- a/test/unit/list/intrusive_michael_rcu_gpt.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - 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 - -#include "test_intrusive_michael_rcu.h" - -namespace { - - typedef cds::urcu::general_threaded<> rcu_implementation; - typedef cds::urcu::general_threaded_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT, IntrusiveMichaelList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_GPT_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); diff --git a/test/unit/list/intrusive_michael_rcu_shb.cpp b/test/unit/list/intrusive_michael_rcu_shb.cpp deleted file mode 100644 index fea8656b..00000000 --- a/test/unit/list/intrusive_michael_rcu_shb.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - -#include "test_intrusive_michael_rcu.h" - -namespace { - - typedef cds::urcu::signal_buffered<> rcu_implementation; - typedef cds::urcu::signal_buffered_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB, IntrusiveMichaelList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHB_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); - -#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/list/intrusive_michael_rcu_sht.cpp b/test/unit/list/intrusive_michael_rcu_sht.cpp deleted file mode 100644 index c75db4d6..00000000 --- a/test/unit/list/intrusive_michael_rcu_sht.cpp +++ /dev/null @@ -1,47 +0,0 @@ -/* - 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 - -#ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED - -#include "test_intrusive_michael_rcu.h" - -namespace { - - typedef cds::urcu::signal_threaded<> rcu_implementation; - typedef cds::urcu::signal_threaded_stripped rcu_implementation_stripped; - -} // namespace - -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT, IntrusiveMichaelList, rcu_implementation ); -INSTANTIATE_TYPED_TEST_CASE_P( RCU_SHT_stripped, IntrusiveMichaelList, rcu_implementation_stripped ); - -#endif // #ifdef CDS_URCU_SIGNAL_HANDLING_ENABLED diff --git a/test/unit/list/test_intrusive_iterable_list.h b/test/unit/list/test_intrusive_iterable_list.h deleted file mode 100644 index 1db06f9c..00000000 --- a/test/unit/list/test_intrusive_iterable_list.h +++ /dev/null @@ -1,554 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H - -#include -#include - -namespace cds_test { - - class intrusive_iterable_list : public fixture - { - public: - struct stat { - int nDisposeCount; - int nUpdateExistsCall; - int nUpdateNewCall; - int nFindCall; - int nEraseCall; - int nInsertCall; - - stat() - : nDisposeCount( 0 ) - , nUpdateExistsCall( 0 ) - , nUpdateNewCall( 0 ) - , nFindCall( 0 ) - , nEraseCall( 0 ) - , nInsertCall( 0 ) - {} - - stat( const stat& s ) - { - *this = s; - } - - stat& operator =( const stat& s ) - { - memcpy( this, &s, sizeof( s ) ); - return *this; - } - }; - - struct item_type - { - int nKey; - int nVal; - - mutable stat s; - - item_type() - {} - - item_type( int key, int val ) - : nKey( key ) - , nVal( val ) - , s() - {} - - item_type( const item_type& v ) - : nKey( v.nKey ) - , nVal( v.nVal ) - , s() - {} - - const int& key() const - { - return nKey; - } - - item_type& operator=( item_type const& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - - item_type& operator=( item_type&& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - }; - - template - struct less - { - bool operator ()( const T& v1, const T& v2 ) const - { - return v1.key() < v2.key(); - } - - template - bool operator ()( const T& v1, const Q& v2 ) const - { - return v1.key() < v2; - } - - template - bool operator ()( const Q& v1, const T& v2 ) const - { - return v1 < v2.key(); - } - }; - - struct other_item { - int nKey; - - other_item( int n ) - : nKey( n ) - {} - }; - - struct other_less { - template - bool operator()( T const& i1, Q const& i2 ) const - { - return i1.nKey < i2.nKey; - } - }; - - template - struct cmp { - int operator ()( const T& v1, const T& v2 ) const - { - if ( v1.key() < v2.key() ) - return -1; - return v1.key() > v2.key() ? 1 : 0; - } - - template - int operator ()( const T& v1, const Q& v2 ) const - { - if ( v1.key() < v2 ) - return -1; - return v1.key() > v2 ? 1 : 0; - } - - template - int operator ()( const Q& v1, const T& v2 ) const - { - if ( v1 < v2.key() ) - return -1; - return v1 > v2.key() ? 1 : 0; - } - }; - - struct mock_disposer - { - template - void operator ()( T * p ) - { - ++p->s.nDisposeCount; - } - }; - - struct update_functor - { - template - void operator()( T& item, T * old ) - { - if ( !old ) - ++item.s.nUpdateNewCall; - else - ++item.s.nUpdateExistsCall; - } - }; - - struct find_functor - { - template - void operator ()( T& item, Q& /*val*/ ) - { - ++item.s.nFindCall; - } - }; - - struct erase_functor - { - template - void operator()( T const& item ) - { - item.s.nEraseCall++; - } - }; - - protected: - template - void test_common( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[ nSize ]; - value_type arr2[ nSize ]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast( i ); - arr[i].nVal = arr[i].nKey * 10; - - arr2[i] = arr[i]; - } - shuffle( arr, arr + nSize ); - shuffle( arr2, arr2 + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - typedef typename List::iterator iterator; - - // insert / find - for ( auto& i : arr ) { - EXPECT_FALSE( l.contains( i.nKey )); - EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - - switch ( i.nKey % 4 ) { - case 0: - EXPECT_TRUE( l.insert( i )); - break; - case 1: - EXPECT_EQ( i.s.nInsertCall, 0 ); - EXPECT_TRUE( l.insert( i, []( value_type& i ) { ++i.s.nInsertCall; } )); - EXPECT_EQ( i.s.nInsertCall, 1 ); - break; - case 2: - { - std::pair ret = l.update( i, []( value_type& i, value_type * old ) { - EXPECT_TRUE( old == nullptr ); - EXPECT_EQ( i.s.nUpdateNewCall, 0 ); - ++i.s.nUpdateNewCall; - }, false ); - EXPECT_EQ( i.s.nUpdateNewCall, 0 ); - EXPECT_EQ( ret.first, false ); - EXPECT_EQ( ret.second, false ); - - ret = l.update( i, []( value_type& i, value_type * old ) { - EXPECT_TRUE( old == nullptr ); - EXPECT_EQ( i.s.nUpdateNewCall, 0 ); - ++i.s.nUpdateNewCall; - }, true ); - EXPECT_EQ( i.s.nUpdateNewCall, 1 ); - EXPECT_EQ( ret.first, true ); - EXPECT_EQ( ret.second, true ); - } - break; - case 3: - { - std::pair ret = l.upsert( i, false ); - EXPECT_EQ( ret.first, false ); - EXPECT_EQ( ret.second, false ); - - ret = l.upsert( i ); - EXPECT_EQ( ret.first, true ); - EXPECT_EQ( ret.second, true ); - } - break; - } - - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 1 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 2 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 3 ); - - EXPECT_FALSE( l.insert( i ) ); - ASSERT_FALSE( l.empty() ); - - int const ckey = i.nKey; - iterator it = l.find( ckey ); - ASSERT_FALSE( it == l.end() ); - EXPECT_EQ( it->nKey, i.nKey ); - EXPECT_EQ( (*it).nVal, i.nVal ); - check_ordered( it, l.end() ); - - it = l.find( i.nKey ); - ASSERT_FALSE( it == l.end() ); - EXPECT_EQ( it->nKey, i.nKey ); - EXPECT_EQ( (*it).nVal, i.nVal ); - check_ordered( it, l.end() ); - - it = l.find_with( other_item( i.nKey ), other_less() ); - ASSERT_FALSE( it == l.end() ); - EXPECT_EQ( it->nKey, i.nKey ); - EXPECT_EQ( it->nVal, i.nVal ); - check_ordered( it, l.end() ); - - } - ASSERT_CONTAINER_SIZE( l, nSize ); - - // check all items - for ( auto const& i : arr ) { - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 4 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 5 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 6 ); - } - ASSERT_FALSE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, nSize ); - - // update existing test - for ( auto& i : arr2 ) { - EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); - std::pair ret = l.update( i, update_functor() ); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - } - - // update with the same value must be empty - no functor is called - for ( auto& i : arr2 ) { - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - std::pair ret = l.update( i, update_functor() ); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - } - - // Apply retired pointer to clean links - List::gc::force_dispose(); - - for ( auto& i : arr ) { - EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); - std::pair ret = l.update( i, []( value_type& i, value_type * old ) { - EXPECT_FALSE( old == nullptr ); - EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); - ++i.s.nUpdateExistsCall; - }); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - } - - // erase test - for ( auto const& i : arr ) { - if ( i.nKey & 1 ) - EXPECT_TRUE( l.erase( i.nKey )); - else - EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less() )); - - EXPECT_FALSE( l.contains( i )); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - - for ( auto const& i : arr ) - EXPECT_EQ( i.s.nDisposeCount, 2 ); - for ( auto const& i : arr2 ) - EXPECT_EQ( i.s.nDisposeCount, 1 ); - - // erase with functor - for ( auto& i : arr ) { - int const updateNewCall = i.s.nUpdateNewCall; - std::pair ret = l.update( i, update_functor(), false ); - EXPECT_FALSE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateNewCall, updateNewCall ); - - ret = l.update( i, update_functor(), true ); - EXPECT_TRUE( ret.first ); - EXPECT_TRUE( ret.second ); - EXPECT_EQ( i.s.nUpdateNewCall, updateNewCall + 1 ); - } - EXPECT_FALSE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, nSize ); - - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nEraseCall, 0 ); - if ( i.nKey & 1 ) { - EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); - EXPECT_FALSE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); - } - else { - EXPECT_TRUE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); - EXPECT_FALSE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); - } - EXPECT_EQ( i.s.nEraseCall, 1 ); - EXPECT_FALSE( l.contains( i.nKey )); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - - for ( auto const& i : arr ) - EXPECT_EQ( i.s.nDisposeCount, 3 ); - - // clear test - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i )); - - EXPECT_FALSE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, nSize ); - - l.clear(); - - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 4 ); - EXPECT_FALSE( l.contains( i )); - } - - // unlink test - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - for ( auto& i : arr ) { - value_type val( i ); - EXPECT_TRUE( l.contains( val )); - EXPECT_FALSE( l.unlink( val )); - EXPECT_TRUE( l.contains( val ) ); - EXPECT_TRUE( l.unlink( i )); - EXPECT_FALSE( l.unlink( i )); - EXPECT_FALSE( l.contains( i ) ); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 5 ); - EXPECT_FALSE( l.contains( i ) ); - } - - // Iterators on empty list - { - auto it = l.begin(); - auto itEnd = l.end(); - auto cit = l.cbegin(); - auto citEnd = l.cend(); - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - - ++it; - ++cit; - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - } - } - - template - void test_ordered_iterator( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[nSize]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast(i); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - - int key = 0; - for ( auto it = l.begin(); it != l.end(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - key = 0; - for ( auto it = l.cbegin(); it != l.cend(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - l.clear(); - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - - template - void check_ordered( Iterator first, Iterator last ) - { - while ( first != last ) { - Iterator it = first; - if ( ++it != last ) { - EXPECT_LT( first->nKey, it->nKey ); - } - first = it; - } - } - - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_H diff --git a/test/unit/list/test_intrusive_iterable_list_hp.h b/test/unit/list/test_intrusive_iterable_list_hp.h deleted file mode 100644 index 4fbb63db..00000000 --- a/test/unit/list/test_intrusive_iterable_list_hp.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H - -#include "test_intrusive_iterable_list.h" - -namespace cds_test { - - class intrusive_iterable_list_hp : public intrusive_iterable_list - { - protected: - template - void test_hp( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[nSize]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast(i); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - typedef typename List::guarded_ptr guarded_ptr; - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - guarded_ptr gp; - - // get() test - for ( auto& i : arr ) { - gp = l.get( i.nKey ); - EXPECT_TRUE( !gp ); - gp = l.get_with( other_item( i.nKey ), other_less() ); - EXPECT_TRUE( !gp ); - - EXPECT_TRUE( l.insert( i ) ); - - gp = l.get( i.nKey ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i.nKey ); - EXPECT_EQ( gp->nVal, i.nVal ); - gp = l.get_with( other_item( i.nKey ), other_less() ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i.nKey ); - EXPECT_EQ( gp->nVal, i.nVal ); - } - - // extract() test - for ( int i = 0; i < static_cast(nSize); ++i ) { - if ( i & 1 ) - gp = l.extract( i ); - else - gp = l.extract_with( other_item( i ), other_less() ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i ); - - gp = l.extract( i ); - EXPECT_TRUE( !gp ); - gp = l.extract_with( other_item( i ), other_less() ); - EXPECT_TRUE( !gp ); - } - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_ITERABLE_LIST_HP_H diff --git a/test/unit/list/test_intrusive_lazy_rcu.h b/test/unit/list/test_intrusive_lazy_rcu.h deleted file mode 100644 index bb8e5fcb..00000000 --- a/test/unit/list/test_intrusive_lazy_rcu.h +++ /dev/null @@ -1,310 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H - -#include "test_intrusive_list_rcu.h" -#include - -namespace ci = cds::intrusive; - -template -class IntrusiveLazyList : public cds_test::intrusive_list_rcu -{ - typedef cds_test::intrusive_list_rcu base_class; -public: - typedef cds::urcu::gc rcu_type; - typedef typename base_class::base_item< ci::lazy_list::node< rcu_type >> base_item; - typedef typename base_class::member_item< ci::lazy_list::node< rcu_type >> member_item; - -protected: - void SetUp() - { - RCU::Construct(); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - RCU::Destruct(); - } -}; - -TYPED_TEST_CASE_P( IntrusiveLazyList ); - -TYPED_TEST_P( IntrusiveLazyList, base_hook ) -{ - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> - , ci::opt::disposer< typename TestFixture::mock_disposer > - , cds::opt::less< typename TestFixture::template less< typename TestFixture::base_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_cmp ) -{ - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> - , ci::opt::disposer< typename TestFixture::mock_disposer > - , cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::base_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_item_counting ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef typename TestFixture::template less< typename TestFixture::base_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_backoff ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef typename TestFixture::template less< typename TestFixture::base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_seqcst ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_stat ) -{ - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, base_hook_wrapped_stat ) -{ - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook ) -{ - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> - ,ci::opt::disposer< typename TestFixture::mock_disposer > - ,cds::opt::less< typename TestFixture::template less< typename TestFixture::member_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_cmp ) -{ - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, - typename ci::lazy_list::make_traits< - ci::opt::hook< ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> - ,ci::opt::disposer< typename TestFixture::mock_disposer > - ,cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::member_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_item_counting ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_seqcst ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_back_off ) -{ - struct traits : public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_stat ) -{ - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::stat<> stat; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveLazyList, member_hook_wrapped_stat ) -{ - struct traits: public ci::lazy_list::traits { - typedef ci::lazy_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef cds::atomicity::item_counter item_counter; - typedef cds::intrusive::lazy_list::wrapped_stat<> stat; - }; - typedef ci::LazyList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - cds::intrusive::lazy_list::stat<> st; - list_type l( st ); - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as -// "No test named can be found in this test case" -REGISTER_TYPED_TEST_CASE_P( IntrusiveLazyList, - base_hook, base_hook_cmp, base_hook_item_counting, base_hook_backoff, base_hook_seqcst, base_hook_stat, base_hook_wrapped_stat, member_hook, member_hook_cmp, member_hook_item_counting, member_hook_seqcst, member_hook_back_off, member_hook_stat, member_hook_wrapped_stat -); - - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LAZY_LIST_RCU_H - diff --git a/test/unit/list/test_intrusive_list.h b/test/unit/list/test_intrusive_list.h deleted file mode 100644 index fc3fe801..00000000 --- a/test/unit/list/test_intrusive_list.h +++ /dev/null @@ -1,506 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H - -#include -#include - -namespace cds_test { - - class intrusive_list_common : public fixture - { - public: - struct stat { - int nDisposeCount; - int nUpdateExistsCall; - int nUpdateNewCall; - int nFindCall; - int nEraseCall; - int nInsertCall; - - stat() - : nDisposeCount( 0 ) - , nUpdateExistsCall( 0 ) - , nUpdateNewCall( 0 ) - , nFindCall( 0 ) - , nEraseCall( 0 ) - , nInsertCall( 0 ) - {} - - stat( const stat& s ) - { - *this = s; - } - - stat& operator =( const stat& s ) - { - memcpy( this, &s, sizeof( s ) ); - return *this; - } - }; - - template - struct base_item : public Node - { - int nKey; - int nVal; - - mutable stat s; - - base_item() - {} - - base_item( int key, int val ) - : nKey( key ) - , nVal( val ) - , s() - {} - - base_item( const base_item& v ) - : nKey( v.nKey ) - , nVal( v.nVal ) - , s() - {} - - const int& key() const - { - return nKey; - } - - base_item& operator=( base_item const& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - - base_item& operator=( base_item&& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - }; - - template - struct member_item - { - int nKey; - int nVal; - Node hMember; - mutable stat s; - - member_item() - {} - - member_item( int key, int val ) - : nKey( key ) - , nVal( val ) - , s() - {} - - member_item( const member_item& v ) - : nKey( v.nKey ) - , nVal( v.nVal ) - , s() - {} - - const int& key() const - { - return nKey; - } - - member_item& operator =( member_item const& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - - member_item& operator=( member_item&& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - }; - - template - struct less - { - bool operator ()( const T& v1, const T& v2 ) const - { - return v1.key() < v2.key(); - } - - template - bool operator ()( const T& v1, const Q& v2 ) const - { - return v1.key() < v2; - } - - template - bool operator ()( const Q& v1, const T& v2 ) const - { - return v1 < v2.key(); - } - }; - - struct other_item { - int nKey; - - other_item( int n ) - : nKey( n ) - {} - }; - - struct other_less { - template - bool operator()( T const& i1, Q const& i2 ) const - { - return i1.nKey < i2.nKey; - } - }; - - template - struct cmp { - int operator ()( const T& v1, const T& v2 ) const - { - if ( v1.key() < v2.key() ) - return -1; - return v1.key() > v2.key() ? 1 : 0; - } - - template - int operator ()( const T& v1, const Q& v2 ) const - { - if ( v1.key() < v2 ) - return -1; - return v1.key() > v2 ? 1 : 0; - } - - template - int operator ()( const Q& v1, const T& v2 ) const - { - if ( v1 < v2.key() ) - return -1; - return v1 > v2.key() ? 1 : 0; - } - }; - - struct mock_disposer - { - template - void operator ()( T * p ) - { - ++p->s.nDisposeCount; - } - }; - - struct update_functor - { - template - void operator ()( bool bNew, T& item, T& /*val*/ ) - { - if ( bNew ) - ++item.s.nUpdateNewCall; - else - ++item.s.nUpdateExistsCall; - } - }; - - struct find_functor - { - template - void operator ()( T& item, Q& /*val*/ ) - { - ++item.s.nFindCall; - } - }; - - struct erase_functor - { - template - void operator()( T const& item ) - { - item.s.nEraseCall++; - } - }; - - protected: - template - void test_common( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[ nSize ]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast( i ); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - // insert / find - for ( auto& i : arr ) { - EXPECT_FALSE( l.contains( i.nKey )); - EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - - if ( i.nKey & 1 ) - EXPECT_TRUE( l.insert( i )); - else { - EXPECT_EQ( i.s.nInsertCall, 0 ); - EXPECT_TRUE( l.insert( i, []( value_type& i ) { ++i.s.nInsertCall; } )); - EXPECT_EQ( i.s.nInsertCall, 1 ); - } - - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 1 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 2 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 3 ); - - EXPECT_FALSE( l.insert( i ) ); - ASSERT_FALSE( l.empty() ); - } - ASSERT_CONTAINER_SIZE( l, nSize ); - - // check all items - for ( auto const& i : arr ) { - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 4 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 5 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 6 ); - } - ASSERT_FALSE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, nSize ); - - // update existing test - for ( auto& i : arr ) { - EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); - std::pair ret = l.update( i, update_functor() ); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - - ret = l.update( i, []( bool bNew, value_type& i, value_type& arg ) { - EXPECT_FALSE( bNew ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - EXPECT_TRUE( &i == &arg ); - ++i.s.nUpdateExistsCall; - }); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 2 ); - } - - // erase test - for ( auto const& i : arr ) { - if ( i.nKey & 1 ) - EXPECT_TRUE( l.erase( i.nKey )); - else - EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less() )); - - EXPECT_FALSE( l.contains( i )); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - - for ( auto const& i : arr ) - EXPECT_EQ( i.s.nDisposeCount, 1 ); - - // erase with functor - for ( auto& i : arr ) { - std::pair ret = l.update( i, update_functor(), false ); - EXPECT_FALSE( ret.first ); - EXPECT_FALSE( ret.second ); - - ret = l.update( i, update_functor(), true ); - EXPECT_TRUE( ret.first ); - EXPECT_TRUE( ret.second ); - EXPECT_EQ( i.s.nUpdateNewCall, 1 ); - } - EXPECT_FALSE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, nSize ); - - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nEraseCall, 0 ); - if ( i.nKey & 1 ) { - EXPECT_TRUE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); - EXPECT_FALSE( l.erase_with( other_item( i.nKey ), other_less(), erase_functor())); - } - else { - EXPECT_TRUE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); - EXPECT_FALSE( l.erase( i.nKey, []( value_type& item) { ++item.s.nEraseCall; } )); - } - EXPECT_EQ( i.s.nEraseCall, 1 ); - EXPECT_FALSE( l.contains( i.nKey )); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - - for ( auto const& i : arr ) - EXPECT_EQ( i.s.nDisposeCount, 2 ); - - // clear test - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i )); - - EXPECT_FALSE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, nSize ); - - l.clear(); - - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 3 ); - EXPECT_FALSE( l.contains( i )); - } - - // unlink test - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - for ( auto& i : arr ) { - value_type val( i ); - EXPECT_TRUE( l.contains( val )); - EXPECT_FALSE( l.unlink( val )); - EXPECT_TRUE( l.contains( val ) ); - EXPECT_TRUE( l.unlink( i )); - EXPECT_FALSE( l.unlink( i )); - EXPECT_FALSE( l.contains( i ) ); - } - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 4 ); - EXPECT_FALSE( l.contains( i ) ); - } - - // Iterators on empty list - { - auto it = l.begin(); - auto itEnd = l.end(); - auto cit = l.cbegin(); - auto citEnd = l.cend(); - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - - ++it; - ++cit; - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - } - } - - template - void test_ordered_iterator( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[nSize]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast(i); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - - int key = 0; - for ( auto it = l.begin(); it != l.end(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - key = 0; - for ( auto it = l.cbegin(); it != l.cend(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - l.clear(); - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_H diff --git a/test/unit/list/test_intrusive_list_hp.h b/test/unit/list/test_intrusive_list_hp.h deleted file mode 100644 index b5a95814..00000000 --- a/test/unit/list/test_intrusive_list_hp.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H - -#include "test_intrusive_list.h" - -namespace cds_test { - - class intrusive_list_hp : public intrusive_list_common - { - protected: - template - void test_hp( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[ nSize ]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast( i ); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - typedef typename List::guarded_ptr guarded_ptr; - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - guarded_ptr gp; - - // get() test - for ( auto& i : arr ) { - gp = l.get( i.nKey ); - EXPECT_TRUE( !gp ); - gp = l.get_with( other_item( i.nKey ), other_less()); - EXPECT_TRUE( !gp ); - - EXPECT_TRUE( l.insert( i )); - - gp = l.get( i.nKey ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i.nKey ); - EXPECT_EQ( gp->nVal, i.nVal ); - gp = l.get_with( other_item( i.nKey ), other_less() ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i.nKey ); - EXPECT_EQ( gp->nVal, i.nVal ); - } - - // extract() test - for ( int i = 0; i < static_cast(nSize); ++i ) { - if ( i & 1 ) - gp = l.extract( i ); - else - gp = l.extract_with( other_item(i), other_less()); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i ); - - gp = l.extract( i ); - EXPECT_TRUE( !gp ); - gp = l.extract_with( other_item( i ), other_less() ); - EXPECT_TRUE( !gp ); - } - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_HP_H diff --git a/test/unit/list/test_intrusive_list_nogc.h b/test/unit/list/test_intrusive_list_nogc.h deleted file mode 100644 index c9298c8b..00000000 --- a/test/unit/list/test_intrusive_list_nogc.h +++ /dev/null @@ -1,493 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H - -#include -#include - -namespace cds_test { - - class intrusive_list_nogc : public fixture - { - public: - struct stat { - int nDisposeCount; - int nUpdateExistsCall; - int nUpdateNewCall; - int nFindCall; - - stat() - : nDisposeCount( 0 ) - , nUpdateExistsCall( 0 ) - , nUpdateNewCall( 0 ) - , nFindCall( 0 ) - {} - - stat( const stat& s ) - { - *this = s; - } - - stat& operator =( const stat& s ) - { - memcpy( this, &s, sizeof( s ) ); - return *this; - } - }; - - template - struct base_item : public Node - { - int nKey; - int nVal; - - mutable stat s; - - base_item() - {} - - base_item( int key, int val ) - : nKey( key ) - , nVal( val ) - , s() - {} - - base_item( const base_item& v ) - : nKey( v.nKey ) - , nVal( v.nVal ) - , s() - {} - - const int& key() const - { - return nKey; - } - - base_item& operator=( base_item const& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - - base_item& operator=( base_item&& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - }; - - template - struct member_item - { - int nKey; - int nVal; - Node hMember; - mutable stat s; - - member_item() - {} - - member_item( int key, int val ) - : nKey( key ) - , nVal( val ) - , s() - {} - - member_item( const member_item& v ) - : nKey( v.nKey ) - , nVal( v.nVal ) - , s() - {} - - const int& key() const - { - return nKey; - } - - member_item& operator =( member_item const& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - - member_item& operator=( member_item&& src ) - { - nKey = src.nKey; - nVal = src.nVal; - return *this; - } - }; - - template - struct less - { - bool operator ()( const T& v1, const T& v2 ) const - { - return v1.key() < v2.key(); - } - - template - bool operator ()( const T& v1, const Q& v2 ) const - { - return v1.key() < v2; - } - - template - bool operator ()( const Q& v1, const T& v2 ) const - { - return v1 < v2.key(); - } - }; - - struct other_item { - int nKey; - - other_item( int n ) - : nKey( n ) - {} - }; - - struct other_less { - template - bool operator()( T const& i1, Q const& i2 ) const - { - return i1.nKey < i2.nKey; - } - }; - - template - struct cmp { - int operator ()( const T& v1, const T& v2 ) const - { - if ( v1.key() < v2.key() ) - return -1; - return v1.key() > v2.key() ? 1 : 0; - } - - template - int operator ()( const T& v1, const Q& v2 ) const - { - if ( v1.key() < v2 ) - return -1; - return v1.key() > v2 ? 1 : 0; - } - - template - int operator ()( const Q& v1, const T& v2 ) const - { - if ( v1 < v2.key() ) - return -1; - return v1 > v2.key() ? 1 : 0; - } - }; - - struct mock_disposer - { - template - void operator ()( T * p ) - { - ++p->s.nDisposeCount; - } - }; - - struct mock_disposer2 - { - template - void operator ()( T * p ) - { - p->s.nDisposeCount += 10; - } - }; - - struct update_functor - { - template - void operator ()( bool bNew, T& item, T& /*val*/ ) - { - if ( bNew ) - ++item.s.nUpdateNewCall; - else - ++item.s.nUpdateExistsCall; - } - }; - - struct find_functor - { - template - void operator ()( T& item, Q& /*val*/ ) - { - ++item.s.nFindCall; - } - }; - - struct erase_functor - { - template - void operator()( T const& item ) - { - item.s.nEraseCall++; - } - }; - - protected: - template - void test_common( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[ nSize ]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast( i ); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - // insert / find - for ( auto& i : arr ) { - EXPECT_FALSE( l.contains( i.nKey )); - EXPECT_FALSE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_FALSE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - EXPECT_FALSE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 0 ); - - EXPECT_TRUE( l.insert( i )); - - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 1 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 2 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 3 ); - - EXPECT_FALSE( l.insert( i ) ); - ASSERT_FALSE( l.empty() ); - } - ASSERT_CONTAINER_SIZE( l, nSize ); - - // check all items - for ( auto const& i : arr ) { - EXPECT_TRUE( l.contains( i.nKey )); - EXPECT_TRUE( l.contains( i )); - EXPECT_TRUE( l.contains( other_item( i.nKey ), other_less())); - EXPECT_TRUE( l.find( i.nKey, []( value_type& item, int ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 4 ); - EXPECT_TRUE( l.find( i, []( value_type& item, value_type const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 5 ); - EXPECT_TRUE( l.find_with( other_item( i.nKey ), other_less(), []( value_type& item, other_item const& ) { ++item.s.nFindCall; } )); - EXPECT_EQ( i.s.nFindCall, 6 ); - } - ASSERT_FALSE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, nSize ); - - // update existing test - for ( auto& i : arr ) { - EXPECT_EQ( i.s.nUpdateExistsCall, 0 ); - std::pair ret = l.update( i, update_functor() ); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - - ret = l.update( i, []( bool bNew, value_type& i, value_type& arg ) { - EXPECT_FALSE( bNew ); - EXPECT_EQ( i.s.nUpdateExistsCall, 1 ); - EXPECT_TRUE( &i == &arg ); - ++i.s.nUpdateExistsCall; - }); - EXPECT_TRUE( ret.first ); - EXPECT_FALSE( ret.second ); - EXPECT_EQ( i.s.nUpdateExistsCall, 2 ); - } - - // clear() test - l.clear(); - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - - - for ( auto& i : arr ) { - std::pair ret = l.update( i, update_functor(), false ); - EXPECT_FALSE( ret.first ); - EXPECT_FALSE( ret.second ); - - ret = l.update( i, update_functor(), true ); - EXPECT_TRUE( ret.first ); - EXPECT_TRUE( ret.second ); - EXPECT_EQ( i.s.nUpdateNewCall, 1 ); - } - - EXPECT_FALSE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, nSize ); - - l.clear( mock_disposer2()); - - EXPECT_TRUE( l.empty() ); - EXPECT_CONTAINER_SIZE( l, 0 ); - - // Apply retired pointer to clean links - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 11 ); - EXPECT_FALSE( l.contains( i )); - } - - // Iterators on empty list - { - auto it = l.begin(); - auto itEnd = l.end(); - auto cit = l.cbegin(); - auto citEnd = l.cend(); - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - - ++it; - ++cit; - - EXPECT_TRUE( it == itEnd ); - EXPECT_TRUE( it == cit ); - EXPECT_TRUE( cit == citEnd ); - } - } - - template - void test_ordered_iterator( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[nSize]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast(i); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - - int key = 0; - for ( auto it = l.begin(); it != l.end(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - key = 0; - for ( auto it = l.cbegin(); it != l.cend(); ++it ) { - EXPECT_EQ( it->nKey, key ); - EXPECT_EQ( (*it).nKey, key ); - ++key; - } - - l.clear(); - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - - template - void test_unordered_iterator( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[nSize]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast(i); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - for ( auto& i : arr ) - EXPECT_TRUE( l.insert( i ) ); - - size_t idx = 0; - for ( auto it = l.begin(); it != l.end(); ++it, ++idx ) { - ASSERT_LT( idx, nSize ); - EXPECT_EQ( it->nKey, arr[idx].nKey ); - EXPECT_EQ( (*it).nKey, arr[idx].nKey ); - } - - idx = 0; - for ( auto it = l.cbegin(); it != l.cend(); ++it, ++idx ) { - ASSERT_LT( idx, nSize ); - EXPECT_EQ( it->nKey, arr[idx].nKey ); - EXPECT_EQ( (*it).nKey, arr[idx].nKey ); - } - - l.clear(); - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_NOGC_H diff --git a/test/unit/list/test_intrusive_list_rcu.h b/test/unit/list/test_intrusive_list_rcu.h deleted file mode 100644 index 9df70379..00000000 --- a/test/unit/list/test_intrusive_list_rcu.h +++ /dev/null @@ -1,146 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H - -#include "test_intrusive_list.h" - -namespace cds_test { - - class intrusive_list_rcu : public intrusive_list_common - { - protected: - template - void test_rcu( List& l ) - { - // Precondition: list is empty - // Postcondition: list is empty - - static const size_t nSize = 20; - typedef typename List::value_type value_type; - value_type arr[ nSize ]; - - for ( size_t i = 0; i < nSize; ++i ) { - arr[i].nKey = static_cast( i ); - arr[i].nVal = arr[i].nKey * 10; - } - shuffle( arr, arr + nSize ); - - typedef typename List::exempt_ptr exempt_ptr; - typedef typename List::raw_ptr raw_ptr; - typedef typename List::rcu_lock rcu_lock; - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - // get() test - for ( auto& i : arr ) { - { - rcu_lock lock; - raw_ptr rp = l.get( i.nKey ); - EXPECT_TRUE( !rp ); - rp = l.get_with( other_item( i.nKey ), other_less()); - EXPECT_TRUE( !rp ); - } - - EXPECT_TRUE( l.insert( i )); - - { - rcu_lock lock; - raw_ptr rp = l.get( i.nKey ); - ASSERT_FALSE( !rp ); - EXPECT_EQ( rp->nKey, i.nKey ); - EXPECT_EQ( rp->nVal, i.nVal ); - } - { - rcu_lock lock; - raw_ptr rp = l.get_with( other_item( i.nKey ), other_less() ); - ASSERT_FALSE( !rp ); - EXPECT_EQ( rp->nKey, i.nKey ); - EXPECT_EQ( rp->nVal, i.nVal ); - } - } - - exempt_ptr gp; - - // extract() test - if ( List::c_bExtractLockExternal ) { - for ( int i = 0; i < static_cast(nSize); ++i ) { - { - rcu_lock lock; - - if ( i & 1 ) - gp = l.extract( i ); - else - gp = l.extract_with( other_item(i), other_less()); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i ); - } - gp.release(); - { - rcu_lock lock; - - gp = l.extract( i ); - EXPECT_TRUE( !gp ); - gp = l.extract_with( other_item( i ), other_less() ); - EXPECT_TRUE( !gp ); - } - } - } - else { - for ( int i = 0; i < static_cast(nSize); ++i ) { - if ( i & 1 ) - gp = l.extract( i ); - else - gp = l.extract_with( other_item( i ), other_less() ); - ASSERT_FALSE( !gp ); - EXPECT_EQ( gp->nKey, i ); - - gp = l.extract( i ); - EXPECT_TRUE( !gp ); - gp = l.extract_with( other_item( i ), other_less() ); - EXPECT_TRUE( !gp ); - } - } - - ASSERT_TRUE( l.empty() ); - ASSERT_CONTAINER_SIZE( l, 0 ); - - List::gc::force_dispose(); - for ( auto const& i : arr ) { - EXPECT_EQ( i.s.nDisposeCount, 1 ); - EXPECT_FALSE( l.contains( i ) ); - } - } - }; - -} // namespace cds_test - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H diff --git a/test/unit/list/test_intrusive_michael_rcu.h b/test/unit/list/test_intrusive_michael_rcu.h deleted file mode 100644 index 1105b022..00000000 --- a/test/unit/list/test_intrusive_michael_rcu.h +++ /dev/null @@ -1,306 +0,0 @@ -/* - 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 CDSUNIT_LIST_TEST_INTRUSIVE_MICHAEL_LIST_RCU_H -#define CDSUNIT_LIST_TEST_INTRUSIVE_MICHAEL_LIST_RCU_H - -#include "test_intrusive_list_rcu.h" -#include - -namespace ci = cds::intrusive; - -template -class IntrusiveMichaelList : public cds_test::intrusive_list_rcu -{ - typedef cds_test::intrusive_list_rcu base_class; -public: - typedef cds::urcu::gc rcu_type; - typedef typename base_class::base_item< ci::michael_list::node< rcu_type >> base_item; - typedef typename base_class::member_item< ci::michael_list::node< rcu_type >> member_item; - -protected: - void SetUp() - { - RCU::Construct(); - cds::threading::Manager::attachThread(); - } - - void TearDown() - { - cds::threading::Manager::detachThread(); - RCU::Destruct(); - } -}; - -TYPED_TEST_CASE_P( IntrusiveMichaelList ); - -TYPED_TEST_P( IntrusiveMichaelList, base_hook ) -{ - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> - , ci::opt::disposer< typename TestFixture::mock_disposer > - , cds::opt::less< typename TestFixture::template less< typename TestFixture::base_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_cmp ) -{ - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >>> - , ci::opt::disposer< typename TestFixture::mock_disposer > - , cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::base_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_item_counting ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef typename TestFixture::template less< typename TestFixture::base_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_backoff ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef typename TestFixture::template less< typename TestFixture::base_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::pause back_off; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_seqcst ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_stat ) -{ - struct traits: public ci::michael_list::traits { - typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::intrusive::michael_list::stat<> stat; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, base_hook_wrapped_stat ) -{ - struct traits: public ci::michael_list::traits { - typedef ci::michael_list::base_hook< cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::base_item > compare; - typedef cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::base_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook ) -{ - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> - ,ci::opt::disposer< typename TestFixture::mock_disposer > - ,cds::opt::less< typename TestFixture::template less< typename TestFixture::member_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_cmp ) -{ - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, - typename ci::michael_list::make_traits< - ci::opt::hook< ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >>> - ,ci::opt::disposer< typename TestFixture::mock_disposer > - ,cds::opt::compare< typename TestFixture::template cmp< typename TestFixture::member_item >> - >::type - > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_item_counting ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_seqcst ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::opt::v::sequential_consistent memory_model; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_back_off ) -{ - struct traits : public ci::michael_list::traits { - typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef typename TestFixture::template less< typename TestFixture::member_item > less; - typedef cds::atomicity::item_counter item_counter; - typedef cds::backoff::empty back_off; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_stat ) -{ - struct traits: public ci::michael_list::traits { - typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef cds::intrusive::michael_list::stat<> stat; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - list_type l; - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - -TYPED_TEST_P( IntrusiveMichaelList, member_hook_wrapped_stat ) -{ - struct traits: public ci::michael_list::traits { - typedef ci::michael_list::member_hook< offsetof( typename TestFixture::member_item, hMember ), cds::opt::gc< typename TestFixture::rcu_type >> hook; - typedef typename TestFixture::mock_disposer disposer; - typedef typename TestFixture::template cmp< typename TestFixture::member_item > compare; - typedef cds::intrusive::michael_list::wrapped_stat<> stat; - }; - typedef ci::MichaelList< typename TestFixture::rcu_type, typename TestFixture::member_item, traits > list_type; - - cds::intrusive::michael_list::stat<> st; - list_type l( st ); - this->test_common( l ); - this->test_ordered_iterator( l ); - this->test_rcu( l ); -} - - -// GCC 5: All test names should be written on single line, otherwise a runtime error will be encountered like as -// "No test named can be found in this test case" -REGISTER_TYPED_TEST_CASE_P( IntrusiveMichaelList, - base_hook, base_hook_cmp, base_hook_item_counting, base_hook_backoff, base_hook_seqcst, base_hook_stat, base_hook_wrapped_stat, member_hook, member_hook_cmp, member_hook_item_counting, member_hook_seqcst, member_hook_back_off, member_hook_stat, member_hook_wrapped_stat -); - - -#endif // CDSUNIT_LIST_TEST_INTRUSIVE_LIST_RCU_H -