From: khizmax Date: Sat, 23 Apr 2016 09:56:48 +0000 (+0300) Subject: Migrated misc unit test to gtest framework X-Git-Tag: v2.2.0~264 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=35a5ac4db91117a0a53a2544f71c10061e0eda08;p=libcds.git Migrated misc unit test to gtest framework Removed old test-hdr --- diff --git a/projects/Win/vc14/cds.sln b/projects/Win/vc14/cds.sln index e899f3b6..87e2b638 100644 --- a/projects/Win/vc14/cds.sln +++ b/projects/Win/vc14/cds.sln @@ -29,17 +29,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-misc", "unit-misc.vcxp {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} EndProjectSection EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "single-threaded test", "single-threaded test", "{B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75}" - ProjectSection(SolutionItems) = preProject - ..\..\..\tests\test-hdr\size_check.h = ..\..\..\tests\test-hdr\size_check.h - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hdr-test-misc", "hdr-test-misc.vcxproj", "{C5E76975-B87B-4B9E-8596-B01DDA683FCA}" - ProjectSection(ProjectDependencies) = postProject - {61179F2F-07E1-490D-B64D-D85A90B6EF81} = {61179F2F-07E1-490D-B64D-D85A90B6EF81} - {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} - EndProjectSection -EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "map", "map", "{6BB7A27F-FC59-4267-B6FA-D034176D1459}" ProjectSection(SolutionItems) = preProject ..\..\..\tests\unit\map2\map_defs.h = ..\..\..\tests\unit\map2\map_defs.h @@ -214,6 +203,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-tree", "gtest-tree.vc {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-misc", "gtest-misc.vcxproj", "{FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}" + ProjectSection(ProjectDependencies) = postProject + {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -260,18 +254,6 @@ Global {77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|Win32.Build.0 = Release|Win32 {77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|x64.ActiveCfg = Release|x64 {77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|x64.Build.0 = Release|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|Win32.ActiveCfg = Debug|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|Win32.Build.0 = Debug|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|x64.ActiveCfg = Debug|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|x64.Build.0 = Debug|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|Win32.Build.0 = DebugVLD|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|x64.ActiveCfg = DebugVLD|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|x64.Build.0 = DebugVLD|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|Win32.ActiveCfg = Release|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|Win32.Build.0 = Release|Win32 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|x64.ActiveCfg = Release|x64 - {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|x64.Build.0 = Release|x64 {3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|Win32.ActiveCfg = Debug|Win32 {3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|Win32.Build.0 = Debug|Win32 {3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|x64.ActiveCfg = Debug|x64 @@ -548,6 +530,18 @@ Global {2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|Win32.Build.0 = Release|Win32 {2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|x64.ActiveCfg = Release|x64 {2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|x64.Build.0 = Release|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|Win32.ActiveCfg = Debug|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|Win32.Build.0 = Debug|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|x64.ActiveCfg = Debug|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|x64.Build.0 = Debug|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|Win32.Build.0 = DebugVLD|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|x64.ActiveCfg = DebugVLD|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|x64.Build.0 = DebugVLD|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|Win32.ActiveCfg = Release|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|Win32.Build.0 = Release|Win32 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|x64.ActiveCfg = Release|x64 + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -555,7 +549,6 @@ Global GlobalSection(NestedProjects) = preSolution {61179F2F-07E1-490D-B64D-D85A90B6EF81} = {B30CA283-1796-4763-92C3-2E4848D443F7} {77350FDC-9E51-438B-9A8F-D2FEA11D46B2} = {B30CA283-1796-4763-92C3-2E4848D443F7} - {C5E76975-B87B-4B9E-8596-B01DDA683FCA} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75} {6BB7A27F-FC59-4267-B6FA-D034176D1459} = {B30CA283-1796-4763-92C3-2E4848D443F7} {A64449B7-90FB-4E2B-A686-9EFC0E298644} = {B30CA283-1796-4763-92C3-2E4848D443F7} {3C598F96-FB84-4D42-9B43-F697F53B0221} = {6BB7A27F-FC59-4267-B6FA-D034176D1459} @@ -581,6 +574,7 @@ Global {42B7E892-DDDA-4D00-9AB7-378E0E7E9433} = {810490B7-31E5-49AE-8455-CAF99A9658B6} {00FD5CB8-E1A4-40CA-B613-30A06A75622B} = {810490B7-31E5-49AE-8455-CAF99A9658B6} {2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB} = {810490B7-31E5-49AE-8455-CAF99A9658B6} + {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06} = {810490B7-31E5-49AE-8455-CAF99A9658B6} EndGlobalSection GlobalSection(DPCodeReviewSolutionGUID) = preSolution DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000} diff --git a/projects/Win/vc14/gtest-misc.vcxproj b/projects/Win/vc14/gtest-misc.vcxproj new file mode 100644 index 00000000..7857f8c5 --- /dev/null +++ b/projects/Win/vc14/gtest-misc.vcxproj @@ -0,0 +1,246 @@ + + + + + DebugVLD + Win32 + + + DebugVLD + x64 + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + + + + + + + + + + + + + + {FA22E700-1AE5-4d7b-B9F1-0A919FF7FF06} + Win32Proj + misc + 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) + + + 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) + + + 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) + + + 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) + + + 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) + + + 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) + + + 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-misc.vcxproj.filters b/projects/Win/vc14/gtest-misc.vcxproj.filters new file mode 100644 index 00000000..37266bf6 --- /dev/null +++ b/projects/Win/vc14/gtest-misc.vcxproj.filters @@ -0,0 +1,48 @@ + + + + + {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 + + + {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 + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Header Files + + + \ No newline at end of file diff --git a/projects/Win/vc14/hdr-test-misc.vcxproj b/projects/Win/vc14/hdr-test-misc.vcxproj deleted file mode 100644 index ad290087..00000000 --- a/projects/Win/vc14/hdr-test-misc.vcxproj +++ /dev/null @@ -1,351 +0,0 @@ - - - - - DebugVLD - Win32 - - - DebugVLD - x64 - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {C5E76975-B87B-4B9E-8596-B01DDA683FCA} - hdrtestmisc - Win32Proj - 8.1 - - - - Application - MultiByte - v140 - - - Application - MultiByte - true - v140 - - - Application - MultiByte - v140 - - - Application - MultiByte - v140 - - - Application - MultiByte - true - v140 - - - Application - MultiByte - v140 - - - - - - - - - - - - - - - - - - - - - - - - - <_ProjectFileVersion>10.0.40219.1 - $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ - $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ - $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ - 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)\ - false - $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ - $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ - false - $(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\ - $(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\ - false - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - AllRules.ruleset - - - $(ProjectName)_d - $(ProjectName)_d - $(ProjectName)_d - $(ProjectName)_d - - - - /bigobj /Zc:inline %(AdditionalOptions) - Disabled - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - Cdecl - 4520 - - - unit-prerequisites_d.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX86 - MultiplyDefinedSymbolOnly - - - - - X64 - - - /bigobj /Zc:inline %(AdditionalOptions) - Disabled - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - ProgramDatabase - Cdecl - 4520 - - - unit-prerequisites_d.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX64 - MultiplyDefinedSymbolOnly - - - - - /bigobj /Zc:inline %(AdditionalOptions) - Full - AnySuitable - true - Speed - false - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - MultiThreadedDLL - StreamingSIMDExtensions2 - - - Level3 - ProgramDatabase - Cdecl - false - 4520 - - - unit-prerequisites.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - true - true - false - - - MachineX86 - true - MultiplyDefinedSymbolOnly - - - - - X64 - - - /bigobj /Zc:inline %(AdditionalOptions) - Full - AnySuitable - true - Speed - false - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - MultiThreadedDLL - - - Level3 - ProgramDatabase - Cdecl - false - 4520 - - - unit-prerequisites.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - true - true - UseLinkTimeCodeGeneration - false - - - MachineX64 - true - MultiplyDefinedSymbolOnly - - - - - /bigobj /Zc:inline %(AdditionalOptions) - Disabled - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - EditAndContinue - Cdecl - 4520 - - - unit-prerequisites_d.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX86 - MultiplyDefinedSymbolOnly - - - - - X64 - - - /bigobj /Zc:inline %(AdditionalOptions) - Disabled - $(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories) - CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions) - true - EnableFastChecks - MultiThreadedDebugDLL - - - Level3 - ProgramDatabase - Cdecl - 4520 - - - unit-prerequisites_d.lib;%(AdditionalDependencies) - $(TargetPath) - $(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories) - true - Console - false - - - MachineX64 - MultiplyDefinedSymbolOnly - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/projects/source.test-hdr.mk b/projects/source.test-hdr.mk deleted file mode 100644 index 3f84e584..00000000 --- a/projects/source.test-hdr.mk +++ /dev/null @@ -1,15 +0,0 @@ -CDS_TESTHDR_MISC := \ - tests/test-hdr/misc/cxx11_atomic_class.cpp \ - tests/test-hdr/misc/cxx11_atomic_func.cpp \ - tests/test-hdr/misc/find_option.cpp \ - tests/test-hdr/misc/allocator_test.cpp \ - tests/test-hdr/misc/michael_allocator.cpp \ - tests/test-hdr/misc/hash_tuple.cpp \ - tests/test-hdr/misc/bitop_st.cpp \ - tests/test-hdr/misc/split_bitstring.cpp \ - tests/test-hdr/misc/permutation_generator.cpp \ - tests/test-hdr/misc/thread_init_fini.cpp - -CDS_TESTHDR_SOURCES := \ - $(CDS_TESTHDR_MISC) - diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index f8e78648..46432de6 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -1,6 +1,7 @@ add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/deque) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/list) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/map) +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/misc) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pqueue) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/queue) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/intrusive-set) @@ -15,6 +16,7 @@ add_custom_target(unit-all unit-deque unit-list unit-map + unit-misc unit-pqueue unit-queue unit-intrusive-set diff --git a/test/unit/misc/CMakeLists.txt b/test/unit/misc/CMakeLists.txt new file mode 100644 index 00000000..e533d2a4 --- /dev/null +++ b/test/unit/misc/CMakeLists.txt @@ -0,0 +1,27 @@ +set(PACKAGE_NAME unit-misc) + +set(CDSGTEST_MISC_SOURCES + ../main.cpp + bitop.cpp + cxx11_atomic_class.cpp + cxx11_atomic_func.cpp + find_option.cpp + hash_tuple.cpp + permutation_generator.cpp + split_bitstring.cpp +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(${PACKAGE_NAME} ${CDSGTEST_MISC_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/misc/bitop.cpp b/test/unit/misc/bitop.cpp new file mode 100644 index 00000000..97a75897 --- /dev/null +++ b/test/unit/misc/bitop.cpp @@ -0,0 +1,137 @@ +/* + 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 +#include + +namespace { + class bitop : public ::testing::Test + {}; + + TEST_F( bitop, bitop32 ) + { + uint32_t n = 0; + + EXPECT_EQ( cds::bitop::MSB(n), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSB( n ), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::SBC( n ), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::ZBC( n ), sizeof( n ) * 8 ) << "n=" << n; + + int nBit = 1; + for ( n = 1; n != 0; n *= 2 ) { + EXPECT_EQ( cds::bitop::MSB( n ), nBit ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSB( n ), nBit ) << "n=" << n; + EXPECT_EQ( cds::bitop::MSBnz( n ), nBit - 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSBnz( n ), nBit - 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::SBC( n ), 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::ZBC( n ), sizeof( n ) * 8 - 1 ) << "n=" << n; + + ++nBit; + } + } + + TEST_F( bitop, bitop64 ) + { + uint64_t n = 0; + + EXPECT_EQ( cds::bitop::MSB( n ), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSB( n ), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::SBC( n ), 0 ) << "n=" << n; + EXPECT_EQ( cds::bitop::ZBC( n ), sizeof( n ) * 8 ) << "n=" << n; + + int nBit = 1; + for ( n = 1; n != 0; n *= 2 ) { + EXPECT_EQ( cds::bitop::MSB( n ), nBit ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSB( n ), nBit ) << "n=" << n; + EXPECT_EQ( cds::bitop::MSBnz( n ), nBit - 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::LSBnz( n ), nBit - 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::SBC( n ), 1 ) << "n=" << n; + EXPECT_EQ( cds::bitop::ZBC( n ), sizeof( n ) * 8 - 1 ) << "n=" << n; + + ++nBit; + } + } + + TEST_F( bitop, floor_pow2 ) + { + EXPECT_EQ( cds::beans::floor2( 0 ), 1 ); + EXPECT_EQ( cds::beans::floor2( 1 ), 1 ); + EXPECT_EQ( cds::beans::floor2( 2 ), 2 ); + EXPECT_EQ( cds::beans::floor2( 3 ), 2 ); + EXPECT_EQ( cds::beans::floor2( 4 ), 4 ); + EXPECT_EQ( cds::beans::floor2( 5 ), 4 ); + EXPECT_EQ( cds::beans::floor2( 7 ), 4 ); + EXPECT_EQ( cds::beans::floor2( 8 ), 8 ); + EXPECT_EQ( cds::beans::floor2( 9 ), 8 ); + + for ( uint32_t n = 2; n; n <<= 1 ) + { + EXPECT_EQ( cds::beans::floor2( n - 1 ), n / 2 ); + EXPECT_EQ( cds::beans::floor2( n + 1 ), n ); + } + + for ( uint64_t n = 2; n; n <<= 1 ) + { + EXPECT_EQ( cds::beans::floor2( n - 1 ), n / 2 ); + EXPECT_EQ( cds::beans::floor2( n ), n ); + EXPECT_EQ( cds::beans::floor2( n + 1 ), n ); + } + } + + TEST_F( bitop, ceil_pow2 ) + { + EXPECT_EQ( cds::beans::ceil2( 0 ), 1 ); + EXPECT_EQ( cds::beans::ceil2( 1 ), 1 ); + EXPECT_EQ( cds::beans::ceil2( 2 ), 2 ); + EXPECT_EQ( cds::beans::ceil2( 3 ), 4 ); + EXPECT_EQ( cds::beans::ceil2( 4 ), 4 ); + EXPECT_EQ( cds::beans::ceil2( 5 ), 8 ); + EXPECT_EQ( cds::beans::ceil2( 7 ), 8 ); + EXPECT_EQ( cds::beans::ceil2( 8 ), 8 ); + EXPECT_EQ( cds::beans::ceil2( 9 ), 16 ); + + for ( uint32_t n = 4; n < (uint32_t(1) << 31); n <<= 1 ) + { + EXPECT_EQ( cds::beans::ceil2( n - 1 ), n ); + EXPECT_EQ( cds::beans::ceil2( n ), n ); + EXPECT_EQ( cds::beans::ceil2( n + 1 ), n * 2 ); + } + + for ( uint64_t n = 4; n < (uint64_t(1) << 63); n <<= 1 ) + { + EXPECT_EQ( cds::beans::ceil2( n - 1 ), n ); + EXPECT_EQ( cds::beans::ceil2( n ), n ); + EXPECT_EQ( cds::beans::ceil2( n + 1 ), n * 2 ); + } + } + +} // namespace diff --git a/test/unit/misc/cxx11_atomic_class.cpp b/test/unit/misc/cxx11_atomic_class.cpp new file mode 100644 index 00000000..4f3c13e0 --- /dev/null +++ b/test/unit/misc/cxx11_atomic_class.cpp @@ -0,0 +1,850 @@ +/* + 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 +#include "cxx11_convert_memory_order.h" + +namespace { + class cxx11_atomic_class: public ::testing::Test + { + protected: + template + void do_test_atomic_flag_mo( AtomicFlag& f, atomics::memory_order order ) + { + atomics::memory_order mo_clear = convert_to_store_order(order); + for ( int i = 0; i < 5; ++i ) { + EXPECT_TRUE( !f.test_and_set( order )); + EXPECT_TRUE( f.test_and_set( order ) ); + f.clear( mo_clear ); + } + } + + template + void do_test_atomic_flag( AtomicFlag& f) + { + f.clear(); + + for ( int i = 0; i < 5; ++i ) { + EXPECT_TRUE( !f.test_and_set()); + EXPECT_TRUE( f.test_and_set() ); + f.clear(); + } + + do_test_atomic_flag_mo( f, atomics::memory_order_relaxed ); + //do_test_atomic_flag_mo( f, atomics::memory_order_consume ); + do_test_atomic_flag_mo( f, atomics::memory_order_acquire ); + do_test_atomic_flag_mo( f, atomics::memory_order_release ); + do_test_atomic_flag_mo( f, atomics::memory_order_acq_rel ); + do_test_atomic_flag_mo( f, atomics::memory_order_seq_cst ); + } + + template + void do_test_atomic_type(Atomic& a) + { + typedef Integral integral_type; + + EXPECT_TRUE( a.is_lock_free() ); + a.store( (integral_type) 0 ); + EXPECT_EQ( a, 0 ); + EXPECT_EQ( a.load(), 0 ); + + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + EXPECT_EQ( a.exchange( n ), 0 ); + EXPECT_EQ( a, n ); + EXPECT_EQ( a.exchange( (integral_type) 0 ), n ); + EXPECT_EQ( a.load(), 0 ); + } + + integral_type prev = a.load(); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( a.compare_exchange_weak( expected, n)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( a.compare_exchange_weak( expected, n)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( a, n ); + } + + a = (integral_type) 0; + + prev = a; + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( a.compare_exchange_strong( expected, n)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( a.compare_exchange_strong( expected, n)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( a.load(), n ); + } + + EXPECT_EQ( a.exchange( (integral_type) 0 ), prev ); + } + + template + void do_test_atomic_integral(Atomic& a) + { + do_test_atomic_type< Atomic, Integral >(a); + + typedef Integral integral_type; + + // fetch_xxx testing + a.store( (integral_type) 0 ); + + // fetch_add + for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) + { + integral_type prev = a.load(); + integral_type n = integral_type(42) << (nByte * 8); + + EXPECT_EQ( a.fetch_add(n), prev); + } + + // fetch_sub + for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) + { + integral_type prev = a.load(); + integral_type n = integral_type(42) << ((nByte - 1) * 8); + + EXPECT_EQ( a.fetch_sub(n), prev); + } + EXPECT_EQ( a.load(), 0 ); + + // fetch_or / fetc_xor / fetch_and + for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) + { + integral_type prev = a.load() ;; + integral_type mask = integral_type(1) << nBit; + + EXPECT_EQ( a.fetch_or( mask ), prev ); + prev = a.load(); + EXPECT_EQ( ( prev & mask), mask); + + EXPECT_EQ( a.fetch_and( (integral_type) ~mask ), prev ); + prev = a.load(); + EXPECT_EQ( integral_type(prev & mask), integral_type(0)); + + EXPECT_EQ( a.fetch_xor( mask ), prev ); + prev = a.load(); + EXPECT_EQ( integral_type( prev & mask), mask); + } + EXPECT_EQ( a.load(), (integral_type) -1 ); + + + // op= testing + a = (integral_type) 0; + + // += + for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) + { + integral_type prev = a; + integral_type n = integral_type(42) << (nByte * 8); + + EXPECT_EQ( (a += n), (prev + n)); + } + + // -= + for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) + { + integral_type prev = a; + integral_type n = integral_type(42) << ((nByte - 1) * 8); + + EXPECT_EQ( (a -= n), prev - n ); + } + EXPECT_EQ( a.load(), 0 ); + + // |= / ^= / &= + for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) + { + integral_type prev = a; + integral_type mask = integral_type(1) << nBit; + + EXPECT_EQ( (a |= mask ), (prev | mask )); + prev = a; + EXPECT_EQ( ( prev & mask), mask); + + EXPECT_EQ( (a &= (integral_type) ~mask ), ( prev & (integral_type) ~mask )); + prev = a; + EXPECT_EQ( ( prev & mask), 0); + + EXPECT_EQ( (a ^= mask ), (prev ^ mask )); + prev = a; + EXPECT_EQ( ( prev & mask), mask); + } + EXPECT_EQ( a, (integral_type) -1 ); + } + + template + void do_test_atomic_type( Atomic& a, atomics::memory_order order ) + { + typedef Integral integral_type; + + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + + EXPECT_TRUE( a.is_lock_free() ); + a.store((integral_type) 0, oStore ); + EXPECT_EQ( a, 0 ); + EXPECT_EQ( a.load( oLoad ), 0 ); + + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + EXPECT_EQ( a.exchange( n, order ), 0 ); + EXPECT_EQ( a.load( oLoad ), n ); + EXPECT_EQ( a.exchange( (integral_type) 0, order ), n ); + EXPECT_EQ( a.load( oLoad ), 0 ); + } + + integral_type prev = a.load( oLoad ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( a.compare_exchange_weak( expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( a.compare_exchange_weak( expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( a.load( oLoad ), n ); + } + + a.store( (integral_type) 0, oStore ); + + prev = a.load( oLoad ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( a.compare_exchange_strong( expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( a.compare_exchange_strong( expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( a.load( oLoad ), n ); + } + + EXPECT_EQ( a.exchange( (integral_type) 0, order ), prev ); + } + + template + void do_test_atomic_integral( Atomic& a, atomics::memory_order order ) + { + do_test_atomic_type< Atomic, Integral >( a, order ); + + typedef Integral integral_type; + + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + + // fetch_xxx testing + a.store( (integral_type) 0, oStore ); + + // fetch_add + for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) + { + integral_type prev = a.load( oLoad ); + integral_type n = integral_type(42) << (nByte * 8); + + EXPECT_EQ( a.fetch_add( n, order), prev); + } + + // fetch_sub + for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) + { + integral_type prev = a.load( oLoad ); + integral_type n = integral_type(42) << ((nByte - 1) * 8); + + EXPECT_EQ( a.fetch_sub( n, order ), prev); + } + EXPECT_EQ( a.load( oLoad ), 0 ); + + // fetch_or / fetc_xor / fetch_and + for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) + { + integral_type prev = a.load( oLoad ) ;; + integral_type mask = integral_type(1) << nBit; + + EXPECT_EQ( a.fetch_or( mask, order ), prev ); + prev = a.load( oLoad ); + EXPECT_EQ( ( prev & mask), mask); + + EXPECT_EQ( a.fetch_and( (integral_type) ~mask, order ), prev ); + prev = a.load( oLoad ); + EXPECT_EQ( ( prev & mask), 0); + + EXPECT_EQ( a.fetch_xor( mask, order ), prev ); + prev = a.load( oLoad ); + EXPECT_EQ( ( prev & mask), mask); + } + EXPECT_EQ( a.load( oLoad ), (integral_type) -1 ); + } + + + + template + void test_atomic_integral_(Atomic& a) + { + do_test_atomic_integral(a); + + do_test_atomic_integral( a, atomics::memory_order_relaxed ); + do_test_atomic_integral( a, atomics::memory_order_acquire ); + do_test_atomic_integral( a, atomics::memory_order_release ); + do_test_atomic_integral( a, atomics::memory_order_acq_rel ); + do_test_atomic_integral( a, atomics::memory_order_seq_cst ); + } + + template + void test_atomic_integral() + { + typedef atomics::atomic atomic_type; + + atomic_type a[8]; + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + test_atomic_integral_( a[i] ); + } + } + template + void test_atomic_integral_volatile() + { + typedef atomics::atomic volatile atomic_type; + + atomic_type a[8]; + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + test_atomic_integral_( a[i] ); + } + } + + template + void do_test_atomic_bool( AtomicBool& a ) + { + EXPECT_TRUE( a.is_lock_free() ); + a.store( false ); + EXPECT_FALSE( a ); + EXPECT_FALSE( a.load()); + + EXPECT_FALSE( a.exchange( true )); + EXPECT_TRUE( a.load()); + EXPECT_TRUE( a.exchange( false )); + EXPECT_FALSE( a.load()); + + bool expected = false; + EXPECT_TRUE( a.compare_exchange_weak( expected, true)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( a.compare_exchange_weak( expected, false)); + EXPECT_TRUE( expected ); + EXPECT_TRUE( a.load() ); + + a.store( false ); + + expected = false; + EXPECT_TRUE( a.compare_exchange_strong( expected, true)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( a.compare_exchange_strong( expected, false)); + EXPECT_TRUE( expected ); + + EXPECT_TRUE( a.load()); + + EXPECT_TRUE( a.exchange( false )); + } + + template + void do_test_atomic_bool( AtomicBool& a, atomics::memory_order order ) + { + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + const atomics::memory_order oExchange = convert_to_exchange_order( order ); + + EXPECT_TRUE( a.is_lock_free() ); + a.store( false, oStore ); + EXPECT_FALSE( a ); + EXPECT_FALSE( a.load( oLoad )); + + EXPECT_FALSE( a.exchange( true, oExchange )); + EXPECT_TRUE( a.load( oLoad )); + EXPECT_TRUE( a.exchange( false, oExchange )); + EXPECT_FALSE( a.load( oLoad )); + + bool expected = false; + EXPECT_TRUE( a.compare_exchange_weak( expected, true, order, atomics::memory_order_relaxed)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( a.compare_exchange_weak( expected, false, order, atomics::memory_order_relaxed)); + EXPECT_TRUE( expected ); + EXPECT_TRUE( a.load( oLoad )); + + //a = bool(false); + a.store( false, oStore ); + + expected = false; + EXPECT_TRUE( a.compare_exchange_strong( expected, true, order, atomics::memory_order_relaxed)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( a.compare_exchange_strong( expected, false, order, atomics::memory_order_relaxed)); + EXPECT_TRUE( expected ); + + EXPECT_TRUE( a.load( oLoad )); + + EXPECT_TRUE( a.exchange( false, oExchange )); + } + + + template + void do_test_atomic_pointer_void_( Atomic& a, char * arr, char aSize, atomics::memory_order order ) + { + atomics::memory_order oLoad = convert_to_load_order(order); + atomics::memory_order oStore = convert_to_store_order(order); + void * p; + + a.store( (void *) arr, oStore ); + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), 1 ); + + p = arr; + EXPECT_TRUE( a.compare_exchange_weak( p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_EQ( *reinterpret_cast(p), 1 ); + EXPECT_FALSE( a.compare_exchange_weak( p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *reinterpret_cast(p), 6 ); + + EXPECT_TRUE( a.compare_exchange_strong( p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *reinterpret_cast(p), 6 ); + EXPECT_FALSE( a.compare_exchange_strong( p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 3 ); + EXPECT_EQ( *reinterpret_cast(p), 4 ); + + EXPECT_EQ( reinterpret_cast(a.exchange( (void *) arr, order )), arr + 3 ); + EXPECT_EQ( reinterpret_cast(a.load( oLoad )), arr ); + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), 1 ); + + for ( char i = 1; i < aSize; ++i ) { + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), i ); + a.fetch_add( 1, order ); + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), i + 1 ); + } + + for ( char i = aSize; i > 1; --i ) { + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), i ); + a.fetch_sub( 1, order ); + EXPECT_EQ( *reinterpret_cast(a.load( oLoad )), i - 1 ); + } + } + + template + void do_test_atomic_pointer_void() + { + typedef typename add_volatile, Volatile>::type atomic_pointer; + + char arr[8]; + const char aSize = sizeof(arr)/sizeof(arr[0]); + for ( char i = 0; i < aSize; ++i ) { + arr[unsigned(i)] = i + 1; + } + + atomic_pointer a; + void * p; + + a.store( (void *) arr ); + EXPECT_EQ( *reinterpret_cast(a.load()), 1 ); + + p = arr; + EXPECT_TRUE( a.compare_exchange_weak( p, (void *)(arr + 5) )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_FALSE( a.compare_exchange_weak( p, (void *)(arr + 3) )); + EXPECT_EQ( p, arr + 5 ); + + EXPECT_TRUE( a.compare_exchange_strong( p, (void *)(arr + 3) )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_FALSE( a.compare_exchange_strong( p, (void *)(arr + 5) )); + EXPECT_EQ( p, arr + 3 ); + + EXPECT_EQ( reinterpret_cast( a.exchange( (void *) arr )), arr + 3 ); + EXPECT_EQ( reinterpret_cast( a.load()), arr ); + EXPECT_EQ( *reinterpret_cast( a.load()), 1 ); + + for ( char i = 1; i < aSize; ++i ) { + EXPECT_EQ( *reinterpret_cast(a.load()), i ); + a.fetch_add( 1 ); + EXPECT_EQ( *reinterpret_cast(a.load()), i + 1 ); + } + + for ( char i = aSize; i > 1; --i ) { + EXPECT_EQ( *reinterpret_cast(a.load()), i ); + a.fetch_sub( 1 ); + EXPECT_EQ( *reinterpret_cast(a.load()), i - 1 ); + } + + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_relaxed ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acquire ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_release ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acq_rel ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_seq_cst ); + } + + template + void test_atomic_pointer_for_( Atomic& a, Integral * arr, Integral aSize, atomics::memory_order order ) + { + typedef Integral integral_type; + atomics::memory_order oLoad = convert_to_load_order(order); + atomics::memory_order oStore = convert_to_store_order(order); + integral_type * p; + + a.store( arr, oStore ); + EXPECT_EQ( *a.load( oLoad ), 1 ); + + p = arr; + EXPECT_TRUE( a.compare_exchange_weak( p, arr + 5, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_EQ( *p, 1 ); + EXPECT_FALSE( a.compare_exchange_weak( p, arr + 3, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + + EXPECT_TRUE( a.compare_exchange_strong( p, arr + 3, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + EXPECT_FALSE( a.compare_exchange_strong( p, arr + 5, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 3 ); + EXPECT_EQ( *p, 4 ); + + EXPECT_EQ( a.exchange( arr, order ), arr + 3 ); + EXPECT_EQ( a.load( oLoad ), arr ); + EXPECT_EQ( *a.load( oLoad ), 1 ); + + for ( integral_type i = 1; i < aSize; ++i ) { + integral_type * p = a.load(); + EXPECT_EQ( *p, i ); + EXPECT_EQ( a.fetch_add( 1, order ), p ); + EXPECT_EQ( *a.load( oLoad ), i + 1 ); + } + + for ( integral_type i = aSize; i > 1; --i ) { + integral_type * p = a.load(); + EXPECT_EQ( *p, i ); + EXPECT_EQ( a.fetch_sub( 1, order ), p ); + EXPECT_EQ( *a.load( oLoad ), i - 1 ); + } + } + + template + void test_atomic_pointer_for() + { + typedef Integral integral_type; + typedef typename add_volatile, Volatile>::type atomic_pointer; + + integral_type arr[8]; + const integral_type aSize = sizeof(arr)/sizeof(arr[0]); + for ( integral_type i = 0; i < aSize; ++i ) { + arr[size_t(i)] = i + 1; + } + + atomic_pointer a; + integral_type * p; + + a.store( arr ); + EXPECT_EQ( *a.load(), 1 ); + + p = arr; + EXPECT_TRUE( a.compare_exchange_weak( p, arr + 5 )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_EQ( *p, 1 ); + EXPECT_FALSE( a.compare_exchange_weak( p, arr + 3 )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + + EXPECT_TRUE( a.compare_exchange_strong( p, arr + 3 )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + EXPECT_FALSE( a.compare_exchange_strong( p, arr + 5 )); + EXPECT_EQ( p, arr + 3 ); + EXPECT_EQ( *p, 4 ); + + EXPECT_EQ( a.exchange( arr ), arr + 3 ); + EXPECT_EQ( a.load(), arr ); + EXPECT_EQ( *a.load(), 1 ); + + for ( integral_type i = 1; i < aSize; ++i ) { + integral_type * p = a.load(); + EXPECT_EQ( *p, i ); + integral_type * pa = a.fetch_add( 1 ); + EXPECT_EQ( pa, p ); + EXPECT_EQ( *a.load(), i + 1 ); + } + + for ( integral_type i = aSize; i > 1; --i ) { + integral_type * p = a.load(); + EXPECT_EQ( *p, i ); + EXPECT_EQ( a.fetch_sub( 1 ), p ); + EXPECT_EQ( *a.load(), i - 1 ); + } + + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_relaxed ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acquire ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_release ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acq_rel ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_seq_cst ); + } + + public: + void test_atomic_flag() + { + // Array to test different alignment + + atomics::atomic_flag flags[8]; + for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) + do_test_atomic_flag( flags[i] ); + } + + void test_atomic_flag_volatile() + { + // Array to test different alignment + + atomics::atomic_flag volatile flags[8]; + for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) + do_test_atomic_flag( flags[i] ); + } + + template + void test_atomic_bool_() + { + // Array to test different alignment + AtomicBool a[8]; + + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + do_test_atomic_bool( a[i] ); + + do_test_atomic_bool( a[i], atomics::memory_order_relaxed ); + //do_test_atomic_bool( a[i], atomics::memory_order_consume ); + do_test_atomic_bool( a[i], atomics::memory_order_acquire ); + do_test_atomic_bool( a[i], atomics::memory_order_release ); + do_test_atomic_bool( a[i], atomics::memory_order_acq_rel ); + do_test_atomic_bool( a[i], atomics::memory_order_seq_cst ); + } + } + + void test_atomic_bool() + { + test_atomic_bool_< atomics::atomic >(); + } + void test_atomic_bool_volatile() + { + test_atomic_bool_< atomics::atomic volatile >(); + } + }; + + TEST_F( cxx11_atomic_class, atomic_char ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_signed_char ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_char ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_short_int ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_signed_short_int ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_short_int ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_int ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_int ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_long ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_long ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_long_long ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_long_long ) + { + test_atomic_integral(); + } + + TEST_F( cxx11_atomic_class, atomic_char_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_signed_char_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_char_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_short_int_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_signed_short_int_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_short_int_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_int_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_int_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_long_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_long_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_long_long_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_unsigned_long_long_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_void ) + { + do_test_atomic_pointer_void(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_void_volatile ) + { + do_test_atomic_pointer_void(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_char ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_char_volatile ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_short ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_short_volatile ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_int ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_int_volatile ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_long ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_long_volatile ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_long_long ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_class, atomic_pointer_long_long_volatile ) + { + test_atomic_pointer_for(); + } +} // namespace diff --git a/test/unit/misc/cxx11_atomic_func.cpp b/test/unit/misc/cxx11_atomic_func.cpp new file mode 100644 index 00000000..e56b8ec7 --- /dev/null +++ b/test/unit/misc/cxx11_atomic_func.cpp @@ -0,0 +1,776 @@ +/* + 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 + +#ifndef CDS_USE_BOOST_ATOMIC +// Skip this test for boost.atomic +// Boost.atomic has no free atomic functions implementation. + +#include "cxx11_convert_memory_order.h" + +namespace misc { + + class cxx11_atomic_func: public ::testing::Test + { + protected: + template + void do_test_atomic_flag_mo( AtomicFlag& f, atomics::memory_order order ) + { + atomics::memory_order mo_clear = convert_to_store_order(order); + + f.clear( convert_to_store_order(order) ); + + for ( int i = 0; i < 5; ++i ) { + EXPECT_FALSE( atomics::atomic_flag_test_and_set_explicit( &f, order )); + EXPECT_TRUE( atomics::atomic_flag_test_and_set_explicit( &f, order ) ); + atomics::atomic_flag_clear_explicit( &f, mo_clear ); + atomics::atomic_flag_clear_explicit( &f, mo_clear ); + } + } + + template + void do_test_atomic_flag( AtomicFlag& f ) + { + f.clear(); + + for ( int i = 0; i < 5; ++i ) { + EXPECT_FALSE( atomics::atomic_flag_test_and_set( &f )); + EXPECT_TRUE( atomics::atomic_flag_test_and_set( &f ) ); + atomics::atomic_flag_clear(&f); + atomics::atomic_flag_clear(&f); + } + + do_test_atomic_flag_mo( f, atomics::memory_order_relaxed ); + do_test_atomic_flag_mo( f, atomics::memory_order_acquire ); + do_test_atomic_flag_mo( f, atomics::memory_order_release ); + do_test_atomic_flag_mo( f, atomics::memory_order_acq_rel ); + do_test_atomic_flag_mo( f, atomics::memory_order_seq_cst ); + } + + template + void do_test_atomic_type(Atomic& a ) + { + typedef Integral integral_type; + + EXPECT_TRUE( atomics::atomic_is_lock_free( &a ) ); + atomics::atomic_store( &a, (integral_type) 0 ); + EXPECT_EQ( a, 0 ); + EXPECT_EQ( atomics::atomic_load( &a ), 0 ); + + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + EXPECT_EQ( atomics::atomic_exchange( &a, n ), 0 ); + EXPECT_EQ( atomics::atomic_load( &a ), n ); + EXPECT_EQ( atomics::atomic_exchange( &a, (integral_type) 0 ), n ); + EXPECT_EQ( atomics::atomic_load( &a ), 0 ); + } + + integral_type prev = atomics::atomic_load( &a ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( atomics::atomic_compare_exchange_weak( &a, &expected, n)); + EXPECT_EQ( expected, prev ); + EXPECT_NE( expected, n ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak( &a, &expected, n) ); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( atomics::atomic_load( &a ), n ); + } + + atomics::atomic_store( &a, (integral_type) 0 ); + + prev = atomics::atomic_load( &a ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong( &a, &expected, n)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong( &a, &expected, n)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( atomics::atomic_load( &a ), n ); + } + + EXPECT_EQ( atomics::atomic_exchange( &a, (integral_type) 0 ), prev ); + } + + template + void do_test_atomic_integral( Atomic& a ) + { + do_test_atomic_type< Atomic, Integral >( a ); + + typedef Integral integral_type; + + // fetch_xxx testing + atomics::atomic_store( &a, (integral_type) 0 ); + + // fetch_add + for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) + { + integral_type prev = atomics::atomic_load( &a ); + integral_type n = integral_type(42) << (nByte * 8); + + EXPECT_EQ( atomics::atomic_fetch_add( &a, n ), prev ); + } + + // fetch_sub + for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) + { + integral_type prev = atomics::atomic_load( &a ); + integral_type n = integral_type(42) << ((nByte - 1) * 8); + + EXPECT_EQ( atomics::atomic_fetch_sub( &a, n ), prev ); + } + EXPECT_EQ( atomics::atomic_load( &a ), 0 ); + + // fetch_or / fetc_xor / fetch_and + for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) + { + integral_type prev = atomics::atomic_load( &a ); + integral_type mask = integral_type(1) << nBit; + + EXPECT_EQ( atomics::atomic_fetch_or( &a, mask ), prev ); + prev = atomics::atomic_load( &a ); + EXPECT_EQ( ( prev & mask ), mask ); + + EXPECT_EQ( atomics::atomic_fetch_and( &a, (integral_type) ~mask ), prev ); + prev = atomics::atomic_load( &a ); + EXPECT_EQ( integral_type(prev & mask), integral_type(0)); + + EXPECT_EQ( atomics::atomic_fetch_xor( &a, mask ), prev ); + prev = atomics::atomic_load( &a ); + EXPECT_EQ( ( prev & mask), mask); + } + EXPECT_EQ( atomics::atomic_load( &a ), (integral_type) -1 ); + } + + template + void do_test_atomic_type( Atomic& a, atomics::memory_order order ) + { + typedef Integral integral_type; + + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + + EXPECT_TRUE( atomics::atomic_is_lock_free( &a ) ); + atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); + EXPECT_EQ( a, 0 ); + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), 0 ); + + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + EXPECT_EQ( atomics::atomic_exchange_explicit( &a, n, order ), 0 ); + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), n ); + EXPECT_EQ( atomics::atomic_exchange_explicit( &a, (integral_type) 0, order ), n ); + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), 0 ); + } + + integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), n ); + } + + atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); + + prev = atomics::atomic_load_explicit( &a, oLoad ); + for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { + integral_type n = integral_type(42) << (nByte * 8); + integral_type expected = prev; + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, prev ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); + EXPECT_EQ( expected, n ); + + prev = n; + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), n ); + } + + EXPECT_EQ( atomics::atomic_exchange_explicit( &a, (integral_type) 0, order ), prev ); + } + + template + void do_test_atomic_integral( Atomic& a, atomics::memory_order order ) + { + do_test_atomic_type< Atomic, Integral >( a, order ); + typedef Integral integral_type; + + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + + // fetch_xxx testing + atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); + + // fetch_add + for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) + { + integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); + integral_type n = integral_type(42) << (nByte * 8); + + EXPECT_EQ( atomics::atomic_fetch_add_explicit( &a, n, order), prev); + } + + // fetch_sub + for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) + { + integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); + integral_type n = integral_type(42) << ((nByte - 1) * 8); + + EXPECT_EQ( atomics::atomic_fetch_sub_explicit( &a, n, order ), prev); + } + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), 0 ); + + // fetch_or / fetc_xor / fetch_and + for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) + { + integral_type prev = atomics::atomic_load_explicit( &a, oLoad ) ;; + integral_type mask = integral_type(1) << nBit; + + EXPECT_EQ( atomics::atomic_fetch_or_explicit( &a, mask, order ), prev ); + prev = atomics::atomic_load_explicit( &a, oLoad ); + EXPECT_EQ( ( prev & mask), mask); + + EXPECT_EQ( atomics::atomic_fetch_and_explicit( &a, (integral_type) ~mask, order ), prev ); + prev = atomics::atomic_load_explicit( &a, oLoad ); + EXPECT_EQ( ( prev & mask), 0); + + EXPECT_EQ( atomics::atomic_fetch_xor_explicit( &a, mask, order ), prev ); + prev = atomics::atomic_load_explicit( &a, oLoad ); + EXPECT_EQ( ( prev & mask), mask); + } + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), (integral_type) -1 ); + } + + template + void test_atomic_integral_(Atomic& a) + { + do_test_atomic_integral(a); + + do_test_atomic_integral( a, atomics::memory_order_relaxed ); + do_test_atomic_integral( a, atomics::memory_order_acquire ); + do_test_atomic_integral( a, atomics::memory_order_release ); + do_test_atomic_integral( a, atomics::memory_order_acq_rel ); + do_test_atomic_integral( a, atomics::memory_order_seq_cst ); + } + + template + void test_atomic_integral() + { + typedef atomics::atomic atomic_type; + atomic_type a[8]; + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + test_atomic_integral_( a[i] ); + } + } + template + void test_atomic_integral_volatile() + { + typedef atomics::atomic volatile atomic_type; + atomic_type a[8]; + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + test_atomic_integral_( a[i] ); + } + } + + template + void do_test_atomic_bool(AtomicBool& a) + { + EXPECT_TRUE( atomics::atomic_is_lock_free( &a ) ); + atomics::atomic_store( &a, false ); + EXPECT_FALSE( a ); + EXPECT_FALSE( atomics::atomic_load( &a )); + + EXPECT_FALSE( atomics::atomic_exchange( &a, true )); + EXPECT_TRUE( atomics::atomic_load( &a )); + EXPECT_TRUE( atomics::atomic_exchange( &a, false )); + EXPECT_FALSE( atomics::atomic_load( &a )); + + bool expected = false; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak( &a, &expected, true)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak( &a, &expected, false)); + EXPECT_TRUE( expected ); + EXPECT_TRUE( atomics::atomic_load( &a )); + + atomics::atomic_store( &a, false ); + + expected = false; + EXPECT_TRUE( atomics::atomic_compare_exchange_strong( &a, &expected, true)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong( &a, &expected, false)); + EXPECT_TRUE( expected ); + + EXPECT_TRUE( atomics::atomic_load( &a )); + + EXPECT_TRUE( atomics::atomic_exchange( &a, false )); + } + + template + void do_test_atomic_bool( AtomicBool& a, atomics::memory_order order ) + { + const atomics::memory_order oLoad = convert_to_load_order( order ); + const atomics::memory_order oStore = convert_to_store_order( order ); + const atomics::memory_order oExchange = convert_to_exchange_order( order ); + + EXPECT_TRUE( atomics::atomic_is_lock_free( &a ) ); + atomics::atomic_store_explicit( &a, false, oStore ); + EXPECT_FALSE( a == false ); + EXPECT_FALSE( atomics::atomic_load_explicit( &a, oLoad )); + + EXPECT_FALSE( atomics::atomic_exchange_explicit( &a, true, oExchange )); + EXPECT_TRUE( atomics::atomic_load_explicit( &a, oLoad )); + EXPECT_TRUE( atomics::atomic_exchange_explicit( &a, false, oExchange )); + EXPECT_FALSE( atomics::atomic_load_explicit( &a, oLoad )); + + bool expected = false; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, true, order, atomics::memory_order_relaxed)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, false, order, atomics::memory_order_relaxed)); + EXPECT_TRUE( expected ); + EXPECT_TRUE( atomics::atomic_load_explicit( &a, oLoad )); + + atomics::atomic_store( &a, false ); + + expected = false; + EXPECT_TRUE( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, true, order, atomics::memory_order_relaxed)); + EXPECT_FALSE( expected ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, false, order, atomics::memory_order_relaxed)); + EXPECT_TRUE( expected ); + + EXPECT_TRUE( atomics::atomic_load_explicit( &a, oLoad )); + + EXPECT_TRUE( atomics::atomic_exchange_explicit( &a, false, oExchange )); + } + + template + void test_atomic_pointer_for_( Atomic& a, Integral * arr, Integral aSize, atomics::memory_order order ) + { + typedef Integral integral_type; + atomics::memory_order oLoad = convert_to_load_order(order); + atomics::memory_order oStore = convert_to_store_order(order); + integral_type * p; + + atomics::atomic_store_explicit( &a, arr, oStore ); + EXPECT_EQ( *atomics::atomic_load_explicit( &a, oLoad ), 1 ); + + p = arr; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak_explicit( &a, &p, arr + 5, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_EQ( *p, 1 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak_explicit( &a, &p, arr + 3, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong_explicit( &a, &p, arr + 3, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong_explicit( &a, &p, arr + 5, order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 3 ); + EXPECT_EQ( *p, 4 ); + + EXPECT_EQ( atomics::atomic_exchange_explicit( &a, arr, order ), arr + 3 ); + EXPECT_EQ( atomics::atomic_load_explicit( &a, oLoad ), arr ); + EXPECT_EQ( *atomics::atomic_load_explicit( &a, oLoad ), 1 ); + + for ( integral_type i = 1; i < aSize; ++i ) { + integral_type * p = atomics::atomic_load_explicit( &a, oLoad ); + EXPECT_EQ( *p, i ); + EXPECT_EQ( atomics::atomic_fetch_add_explicit( &a, 1, order ), p ); + EXPECT_EQ( *atomics::atomic_load_explicit( &a, oLoad ), i + 1 ); + } + + for ( integral_type i = aSize; i > 1; --i ) { + integral_type * p = atomics::atomic_load_explicit( &a, oLoad ); + EXPECT_EQ( *p, i ); + EXPECT_EQ( atomics::atomic_fetch_sub_explicit( &a, 1, order ), p ); + EXPECT_EQ( *atomics::atomic_load_explicit( &a, oLoad ), i - 1 ); + } + } + + template + void test_atomic_pointer_for() + { + typedef Integral integral_type; + typedef typename add_volatile, Volatile>::type atomic_pointer; + + integral_type arr[8]; + const integral_type aSize = sizeof(arr)/sizeof(arr[0]); + for ( integral_type i = 0; i < aSize; ++i ) { + arr[size_t(i)] = i + 1; + } + + atomic_pointer a; + integral_type * p; + + atomics::atomic_store( &a, arr ); + EXPECT_EQ( *atomics::atomic_load( &a ), 1 ); + + p = arr; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak( &a, &p, arr + 5 )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak( &a, &p, arr + 3 )); + EXPECT_EQ( p, arr + 5 ); + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong( &a, &p, arr + 3 )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong( &a, &p, arr + 5 )); + EXPECT_EQ( p, arr + 3 ); + + EXPECT_EQ( atomics::atomic_exchange( &a, arr ), arr + 3 ); + EXPECT_EQ( atomics::atomic_load( &a ), arr ); + EXPECT_EQ( *atomics::atomic_load( &a ), 1 ); + + for ( integral_type i = 1; i < aSize; ++i ) { + integral_type * p = atomics::atomic_load( &a ); + EXPECT_EQ( *p, i ); + EXPECT_EQ( atomics::atomic_fetch_add( &a, 1 ), p ); + EXPECT_EQ( *atomics::atomic_load( &a ), i + 1 ); + } + + for ( integral_type i = aSize; i > 1; --i ) { + integral_type * p = atomics::atomic_load( &a ); + EXPECT_EQ( *p, i ); + EXPECT_EQ( atomics::atomic_fetch_sub( &a, 1 ), p ); + EXPECT_EQ( *atomics::atomic_load( &a ), i - 1 ); + } + + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_relaxed ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acquire ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_release ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acq_rel ); + test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_seq_cst ); + + } + + template + void do_test_atomic_pointer_void_( Atomic& a, char * arr, char aSize, atomics::memory_order order ) + { + atomics::memory_order oLoad = convert_to_load_order(order); + atomics::memory_order oStore = convert_to_store_order(order); + char * p; + + atomics::atomic_store_explicit( &a, (void *) arr, oStore ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), 1 ); + + p = arr; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak_explicit( &a, (void **) &p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_EQ( *p, 1 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak_explicit( &a, (void **) &p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong_explicit( &a, (void **) &p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_EQ( *p, 6 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong_explicit( &a, (void **) &p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); + EXPECT_EQ( p, arr + 3 ); + EXPECT_EQ( *p, 4 ); + + EXPECT_EQ( reinterpret_cast(atomics::atomic_exchange_explicit( &a, (void *) arr, order )), arr + 3 ); + EXPECT_EQ( reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), arr ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), 1 ); + + for ( char i = 1; i < aSize; ++i ) { + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), i ); + atomics::atomic_fetch_add_explicit( &a, 1, order ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), i + 1 ); + } + + for ( char i = aSize; i > 1; --i ) { + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), i ); + atomics::atomic_fetch_sub_explicit( &a, 1, order ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )), i - 1 ); + } + } + + template + void do_test_atomic_pointer_void() + { + typedef typename add_volatile, Volatile>::type atomic_pointer; + + char arr[8]; + const char aSize = sizeof(arr)/sizeof(arr[0]); + for ( char i = 0; i < aSize; ++i ) { + arr[unsigned(i)] = i + 1; + } + + atomic_pointer a; + char * p; + + atomics::atomic_store( &a, (void *) arr ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), 1 ); + + p = arr; + EXPECT_TRUE( atomics::atomic_compare_exchange_weak( &a, (void **) &p, (void *)(arr + 5) )); + EXPECT_EQ( p, arr + 0 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_weak( &a, (void **) &p, (void *)(arr + 3) )); + EXPECT_EQ( p, arr + 5 ); + + EXPECT_TRUE( atomics::atomic_compare_exchange_strong( &a, (void **) &p, (void *)(arr + 3) )); + EXPECT_EQ( p, arr + 5 ); + EXPECT_FALSE( atomics::atomic_compare_exchange_strong( &a, (void **) &p, (void *)(arr + 5) )); + EXPECT_EQ( p, arr + 3 ); + + EXPECT_EQ( reinterpret_cast( atomics::atomic_exchange( &a, (void *) arr )), arr + 3 ); + EXPECT_EQ( reinterpret_cast( atomics::atomic_load( &a )), arr ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), 1 ); + + for ( char i = 1; i < aSize; ++i ) { + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), i ); + atomics::atomic_fetch_add( &a, 1 ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), i + 1 ); + } + + for ( char i = aSize; i > 1; --i ) { + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), i ); + atomics::atomic_fetch_sub( &a, 1 ); + EXPECT_EQ( *reinterpret_cast(atomics::atomic_load( &a )), i - 1 ); + } + + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_relaxed ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acquire ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_release ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acq_rel ); + do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_seq_cst ); + } + + public: + void test_atomic_flag() + { + atomics::atomic_flag flags[8]; + for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) + do_test_atomic_flag( flags[i] ); + } + void test_atomic_flag_volatile() + { + atomics::atomic_flag volatile flags[8]; + for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) + do_test_atomic_flag( flags[i] ); + } + + template + void test_atomic_bool_() + { + AtomicBool a[8]; + for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { + do_test_atomic_bool( a[i] ); + + do_test_atomic_bool( a[i], atomics::memory_order_relaxed ); + do_test_atomic_bool( a[i], atomics::memory_order_acquire ); + do_test_atomic_bool( a[i], atomics::memory_order_release ); + do_test_atomic_bool( a[i], atomics::memory_order_acq_rel ); + do_test_atomic_bool( a[i], atomics::memory_order_seq_cst ); + } + } + + void test_atomic_bool() + { + test_atomic_bool_ >(); + } + void test_atomic_bool_volatile() + { + test_atomic_bool_ volatile >(); + } + }; + + TEST_F( cxx11_atomic_func, atomic_char ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_char_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_char ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_char_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_signed_char ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_signed_char_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_short_int ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_short_int_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_short_int ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_short_int_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_int ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_int_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_int ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_int_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_long ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_long_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_long ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_long_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_long_long ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_long_long_volatile ) + { + test_atomic_integral_volatile(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_long_long ) + { + test_atomic_integral(); + } + TEST_F( cxx11_atomic_func, atomic_unsigned_long_long_volatile ) + { + test_atomic_integral_volatile(); + } + + TEST_F( cxx11_atomic_func, atomic_pointer_void ) + { + do_test_atomic_pointer_void(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_void_volatile ) + { + do_test_atomic_pointer_void(); + } + + TEST_F( cxx11_atomic_func, atomic_pointer_char ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_char_volatile ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_short ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_short_volatile ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_int ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_int_volatile ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_long ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_long_volatile ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_long_long ) + { + test_atomic_pointer_for(); + } + TEST_F( cxx11_atomic_func, atomic_pointer_long_long_volatile ) + { + test_atomic_pointer_for(); + } + + TEST_F( cxx11_atomic_func, test_atomic_fence ) + { + atomics::atomic_thread_fence(atomics::memory_order_relaxed ); + atomics::atomic_thread_fence(atomics::memory_order_acquire ); + atomics::atomic_thread_fence(atomics::memory_order_release ); + atomics::atomic_thread_fence(atomics::memory_order_acq_rel ); + atomics::atomic_thread_fence(atomics::memory_order_seq_cst ); + + atomics::atomic_signal_fence(atomics::memory_order_relaxed ); + atomics::atomic_signal_fence(atomics::memory_order_acquire ); + atomics::atomic_signal_fence(atomics::memory_order_release ); + atomics::atomic_signal_fence(atomics::memory_order_acq_rel ); + atomics::atomic_signal_fence(atomics::memory_order_seq_cst ); + } +} // namespace + + +#endif // #ifndef CDS_USE_BOOST_ATOMIC diff --git a/test/unit/misc/cxx11_convert_memory_order.h b/test/unit/misc/cxx11_convert_memory_order.h new file mode 100644 index 00000000..f038dc9d --- /dev/null +++ b/test/unit/misc/cxx11_convert_memory_order.h @@ -0,0 +1,87 @@ +/* + 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. +*/ + +// This header should be included AFTER if needed + +namespace { + + static inline atomics::memory_order convert_to_store_order( atomics::memory_order order ) + { + switch ( order ) { + case atomics::memory_order_acquire: + case atomics::memory_order_consume: + return atomics::memory_order_relaxed; + case atomics::memory_order_acq_rel: + return atomics::memory_order_release; + default: + return order; + } + } + + static inline atomics::memory_order convert_to_load_order( atomics::memory_order order ) + { + switch ( order ) { + case atomics::memory_order_release: + return atomics::memory_order_relaxed; + case atomics::memory_order_acq_rel: + return atomics::memory_order_acquire; + default: + return order; + } + } + +#if CDS_COMPILER == CDS_COMPILER_INTEL + static inline atomics::memory_order convert_to_exchange_order( atomics::memory_order order ) + { + return order == atomics::memory_order_consume ? atomics::memory_order_relaxed : order; + } +#else + static inline atomics::memory_order convert_to_exchange_order( atomics::memory_order order ) + { + return order; + } +#endif + + template + struct add_volatile; + + template + struct add_volatile + { + typedef T type; + }; + + template + struct add_volatile + { + typedef T volatile type; + }; + +} // namespace diff --git a/test/unit/misc/find_option.cpp b/test/unit/misc/find_option.cpp new file mode 100644 index 00000000..84837f21 --- /dev/null +++ b/test/unit/misc/find_option.cpp @@ -0,0 +1,209 @@ +/* + 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 + +// Value options +namespace { + + template + struct int_opt { + static const int value = Val; + }; + + template + struct bool_opt { + static const bool value = Val; + }; + + enum user_enum { + val_zero, val_one, val_two, val_three, val_four, val_five + }; + + template + struct enum_opt { + static const user_enum value = Val; + }; +} + +// Declare necessary cds::opt::find_option specialization for user-provided enum type +CDS_DECLARE_FIND_OPTION_INTEGRAL_SPECIALIZATION( user_enum ) + +void find_option_compiler_test() +{ + + // ************************************************* + // Type options + // + struct tag_default; + struct tag_a; + struct tag_b; + + // Option not found + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag, cds::opt::stat, bool_opt >::type, + cds::opt::tag + >::value), "Result != tag_default" ); + + // Option found once + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag, cds::opt::tag >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag, cds::opt::stat, cds::opt::tag >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + // First option + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag + ,cds::opt::tag // desired + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + // Last option + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::tag // desired + >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + // Middle option + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::tag // desired + ,cds::opt::stat + ,cds::opt::stat + >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + // Option not found + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + >::type, + cds::opt::tag + >::value), "Result != tag_default" ); + + // Multiple options + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag, cds::opt::tag, cds::opt::tag >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + static_assert( (std::is_same< + cds::opt::find_option< cds::opt::tag + ,cds::opt::tag // desired - first accepted + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::stat + ,cds::opt::tag // desired + >::type, + cds::opt::tag + >::value), "Result != tag_a" ); + + + // ***************************************************** + // Value options + + // Not found + static_assert( (std::is_same< + cds::opt::find_option< int_opt<15>, bool_opt, cds::opt::stat >::type, + int_opt<15> + >::value), "Result != int_opt<15>" ); + + static_assert( (std::is_same< + cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat >::type, + int_opt<100> + >::value), "Result != int_opt<100>" ); + + static_assert( (std::is_same< + cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat, bool_opt, int_opt<200> >::type, + int_opt<100> + >::value), "Result != int_opt<100>" ); + + // User-provided enum type + static_assert( (std::is_same< + cds::opt::find_option< enum_opt, int_opt<100>, cds::opt::stat, int_opt<200> >::type, + enum_opt + >::value), "Result != enum_opt" ); + + static_assert( (std::is_same< + cds::opt::find_option< enum_opt, int_opt<100>, cds::opt::stat, enum_opt, int_opt<200> >::type, + enum_opt + >::value), "Result != enum_opt" ); + +} + +void test_extracting_option_value() +{ + struct tag_a; + + // Define option + typedef cds::opt::tag< tag_a > tag_option; + + // What is the value of the tag_option? + // How we can extract tag_a from tag_option? + // Here is a solution: + typedef cds::opt::value< tag_option >::tag tag_option_value; + + // tag_option_value is the same as tag_a + static_assert( (std::is_same< tag_option_value, tag_a >::value), "Error getting the value of option: tag_option_value != tag_a" ); + + // Value-option + typedef cds::opt::alignment< 16 > align_option; + static_assert( cds::opt::value< align_option >::alignment == 16, "Error getting the value of option: option value != 16" ); +} diff --git a/test/unit/misc/hash_tuple.cpp b/test/unit/misc/hash_tuple.cpp new file mode 100644 index 00000000..fc72f5fe --- /dev/null +++ b/test/unit/misc/hash_tuple.cpp @@ -0,0 +1,142 @@ +/* + 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 + +namespace { + typedef cds::opt::v::hash_selector< cds::opt::none >::type hashing; + +#define HASHING(_n) \ + struct hash##_n: public hashing { \ + template size_t operator()( T const& v ) const { return hashing::operator()(v) + _n ; } \ + }; + + HASHING(2) + HASHING(3) + HASHING(4) + HASHING(5) + HASHING(6) + HASHING(7) + HASHING(8) + HASHING(9) + HASHING(10) +#undef HASHING + + TEST( HashTuple, test ) + { + int nVal = 5; + size_t nHash = hashing()(nVal); + + size_t val[16]; + + cds::opt::hash< std::tuple< hashing, hash2 > >::pack::hash h2; + h2( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3 > >::pack::hash h3; + h3( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4 > >::pack::hash h4; + h4( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5 > >::pack::hash h5; + h5( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6 > >::pack::hash h6; + h6( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + EXPECT_EQ( val[5], nHash + 6 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7 > >::pack::hash h7; + h7( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + EXPECT_EQ( val[5], nHash + 6 ); + EXPECT_EQ( val[6], nHash + 7 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8 > >::pack::hash h8; + h8( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + EXPECT_EQ( val[5], nHash + 6 ); + EXPECT_EQ( val[6], nHash + 7 ); + EXPECT_EQ( val[7], nHash + 8 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9 > >::pack::hash h9; + h9( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + EXPECT_EQ( val[5], nHash + 6 ); + EXPECT_EQ( val[6], nHash + 7 ); + EXPECT_EQ( val[7], nHash + 8 ); + EXPECT_EQ( val[8], nHash + 9 ); + + cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9, hash10 > >::pack::hash h10; + h10( val, nVal ); + EXPECT_EQ( val[0], nHash ); + EXPECT_EQ( val[1], nHash + 2 ); + EXPECT_EQ( val[2], nHash + 3 ); + EXPECT_EQ( val[3], nHash + 4 ); + EXPECT_EQ( val[4], nHash + 5 ); + EXPECT_EQ( val[5], nHash + 6 ); + EXPECT_EQ( val[6], nHash + 7 ); + EXPECT_EQ( val[7], nHash + 8 ); + EXPECT_EQ( val[8], nHash + 9 ); + EXPECT_EQ( val[9], nHash + 10 ); + } + +} // namespace diff --git a/test/unit/misc/permutation_generator.cpp b/test/unit/misc/permutation_generator.cpp new file mode 100644 index 00000000..f02bb9b2 --- /dev/null +++ b/test/unit/misc/permutation_generator.cpp @@ -0,0 +1,95 @@ +/* + 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 + +namespace { + + class Permutations: public ::testing::Test + { + protected: + static const size_t c_nMax = 1024; + + template + void test_with( Gen& gen, size_t nLen ) + { + unsigned int arr[c_nMax]; + for ( size_t nPass = 0; nPass < 10; ++nPass ) { + for ( size_t i = 0; i < c_nMax; ++i ) + arr[i] = 0; + + do { + typename Gen::integer_type i = gen; + ++arr[ i ]; + } while ( gen.next() ); + + for ( size_t i = 0; i < nLen; ++i ) + EXPECT_EQ( arr[i], 1 ) << "i=" << i; + for ( size_t i = nLen; i < c_nMax; ++i ) + EXPECT_EQ( arr[i], 0 ) << "i=" << i; + + gen.reset(); + } + } + + template + void test() + { + for ( size_t nLen = 2; nLen <= c_nMax; ++nLen ) { + Gen gen( nLen ); + test_with( gen, nLen ); + } + } + + template + void test2() + { + for ( size_t nLen = 2; nLen <= c_nMax; nLen *= 2 ) { + Gen gen( nLen ); + test_with( gen, nLen ); + } + } + }; + + TEST_F( Permutations, random_permutation ) + { + test< cds::opt::v::random_permutation<> >(); + } + TEST_F( Permutations, random2_permutation ) + { + test2< cds::opt::v::random2_permutation<> >(); + } + TEST_F( Permutations, random_shuffle_permutation ) + { + test< cds::opt::v::random_shuffle_permutation<> >(); + } + +} // namespace diff --git a/test/unit/misc/split_bitstring.cpp b/test/unit/misc/split_bitstring.cpp new file mode 100644 index 00000000..a362a332 --- /dev/null +++ b/test/unit/misc/split_bitstring.cpp @@ -0,0 +1,318 @@ +/* + 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 + +namespace { + class Split_bitstrig : public ::testing::Test + { + protected: + bool is_big_endian() + { + union { + uint32_t ui; + uint8_t ch; + } byte_order; + byte_order.ui = 0xFF000001; + + return byte_order.ch != 0x01; + } + + void cut_uint_le() + { + typedef cds::algo::split_bitstring< size_t > split_bitstring; + + size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210; + split_bitstring splitter(src); + size_t res; + + // Trivial case + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = splitter.cut(sizeof(src) * 8); + EXPECT_EQ( res, src ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ(splitter.safe_cut(sizeof(src) * 8), 0 ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + splitter.reset(); + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = splitter.cut(sizeof(src) * 8); + EXPECT_EQ( res, src ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( splitter.safe_cut(sizeof(src) * 8), 0 ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + ASSERT_EQ( splitter.cut( 4 ), i ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_FALSE( splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = res + (splitter.cut( 1 ) << i); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + size_t shift = 0; + while ( splitter ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + int bits = rand() % 16; + res = res + ( splitter.safe_cut( bits ) << shift ); + shift += bits; + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + } + } + + void cut_uint_be() + { + typedef cds::algo::split_bitstring< size_t > split_bitstring; + + size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210; + split_bitstring splitter(src); + size_t res; + + // Trivial case + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = splitter.cut(sizeof(src) * 8); + ASSERT_EQ( res, src ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ(splitter.safe_cut(sizeof(src) * 8), 0 ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + splitter.reset(); + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = splitter.cut(sizeof(src) * 8); + EXPECT_EQ( res, src ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ(splitter.safe_cut(sizeof(src) * 8), 0 ); + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + EXPECT_EQ( splitter.cut( 4 ), 0x0F - i ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = (res << 1) + splitter.cut( 1 ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + while ( splitter ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + int bits = rand() % 16; + res = (res << bits) + splitter.safe_cut( bits ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + } + } + + template + void cut_small_le() + { + typedef PartUInt part_uint; + + typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; + + uint64_t src = 0xFEDCBA9876543210; + split_bitstring splitter(src); + uint64_t res; + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + EXPECT_EQ( static_cast(splitter.cut( 4 )), i ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = res + ( static_cast(splitter.cut( 1 )) << i); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + size_t shift = 0; + while ( splitter ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + int bits = rand() % 16; + res = res + ( static_cast(splitter.safe_cut( bits )) << shift ); + shift += bits; + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + } + } + + template + void cut_small_be() + { + typedef PartUInt part_uint; + + typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; + + uint64_t src = 0xFEDCBA9876543210; + split_bitstring splitter(src); + uint64_t res; + + // Cut each hex digit + splitter.reset(); + for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + EXPECT_EQ( splitter.cut( 4 ), 0x0F - i ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + + // by one bit + { + splitter.reset(); + res = 0; + for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + res = (res << 1) + splitter.cut( 1 ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + + // random cut + { + for ( size_t k = 0; k < 100; ++k ) { + splitter.reset(); + res = 0; + while ( splitter ) { + ASSERT_FALSE( splitter.eos() ); + ASSERT_FALSE( !splitter ); + int bits = rand() % 16; + res = (res << bits) + splitter.safe_cut( bits ); + } + ASSERT_TRUE( splitter.eos() ); + ASSERT_TRUE( !splitter ); + EXPECT_EQ( res, src ); + } + } + } + }; + + TEST_F( Split_bitstrig, cut_uint ) + { + if ( is_big_endian() ) + cut_uint_be(); + else + cut_uint_le(); + } + + TEST_F( Split_bitstrig, cut_uint16 ) + { + if ( is_big_endian() ) + cut_small_be(); + else + cut_small_le(); + } + +} // namespace diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2b16f072..1a9516e7 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,7 +10,6 @@ set(SOURCES cppunit/test_main.cpp add_library(${TEST_COMMON} OBJECT ${SOURCES}) -add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test-hdr) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/unit) #file(GLOB CONF_FILES ${PROJECT_SOURCE_DIR}/tests/data/*.conf) diff --git a/tests/test-hdr/CMakeLists.txt b/tests/test-hdr/CMakeLists.txt deleted file mode 100644 index fa5938cd..00000000 --- a/tests/test-hdr/CMakeLists.txt +++ /dev/null @@ -1,20 +0,0 @@ -set(PACKAGE_NAME test-hdr) - -set(CDS_TESTHDR_MISC - misc/cxx11_atomic_class.cpp - misc/cxx11_atomic_func.cpp - misc/find_option.cpp - misc/allocator_test.cpp - misc/michael_allocator.cpp - misc/hash_tuple.cpp - misc/bitop_st.cpp - misc/split_bitstring.cpp - misc/permutation_generator.cpp - misc/thread_init_fini.cpp) - -set(CDS_TESTHDR_SOURCES - ${CDS_TESTHDR_MISC}) - -add_executable(${PACKAGE_NAME} ${CDS_TESTHDR_SOURCES} $ $) -target_link_libraries(${PACKAGE_NAME} ${CDS_SHARED_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/tests/test-hdr/misc/allocator_test.cpp b/tests/test-hdr/misc/allocator_test.cpp deleted file mode 100644 index 9cd3f2af..00000000 --- a/tests/test-hdr/misc/allocator_test.cpp +++ /dev/null @@ -1,196 +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 "misc/michael_allocator.h" -#include -#include - -#include "cppunit/cppunit_proxy.h" - -namespace misc { - - static size_t s_nPassCount = 10; - static unsigned long long s_nAllocPerPass = 1024 * 1024 * 1024; - - static size_t s_nConstructCount = 0; - static size_t s_nDestructCount = 0; - - class Allocator_test : public CppUnitMini::TestCase - { - static const size_t s_nArrSizeSize = 64 * 1024; - unsigned int m_arrSize[s_nArrSizeSize]; - - template - void alloc_free() - { - ALLOC a; - - for ( size_t nPass = 0; nPass < s_nPassCount; ++nPass ) { - unsigned long long nTotalAllocated = 0; - size_t nCurIdx = 0; - while ( nTotalAllocated < s_nAllocPerPass ) { - size_t nSize = m_arrSize[nCurIdx] + 4; - char * p = a.allocate( nSize, nullptr ); - CPPUNIT_ASSERT( p != nullptr ); - memset( p, 0x96, nSize ); - nTotalAllocated += nSize; - a.deallocate( p, 1 ); - if ( ++nCurIdx > s_nArrSizeSize ) - nCurIdx = 0; - } - } - } - - void alloc_free_michael() - { - std::cout << "\n\tMichael allocator" << std::flush; - cds::OS::Timer timer; - alloc_free >(); - double fDur = timer.duration(); - std::cout << "\tduration=" << fDur << std::endl; - - //cds::memory::michael_allocator::statistics st; - //s_MichaelAlloc.get_statistics( st ); - } - void alloc_free_std() - { - std::cout << "\n\tstd::allocator" << std::flush; - cds::OS::Timer timer; - alloc_free >(); - double fDur = timer.duration(); - std::cout << "\tduration=" << fDur << std::endl; - } - - template - void alloc_all_free_all() - { - ALLOC a; - - for ( size_t nPass = 0; nPass < s_nPassCount; ++nPass ) { - unsigned long long nTotalAllocated = 0; - char * pHead = a.allocate( sizeof(void *), nullptr ); - CPPUNIT_ASSERT( pHead != nullptr ); - char * pCur = pHead; - size_t nCurIdx = 0; - while ( nTotalAllocated < s_nAllocPerPass ) { - size_t nSize = m_arrSize[nCurIdx] + sizeof(void *); - char * p = a.allocate( nSize, nullptr ); - CPPUNIT_ASSERT( p != nullptr ); - memset( p, 0x96, nSize ); - *((char **) pCur) = p; - pCur = p; - nTotalAllocated += nSize; - if ( ++nCurIdx > s_nArrSizeSize ) - nCurIdx = 0; - } - *((char **) pCur) = nullptr; - - pCur = pHead; - while ( pCur != nullptr ) { - char * pNext = *((char **) pCur); - a.deallocate( pCur, 0 ); - pCur = pNext; - } - } - } - - void alloc_all_free_all_michael() - { - std::cout << "\n\tMichael allocator" << std::flush; - cds::OS::Timer timer; - alloc_all_free_all >(); - double fDur = timer.duration(); - std::cout << "\tduration=" << fDur << std::endl; - - //cds::memory::michael_allocator::statistics st; - //s_MichaelAlloc.get_statistics( st ); - } - void alloc_all_free_all_std() - { - std::cout << "\n\tstd::allocator" << std::flush; - cds::OS::Timer timer; - alloc_all_free_all >(); - double fDur = timer.duration(); - std::cout << "\tduration=" << fDur << std::endl; - } - - struct SimpleStruct - { - int n; - - SimpleStruct() - { - ++s_nConstructCount; - } - - ~SimpleStruct() - { - ++s_nDestructCount; - } - }; - - void test_array() - { - size_t const nArraySize = 10; - - SimpleStruct * pArr; - cds::details::Allocator a; - pArr = a.NewArray( nArraySize ); - a.Delete( pArr, nArraySize ); - - CPPUNIT_ASSERT( s_nConstructCount == nArraySize ); - CPPUNIT_ASSERT( s_nConstructCount == s_nDestructCount ); - } - - - void setUpParams( const CppUnitMini::TestCfg& cfg ) - { - s_nPassCount = cfg.getULong( "PassCount", 10 ); - s_nAllocPerPass = cfg.getULong( "AllocPerPass", 1024 ) * 1024 * 1024; - } - - public: - Allocator_test() - { - CPPUNIT_ASSERT( s_nArrSizeSize == sizeof(m_arrSize) / sizeof(m_arrSize[0]) ); - for ( size_t i = 0; i < s_nArrSizeSize; ++i ) - m_arrSize[i] = rand(); - } - - CPPUNIT_TEST_SUITE(Allocator_test); - CPPUNIT_TEST(test_array) - CPPUNIT_TEST(alloc_free_michael) - CPPUNIT_TEST(alloc_free_std) - CPPUNIT_TEST(alloc_all_free_all_michael) - CPPUNIT_TEST(alloc_all_free_all_std) - CPPUNIT_TEST_SUITE_END(); - }; -} // namespace memory -CPPUNIT_TEST_SUITE_REGISTRATION( misc::Allocator_test ); diff --git a/tests/test-hdr/misc/bitop_st.cpp b/tests/test-hdr/misc/bitop_st.cpp deleted file mode 100644 index f0546652..00000000 --- a/tests/test-hdr/misc/bitop_st.cpp +++ /dev/null @@ -1,113 +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 "cppunit/cppunit_proxy.h" - -#include -#include - -class bitop_ST : public CppUnitMini::TestCase -{ -protected: - void bitop32() - { - uint32_t n; - n = 0; - CPPUNIT_ASSERT_EX( cds::bitop::MSB(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSB(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::SBC(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::ZBC(n) == sizeof(n) * 8, "n=" << n ); - - int nBit = 1; - for ( n = 1; n != 0; n *= 2 ) { - CPPUNIT_ASSERT_EX( cds::bitop::MSB(n) == nBit, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSB(n) == nBit, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::MSBnz(n) == nBit - 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSBnz(n) == nBit - 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::SBC(n) == 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::ZBC(n) == sizeof(n) * 8 - 1, "n=" << n ); - - ++nBit; - } - } - - void bitop64() - { - uint64_t n; - n = 0; - CPPUNIT_ASSERT_EX( cds::bitop::MSB(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSB(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::SBC(n) == 0, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::ZBC(n) == sizeof(n) * 8, "n=" << n ); - - int nBit = 1; - for ( n = 1; n != 0; n *= 2 ) { - CPPUNIT_ASSERT_EX( cds::bitop::MSB(n) == nBit, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSB(n) == nBit, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::MSBnz(n) == nBit - 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::LSBnz(n) == nBit - 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::SBC(n) == 1, "n=" << n ); - CPPUNIT_ASSERT_EX( cds::bitop::ZBC(n) == sizeof(n) * 8 - 1, "n=" << n ); - - ++nBit; - } - } - - void floor_ceil_pow2() - { - CPPUNIT_CHECK_EX( cds::beans::floor2(0) == 1, "floor2(0) = " << cds::beans::floor2(0) << ", expected 1" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(1) == 1, "floor2(1) = " << cds::beans::floor2(1) << ", expected 1" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(2) == 2, "floor2(2) = " << cds::beans::floor2(2) << ", expected 2" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(3) == 2, "floor2(3) = " << cds::beans::floor2(3) << ", expected 2" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(4) == 4, "floor2(4) = " << cds::beans::floor2(4) << ", expected 4" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(5) == 4, "floor2(5) = " << cds::beans::floor2(5) << ", expected 4" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(7) == 4, "floor2(7) = " << cds::beans::floor2(7) << ", expected 4" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(8) == 8, "floor2(8) = " << cds::beans::floor2(8) << ", expected 8" ); - CPPUNIT_CHECK_EX( cds::beans::floor2(9) == 8, "floor2(9) = " << cds::beans::floor2(9) << ", expected 8" ); - - CPPUNIT_CHECK_EX( cds::beans::ceil2(0) == 1, "ceil2(0) = " << cds::beans::ceil2(0) << ", expected 1" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(1) == 1, "ceil2(1) = " << cds::beans::ceil2(1) << ", expected 1" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(2) == 2, "ceil2(2) = " << cds::beans::ceil2(2) << ", expected 2" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(3) == 4, "ceil2(3) = " << cds::beans::ceil2(3) << ", expected 4" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(4) == 4, "ceil2(4) = " << cds::beans::ceil2(4) << ", expected 4" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(5) == 8, "ceil2(5) = " << cds::beans::ceil2(5) << ", expected 8" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(7) == 8, "ceil2(7) = " << cds::beans::ceil2(7) << ", expected 8" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(8) == 8, "ceil2(8) = " << cds::beans::ceil2(8) << ", expected 8" ); - CPPUNIT_CHECK_EX( cds::beans::ceil2(9) == 16, "ceil2(9) = " << cds::beans::ceil2(16) << ", expected 16" ); - } - - CPPUNIT_TEST_SUITE(bitop_ST); - CPPUNIT_TEST(bitop32) - CPPUNIT_TEST(bitop64) - CPPUNIT_TEST(floor_ceil_pow2) - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(bitop_ST); diff --git a/tests/test-hdr/misc/cxx11_atomic_class.cpp b/tests/test-hdr/misc/cxx11_atomic_class.cpp deleted file mode 100644 index 8dcdbc0d..00000000 --- a/tests/test-hdr/misc/cxx11_atomic_class.cpp +++ /dev/null @@ -1,778 +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 "cppunit/cppunit_proxy.h" - -#include - -#include "misc/cxx11_convert_memory_order.h" - -namespace misc { - class cxx11_atomic_class: public CppUnitMini::TestCase - { - template - void do_test_atomic_flag_mo( AtomicFlag& f, atomics::memory_order order ) - { - atomics::memory_order mo_clear = convert_to_store_order(order); - for ( int i = 0; i < 5; ++i ) { - CPPUNIT_ASSERT( !f.test_and_set( order )); - CPPUNIT_ASSERT( f.test_and_set( order ) ); - f.clear( mo_clear ); - } - } - - template - void do_test_atomic_flag( AtomicFlag& f) - { - f.clear(); - - for ( int i = 0; i < 5; ++i ) { - CPPUNIT_ASSERT( !f.test_and_set()); - CPPUNIT_ASSERT( f.test_and_set() ); - f.clear(); - } - - do_test_atomic_flag_mo( f, atomics::memory_order_relaxed ); - //do_test_atomic_flag_mo( f, atomics::memory_order_consume ); - do_test_atomic_flag_mo( f, atomics::memory_order_acquire ); - do_test_atomic_flag_mo( f, atomics::memory_order_release ); - do_test_atomic_flag_mo( f, atomics::memory_order_acq_rel ); - do_test_atomic_flag_mo( f, atomics::memory_order_seq_cst ); - } - - template - void do_test_atomic_type(Atomic& a) - { - typedef Integral integral_type; - - CPPUNIT_ASSERT( a.is_lock_free() ); - a.store( (integral_type) 0 ); - CPPUNIT_ASSERT( a == 0 ); - CPPUNIT_ASSERT( a.load() == 0 ); - - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - CPPUNIT_ASSERT( a.exchange( n ) == 0 ); - CPPUNIT_ASSERT( a == n ); - CPPUNIT_ASSERT( a.exchange( (integral_type) 0 ) == n ); - CPPUNIT_ASSERT( a.load() == 0 ); - } - - integral_type prev = a.load(); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( a.compare_exchange_weak( expected, n)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( expected, n)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( a == n ); - } - - a = (integral_type) 0; - - prev = a; - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( a.compare_exchange_strong( expected, n)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( expected, n)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( a.load() == n ); - } - - CPPUNIT_ASSERT( a.exchange( (integral_type) 0 ) == prev ); - } - - template - void do_test_atomic_integral(Atomic& a) - { - do_test_atomic_type< Atomic, Integral >(a); - - typedef Integral integral_type; - - // fetch_xxx testing - a.store( (integral_type) 0 ); - - // fetch_add - for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) - { - integral_type prev = a.load(); - integral_type n = integral_type(42) << (nByte * 8); - - CPPUNIT_ASSERT( a.fetch_add(n) == prev); - } - - // fetch_sub - for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) - { - integral_type prev = a.load(); - integral_type n = integral_type(42) << ((nByte - 1) * 8); - - CPPUNIT_ASSERT( a.fetch_sub(n) == prev); - } - CPPUNIT_ASSERT( a.load() == 0 ); - - // fetch_or / fetc_xor / fetch_and - for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) - { - integral_type prev = a.load() ;; - integral_type mask = 1 << nBit; - - CPPUNIT_ASSERT( a.fetch_or( mask ) == prev ); - prev = a.load(); - CPPUNIT_ASSERT( ( prev & mask) == mask); - - CPPUNIT_ASSERT( a.fetch_and( (integral_type) ~mask ) == prev ); - prev = a.load(); - CPPUNIT_ASSERT( integral_type(prev & mask) == integral_type(0)); - - CPPUNIT_ASSERT( a.fetch_xor( mask ) == prev ); - prev = a.load(); - CPPUNIT_ASSERT( integral_type( prev & mask) == mask); - } - CPPUNIT_ASSERT( a.load() == (integral_type) -1 ); - - - // op= testing - a = (integral_type) 0; - - // += - for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) - { - integral_type prev = a; - integral_type n = integral_type(42) << (nByte * 8); - - CPPUNIT_ASSERT( (a += n) == (prev + n)); - } - - // -= - for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) - { - integral_type prev = a; - integral_type n = integral_type(42) << ((nByte - 1) * 8); - - CPPUNIT_ASSERT( (a -= n) == prev - n ); - } - CPPUNIT_ASSERT( a.load() == 0 ); - - // |= / ^= / &= - for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) - { - integral_type prev = a; - integral_type mask = integral_type(1) << nBit; - - CPPUNIT_ASSERT( (a |= mask ) == (prev | mask )); - prev = a; - CPPUNIT_ASSERT( ( prev & mask) == mask); - - CPPUNIT_ASSERT( (a &= (integral_type) ~mask ) == ( prev & (integral_type) ~mask )); - prev = a; - CPPUNIT_ASSERT( ( prev & mask) == 0); - - CPPUNIT_ASSERT( (a ^= mask ) == (prev ^ mask )); - prev = a; - CPPUNIT_ASSERT( ( prev & mask) == mask); - } - CPPUNIT_ASSERT( a == (integral_type) -1 ); - } - - template - void do_test_atomic_type( Atomic& a, atomics::memory_order order ) - { - typedef Integral integral_type; - - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - - CPPUNIT_ASSERT( a.is_lock_free() ); - a.store((integral_type) 0, oStore ); - CPPUNIT_ASSERT( a == 0 ); - CPPUNIT_ASSERT( a.load( oLoad ) == 0 ); - - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - CPPUNIT_ASSERT( a.exchange( n, order ) == 0 ); - CPPUNIT_ASSERT( a.load( oLoad ) == n ); - CPPUNIT_ASSERT( a.exchange( (integral_type) 0, order ) == n ); - CPPUNIT_ASSERT( a.load( oLoad ) == 0 ); - } - - integral_type prev = a.load( oLoad ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( a.compare_exchange_weak( expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( a.load( oLoad ) == n ); - } - - a.store( (integral_type) 0, oStore ); - - prev = a.load( oLoad ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( a.compare_exchange_strong( expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( a.load( oLoad ) == n ); - } - - CPPUNIT_ASSERT( a.exchange( (integral_type) 0, order ) == prev ); - } - - template - void do_test_atomic_integral( Atomic& a, atomics::memory_order order ) - { - do_test_atomic_type< Atomic, Integral >( a, order ); - - typedef Integral integral_type; - - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - - // fetch_xxx testing - a.store( (integral_type) 0, oStore ); - - // fetch_add - for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) - { - integral_type prev = a.load( oLoad ); - integral_type n = integral_type(42) << (nByte * 8); - - CPPUNIT_ASSERT( a.fetch_add( n, order) == prev); - } - - // fetch_sub - for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) - { - integral_type prev = a.load( oLoad ); - integral_type n = integral_type(42) << ((nByte - 1) * 8); - - CPPUNIT_ASSERT( a.fetch_sub( n, order ) == prev); - } - CPPUNIT_ASSERT( a.load( oLoad ) == 0 ); - - // fetch_or / fetc_xor / fetch_and - for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) - { - integral_type prev = a.load( oLoad ) ;; - integral_type mask = 1 << nBit; - - CPPUNIT_ASSERT( a.fetch_or( mask, order ) == prev ); - prev = a.load( oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - - CPPUNIT_ASSERT( a.fetch_and( (integral_type) ~mask, order ) == prev ); - prev = a.load( oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == 0); - - CPPUNIT_ASSERT( a.fetch_xor( mask, order ) == prev ); - prev = a.load( oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - } - CPPUNIT_ASSERT( a.load( oLoad ) == (integral_type) -1 ); - } - - - - template - void test_atomic_integral_(Atomic& a) - { - do_test_atomic_integral(a); - - do_test_atomic_integral( a, atomics::memory_order_relaxed ); -//#if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40900) -// do_test_atomic_integral( a, atomics::memory_order_consume ); -//#endif - do_test_atomic_integral( a, atomics::memory_order_acquire ); - do_test_atomic_integral( a, atomics::memory_order_release ); - do_test_atomic_integral( a, atomics::memory_order_acq_rel ); - do_test_atomic_integral( a, atomics::memory_order_seq_cst ); - } - - template - void test_atomic_integral() - { - typedef atomics::atomic atomic_type; - - atomic_type a[8]; - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - test_atomic_integral_( a[i] ); - } - } - template - void test_atomic_integral_volatile() - { - typedef atomics::atomic volatile atomic_type; - - atomic_type a[8]; - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - test_atomic_integral_( a[i] ); - } - } - - template - void do_test_atomic_bool( AtomicBool& a ) - { - CPPUNIT_ASSERT( a.is_lock_free() ); - a.store( false ); - CPPUNIT_ASSERT( a == false ); - CPPUNIT_ASSERT( a.load() == false ); - - CPPUNIT_ASSERT( a.exchange( true ) == false ); - CPPUNIT_ASSERT( a.load() == true ); - CPPUNIT_ASSERT( a.exchange( false ) == true ); - CPPUNIT_ASSERT( a.load() == false ); - - bool expected = false; - CPPUNIT_ASSERT( a.compare_exchange_weak( expected, true)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( expected, false)); - CPPUNIT_ASSERT( expected == true ); - CPPUNIT_ASSERT( a.load() == true ); - - a.store( false ); - - expected = false; - CPPUNIT_ASSERT( a.compare_exchange_strong( expected, true)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( expected, false)); - CPPUNIT_ASSERT( expected == true ); - - CPPUNIT_ASSERT( a.load() == true ); - - CPPUNIT_ASSERT( a.exchange( false ) == true ); - } - - template - void do_test_atomic_bool( AtomicBool& a, atomics::memory_order order ) - { - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - const atomics::memory_order oExchange = convert_to_exchange_order( order ); - - CPPUNIT_ASSERT( a.is_lock_free() ); - a.store( false, oStore ); - CPPUNIT_ASSERT( a == false ); - CPPUNIT_ASSERT( a.load( oLoad ) == false ); - - CPPUNIT_ASSERT( a.exchange( true, oExchange ) == false ); - CPPUNIT_ASSERT( a.load( oLoad ) == true ); - CPPUNIT_ASSERT( a.exchange( false, oExchange ) == true ); - CPPUNIT_ASSERT( a.load( oLoad ) == false ); - - bool expected = false; - CPPUNIT_ASSERT( a.compare_exchange_weak( expected, true, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( expected, false, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == true ); - CPPUNIT_ASSERT( a.load( oLoad ) == true ); - - //a = bool(false); - a.store( false, oStore ); - - expected = false; - CPPUNIT_ASSERT( a.compare_exchange_strong( expected, true, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( expected, false, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == true ); - - CPPUNIT_ASSERT( a.load( oLoad ) == true ); - - CPPUNIT_ASSERT( a.exchange( false, oExchange ) == true ); - } - - - template - void do_test_atomic_pointer_void_( Atomic& a, char * arr, char aSize, atomics::memory_order order ) - { - atomics::memory_order oLoad = convert_to_load_order(order); - atomics::memory_order oStore = convert_to_store_order(order); - void * p; - - a.store( (void *) arr, oStore ); - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == 1 ); - - p = arr; - CPPUNIT_ASSERT( a.compare_exchange_weak( p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( *reinterpret_cast(p) == 1 ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *reinterpret_cast(p) == 6 ); - - CPPUNIT_ASSERT( a.compare_exchange_strong( p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *reinterpret_cast(p) == 6 ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 3 ); - CPPUNIT_ASSERT( *reinterpret_cast(p) == 4 ); - - CPPUNIT_ASSERT( reinterpret_cast(a.exchange( (void *) arr, order )) == arr + 3 ); - CPPUNIT_ASSERT( reinterpret_cast(a.load( oLoad )) == arr ); - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == 1 ); - - for ( char i = 1; i < aSize; ++i ) { - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == i ); - CPPUNIT_ASSERT( a.fetch_add( 1, order )); - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == i + 1 ); - } - - for ( char i = aSize; i > 1; --i ) { - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == i ); - CPPUNIT_ASSERT( a.fetch_sub( 1, order )); - CPPUNIT_ASSERT( *reinterpret_cast(a.load( oLoad )) == i - 1 ); - } - } - - template - void do_test_atomic_pointer_void() - { - typedef typename add_volatile, Volatile>::type atomic_pointer; - - char arr[8]; - const char aSize = sizeof(arr)/sizeof(arr[0]); - for ( char i = 0; i < aSize; ++i ) { - arr[unsigned(i)] = i + 1; - } - - atomic_pointer a; - void * p; - -#if CDS_BUILD_BITS == 32 && !( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION == 40700 ) - /* GCC 4.7.0 has an linktime error in 32bit x86 mode: - - ../tests/test-hdr/misc/cxx11_atomic_class.o: In function `std::__atomic_base::is_lock_free() const': - /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/atomic_base.h:719: undefined reference to `__atomic_is_lock_free' - - ../tests/test-hdr/misc/cxx11_atomic_class.o: In function `std::__atomic_base::is_lock_free() const volatile': - /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.7.0/../../../../include/c++/4.7.0/bits/atomic_base.h:723: undefined reference to `__atomic_is_lock_free' - - */ - CPPUNIT_ASSERT( a.is_lock_free() ); -#endif - - a.store( (void *) arr ); - CPPUNIT_ASSERT( *reinterpret_cast(a.load()) == 1 ); - - p = arr; - CPPUNIT_ASSERT( a.compare_exchange_weak( p, (void *)(arr + 5) )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( p, (void *)(arr + 3) )); - CPPUNIT_ASSERT( p == arr + 5 ); - - CPPUNIT_ASSERT( a.compare_exchange_strong( p, (void *)(arr + 3) )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( p, (void *)(arr + 5) )); - CPPUNIT_ASSERT( p == arr + 3 ); - - CPPUNIT_ASSERT( reinterpret_cast( a.exchange( (void *) arr )) == arr + 3 ); - CPPUNIT_ASSERT( reinterpret_cast( a.load()) == arr ); - CPPUNIT_ASSERT( *reinterpret_cast( a.load()) == 1 ); - - for ( char i = 1; i < aSize; ++i ) { - CPPUNIT_ASSERT( *reinterpret_cast(a.load()) == i ); - CPPUNIT_ASSERT( a.fetch_add( 1 )); - CPPUNIT_ASSERT( *reinterpret_cast(a.load()) == i + 1 ); - } - - for ( char i = aSize; i > 1; --i ) { - CPPUNIT_ASSERT( *reinterpret_cast(a.load()) == i ); - CPPUNIT_ASSERT( a.fetch_sub( 1 )); - CPPUNIT_ASSERT( *reinterpret_cast(a.load()) == i - 1 ); - } - - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_relaxed ); - //do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_consume ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acquire ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_release ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acq_rel ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_seq_cst ); - } - - template - void test_atomic_pointer_for_( Atomic& a, Integral * arr, Integral aSize, atomics::memory_order order ) - { - typedef Integral integral_type; - atomics::memory_order oLoad = convert_to_load_order(order); - atomics::memory_order oStore = convert_to_store_order(order); - integral_type * p; - - a.store( arr, oStore ); - CPPUNIT_ASSERT( *a.load( oLoad ) == 1 ); - - p = arr; - CPPUNIT_ASSERT( a.compare_exchange_weak( p, arr + 5, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( *p == 1 ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( p, arr + 3, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - - CPPUNIT_ASSERT( a.compare_exchange_strong( p, arr + 3, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( p, arr + 5, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 3 ); - CPPUNIT_ASSERT( *p == 4 ); - - CPPUNIT_ASSERT( a.exchange( arr, order ) == arr + 3 ); - CPPUNIT_ASSERT( a.load( oLoad ) == arr ); - CPPUNIT_ASSERT( *a.load( oLoad ) == 1 ); - - for ( integral_type i = 1; i < aSize; ++i ) { - integral_type * p = a.load(); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( a.fetch_add( 1, order ) == p ); - CPPUNIT_ASSERT( *a.load( oLoad ) == i + 1 ); - } - - for ( integral_type i = aSize; i > 1; --i ) { - integral_type * p = a.load(); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( a.fetch_sub( 1, order ) == p ); - CPPUNIT_ASSERT( *a.load( oLoad ) == i - 1 ); - } - } - - template - void test_atomic_pointer_for() - { - typedef Integral integral_type; - typedef typename add_volatile, Volatile>::type atomic_pointer; - - integral_type arr[8]; - const integral_type aSize = sizeof(arr)/sizeof(arr[0]); - for ( integral_type i = 0; i < aSize; ++i ) { - arr[size_t(i)] = i + 1; - } - - atomic_pointer a; - integral_type * p; - - a.store( arr ); - CPPUNIT_ASSERT( *a.load() == 1 ); - - p = arr; - CPPUNIT_ASSERT( a.compare_exchange_weak( p, arr + 5 )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( *p == 1 ); - CPPUNIT_ASSERT( !a.compare_exchange_weak( p, arr + 3 )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - - CPPUNIT_ASSERT( a.compare_exchange_strong( p, arr + 3 )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - CPPUNIT_ASSERT( !a.compare_exchange_strong( p, arr + 5 )); - CPPUNIT_ASSERT( p == arr + 3 ); - CPPUNIT_ASSERT( *p == 4 ); - - CPPUNIT_ASSERT( a.exchange( arr ) == arr + 3 ); - CPPUNIT_ASSERT( a.load() == arr ); - CPPUNIT_ASSERT( *a.load() == 1 ); - - for ( integral_type i = 1; i < aSize; ++i ) { - integral_type * p = a.load(); - CPPUNIT_ASSERT( *p == i ); - integral_type * pa = a.fetch_add( 1 ); - CPPUNIT_ASSERT_EX( pa == p, "pa=" << ((uintptr_t) pa) << " p=" << ((uintptr_t) p) ); - CPPUNIT_ASSERT( *a.load() == i + 1 ); - } - - for ( integral_type i = aSize; i > 1; --i ) { - integral_type * p = a.load(); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( a.fetch_sub( 1 ) == p ); - CPPUNIT_ASSERT( *a.load() == i - 1 ); - } - - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_relaxed ); - //test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_consume ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acquire ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_release ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acq_rel ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_seq_cst ); - } - - public: - void test_atomic_flag() - { - // Array to test different alignment - - atomics::atomic_flag flags[8]; - for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) - do_test_atomic_flag( flags[i] ); - } - - void test_atomic_flag_volatile() - { - // Array to test different alignment - - atomics::atomic_flag volatile flags[8]; - for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) - do_test_atomic_flag( flags[i] ); - } - - template - void test_atomic_bool_() - { - // Array to test different alignment - AtomicBool a[8]; - - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - do_test_atomic_bool( a[i] ); - - do_test_atomic_bool( a[i], atomics::memory_order_relaxed ); - //do_test_atomic_bool( a[i], atomics::memory_order_consume ); - do_test_atomic_bool( a[i], atomics::memory_order_acquire ); - do_test_atomic_bool( a[i], atomics::memory_order_release ); - do_test_atomic_bool( a[i], atomics::memory_order_acq_rel ); - do_test_atomic_bool( a[i], atomics::memory_order_seq_cst ); - } - } - - void test_atomic_bool() - { - test_atomic_bool_< atomics::atomic >(); - } - void test_atomic_bool_volatile() - { - test_atomic_bool_< atomics::atomic volatile >(); - } - - void test_atomic_char() { test_atomic_integral(); } - void test_atomic_signed_char() { test_atomic_integral(); } - void test_atomic_unsigned_char() { test_atomic_integral(); } - void test_atomic_short_int() { test_atomic_integral(); } - void test_atomic_unsigned_short_int() { test_atomic_integral(); } - void test_atomic_int() { test_atomic_integral(); } - void test_atomic_unsigned_int() { test_atomic_integral(); } - void test_atomic_long() { test_atomic_integral(); } - void test_atomic_unsigned_long() { test_atomic_integral(); } - void test_atomic_long_long() { test_atomic_integral(); } - void test_atomic_unsigned_long_long() { test_atomic_integral(); } - - void test_atomic_char_volatile() { test_atomic_integral_volatile(); } - void test_atomic_signed_char_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_char_volatile() { test_atomic_integral_volatile(); } - void test_atomic_short_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_short_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_long_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_long_long_volatile() { test_atomic_integral_volatile(); } - - void test_atomic_pointer_void() { do_test_atomic_pointer_void() ;} - void test_atomic_pointer_void_volatile(){ do_test_atomic_pointer_void() ;} - - void test_atomic_pointer_char() { test_atomic_pointer_for() ;} - void test_atomic_pointer_short() { test_atomic_pointer_for() ;} - void test_atomic_pointer_int() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_long() { test_atomic_pointer_for() ;} - - void test_atomic_pointer_char_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_short_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_int_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_long_volatile() { test_atomic_pointer_for() ;} - - public: - CPPUNIT_TEST_SUITE(cxx11_atomic_class) - CPPUNIT_TEST( test_atomic_flag ) - CPPUNIT_TEST( test_atomic_flag_volatile ) - - CPPUNIT_TEST( test_atomic_bool ) - CPPUNIT_TEST( test_atomic_char ) - CPPUNIT_TEST( test_atomic_signed_char) - CPPUNIT_TEST( test_atomic_unsigned_char) - CPPUNIT_TEST( test_atomic_short_int) - CPPUNIT_TEST( test_atomic_unsigned_short_int) - CPPUNIT_TEST( test_atomic_int) - CPPUNIT_TEST( test_atomic_unsigned_int) - CPPUNIT_TEST( test_atomic_long) - CPPUNIT_TEST( test_atomic_unsigned_long) - CPPUNIT_TEST( test_atomic_long_long) - CPPUNIT_TEST( test_atomic_unsigned_long_long) - - CPPUNIT_TEST( test_atomic_bool_volatile ) - CPPUNIT_TEST( test_atomic_char_volatile ) - CPPUNIT_TEST( test_atomic_signed_char_volatile) - CPPUNIT_TEST( test_atomic_unsigned_char_volatile) - CPPUNIT_TEST( test_atomic_short_int_volatile) - CPPUNIT_TEST( test_atomic_unsigned_short_int_volatile) - CPPUNIT_TEST( test_atomic_int_volatile) - CPPUNIT_TEST( test_atomic_unsigned_int_volatile) - CPPUNIT_TEST( test_atomic_long_volatile) - CPPUNIT_TEST( test_atomic_unsigned_long_volatile) - CPPUNIT_TEST( test_atomic_long_long_volatile) - CPPUNIT_TEST( test_atomic_unsigned_long_long_volatile) - - CPPUNIT_TEST( test_atomic_pointer_void) - CPPUNIT_TEST( test_atomic_pointer_void_volatile) - - CPPUNIT_TEST( test_atomic_pointer_char) - CPPUNIT_TEST( test_atomic_pointer_short) - CPPUNIT_TEST( test_atomic_pointer_int) - CPPUNIT_TEST( test_atomic_pointer_long) - CPPUNIT_TEST( test_atomic_pointer_long_long) - - CPPUNIT_TEST( test_atomic_pointer_char_volatile) - CPPUNIT_TEST( test_atomic_pointer_short_volatile) - CPPUNIT_TEST( test_atomic_pointer_int_volatile) - CPPUNIT_TEST( test_atomic_pointer_long_volatile) - CPPUNIT_TEST( test_atomic_pointer_long_long_volatile) - - CPPUNIT_TEST_SUITE_END() - }; -} // namespace misc - -CPPUNIT_TEST_SUITE_REGISTRATION(misc::cxx11_atomic_class); diff --git a/tests/test-hdr/misc/cxx11_atomic_func.cpp b/tests/test-hdr/misc/cxx11_atomic_func.cpp deleted file mode 100644 index 4aeacd5e..00000000 --- a/tests/test-hdr/misc/cxx11_atomic_func.cpp +++ /dev/null @@ -1,739 +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 "cppunit/cppunit_proxy.h" - -#include - -#ifndef CDS_USE_BOOST_ATOMIC -// Skip this test for boost.atomic -// Boost.atomic has no free atomic functions implementation. - -#include "misc/cxx11_convert_memory_order.h" - -namespace misc { - - class cxx11_atomic_func: public CppUnitMini::TestCase - { - template - void do_test_atomic_flag_mo( AtomicFlag& f, atomics::memory_order order ) - { - atomics::memory_order mo_clear = convert_to_store_order(order); - - f.clear( convert_to_store_order(order) ); - - for ( int i = 0; i < 5; ++i ) { - CPPUNIT_ASSERT( !atomics::atomic_flag_test_and_set_explicit( &f, order )); - CPPUNIT_ASSERT( atomics::atomic_flag_test_and_set_explicit( &f, order ) ); - atomics::atomic_flag_clear_explicit( &f, mo_clear ); - atomics::atomic_flag_clear_explicit( &f, mo_clear ); - } - //CPPUNIT_ASSERT( f.m_Flag == 0 ); - } - - template - void do_test_atomic_flag( AtomicFlag& f ) - { - f.clear(); - - for ( int i = 0; i < 5; ++i ) { - //CPPUNIT_ASSERT( f.m_Flag == 0 ); - CPPUNIT_ASSERT( !atomics::atomic_flag_test_and_set( &f )); - //CPPUNIT_ASSERT( f.m_Flag != 0 ); - CPPUNIT_ASSERT( atomics::atomic_flag_test_and_set( &f ) ); - //CPPUNIT_ASSERT( f.m_Flag != 0 ); - atomics::atomic_flag_clear(&f); - //CPPUNIT_ASSERT( f.m_Flag == 0 ); - atomics::atomic_flag_clear(&f); - } - //CPPUNIT_ASSERT( f.m_Flag == 0 ); - - do_test_atomic_flag_mo( f, atomics::memory_order_relaxed ); - //do_test_atomic_flag_mo( f, atomics::memory_order_consume ); - do_test_atomic_flag_mo( f, atomics::memory_order_acquire ); - do_test_atomic_flag_mo( f, atomics::memory_order_release ); - do_test_atomic_flag_mo( f, atomics::memory_order_acq_rel ); - do_test_atomic_flag_mo( f, atomics::memory_order_seq_cst ); - } - - template - void do_test_atomic_type(Atomic& a ) - { - typedef Integral integral_type; - - CPPUNIT_ASSERT( atomics::atomic_is_lock_free( &a ) ); - atomics::atomic_store( &a, (integral_type) 0 ); - CPPUNIT_ASSERT( a == 0 ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == 0 ); - - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, n ) == 0 ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == n ); - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, (integral_type) 0 ) == n ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == 0 ); - } - - integral_type prev = atomics::atomic_load( &a ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak( &a, &expected, n)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( expected != n ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak( &a, &expected, n) ); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == n ); - } - - atomics::atomic_store( &a, (integral_type) 0 ); - - prev = atomics::atomic_load( &a ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong( &a, &expected, n)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong( &a, &expected, n)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == n ); - } - - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, (integral_type) 0 ) == prev ); - } - - template - void do_test_atomic_integral( Atomic& a ) - { - do_test_atomic_type< Atomic, Integral >( a ); - - typedef Integral integral_type; - - // fetch_xxx testing - atomics::atomic_store( &a, (integral_type) 0 ); - - // fetch_add - for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) - { - integral_type prev = atomics::atomic_load( &a ); - integral_type n = integral_type(42) << (nByte * 8); - - CPPUNIT_ASSERT( atomics::atomic_fetch_add( &a, n) == prev); - } - - // fetch_sub - for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) - { - integral_type prev = atomics::atomic_load( &a ); - integral_type n = integral_type(42) << ((nByte - 1) * 8); - - CPPUNIT_ASSERT( atomics::atomic_fetch_sub( &a, n) == prev); - } - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == 0 ); - - // fetch_or / fetc_xor / fetch_and - for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) - { - integral_type prev = atomics::atomic_load( &a ); - integral_type mask = 1 << nBit; - - CPPUNIT_ASSERT( atomics::atomic_fetch_or( &a, mask ) == prev ); - prev = atomics::atomic_load( &a ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - - CPPUNIT_ASSERT( atomics::atomic_fetch_and( &a, (integral_type) ~mask ) == prev ); - prev = atomics::atomic_load( &a ); - CPPUNIT_ASSERT_EX( integral_type(prev & mask) == integral_type(0), "prev=" << std::hex << prev << ", mask=" << std::hex << mask); - - CPPUNIT_ASSERT( atomics::atomic_fetch_xor( &a, mask ) == prev ); - prev = atomics::atomic_load( &a ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - } - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == (integral_type) -1 ); - } - - template - void do_test_atomic_type( Atomic& a, atomics::memory_order order ) - { - typedef Integral integral_type; - - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - - CPPUNIT_ASSERT( atomics::atomic_is_lock_free( &a ) ); - atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); - CPPUNIT_ASSERT( a == 0 ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == 0 ); - - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, n, order ) == 0 ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == n ); - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, (integral_type) 0, order ) == n ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == 0 ); - } - - integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == n ); - } - - atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); - - prev = atomics::atomic_load_explicit( &a, oLoad ); - for ( size_t nByte = 0; nByte < sizeof(Integral); ++nByte ) { - integral_type n = integral_type(42) << (nByte * 8); - integral_type expected = prev; - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == prev ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong_explicit( &a, &expected, n, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == n ); - - prev = n; - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == n ); - } - - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, (integral_type) 0, order ) == prev ); - } - - template - void do_test_atomic_integral( Atomic& a, atomics::memory_order order ) - { - do_test_atomic_type< Atomic, Integral >( a, order ); - typedef Integral integral_type; - - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - - // fetch_xxx testing - atomics::atomic_store_explicit( &a, (integral_type) 0, oStore ); - - // fetch_add - for ( size_t nByte = 0; nByte < sizeof(integral_type); ++nByte ) - { - integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); - integral_type n = integral_type(42) << (nByte * 8); - - CPPUNIT_ASSERT( atomics::atomic_fetch_add_explicit( &a, n, order) == prev); - } - - // fetch_sub - for ( size_t nByte = sizeof(integral_type); nByte > 0; --nByte ) - { - integral_type prev = atomics::atomic_load_explicit( &a, oLoad ); - integral_type n = integral_type(42) << ((nByte - 1) * 8); - - CPPUNIT_ASSERT( atomics::atomic_fetch_sub_explicit( &a, n, order ) == prev); - } - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == 0 ); - - // fetch_or / fetc_xor / fetch_and - for ( size_t nBit = 0; nBit < sizeof(integral_type) * 8; ++nBit ) - { - integral_type prev = atomics::atomic_load_explicit( &a, oLoad ) ;; - integral_type mask = 1 << nBit; - - CPPUNIT_ASSERT( atomics::atomic_fetch_or_explicit( &a, mask, order ) == prev ); - prev = atomics::atomic_load_explicit( &a, oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - - CPPUNIT_ASSERT( atomics::atomic_fetch_and_explicit( &a, (integral_type) ~mask, order ) == prev ); - prev = atomics::atomic_load_explicit( &a, oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == 0); - - CPPUNIT_ASSERT( atomics::atomic_fetch_xor_explicit( &a, mask, order ) == prev ); - prev = atomics::atomic_load_explicit( &a, oLoad ); - CPPUNIT_ASSERT( ( prev & mask) == mask); - } - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == (integral_type) -1 ); - } - - template - void test_atomic_integral_(Atomic& a) - { - do_test_atomic_integral(a); - - do_test_atomic_integral( a, atomics::memory_order_relaxed ); - //do_test_atomic_integral( a, atomics::memory_order_consume ); - do_test_atomic_integral( a, atomics::memory_order_acquire ); - do_test_atomic_integral( a, atomics::memory_order_release ); - do_test_atomic_integral( a, atomics::memory_order_acq_rel ); - do_test_atomic_integral( a, atomics::memory_order_seq_cst ); - } - - template - void test_atomic_integral() - { - typedef atomics::atomic atomic_type; - atomic_type a[8]; - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - test_atomic_integral_( a[i] ); - } - } - template - void test_atomic_integral_volatile() - { - typedef atomics::atomic volatile atomic_type; - atomic_type a[8]; - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - test_atomic_integral_( a[i] ); - } - } - - template - void do_test_atomic_bool(AtomicBool& a) - { - CPPUNIT_ASSERT( atomics::atomic_is_lock_free( &a ) ); - atomics::atomic_store( &a, false ); - CPPUNIT_ASSERT( a == false ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == false ); - - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, true ) == false ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == true ); - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, false ) == true ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == false ); - - bool expected = false; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak( &a, &expected, true)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak( &a, &expected, false)); - CPPUNIT_ASSERT( expected == true ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == true ); - - atomics::atomic_store( &a, false ); - - expected = false; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong( &a, &expected, true)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong( &a, &expected, false)); - CPPUNIT_ASSERT( expected == true ); - - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == true ); - - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, false ) == true ); - } - - template - void do_test_atomic_bool( AtomicBool& a, atomics::memory_order order ) - { - const atomics::memory_order oLoad = convert_to_load_order( order ); - const atomics::memory_order oStore = convert_to_store_order( order ); - const atomics::memory_order oExchange = convert_to_exchange_order( order ); - - CPPUNIT_ASSERT( atomics::atomic_is_lock_free( &a ) ); - atomics::atomic_store_explicit( &a, false, oStore ); - CPPUNIT_ASSERT( a == false ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == false ); - - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, true, oExchange ) == false ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == true ); - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, false, oExchange ) == true ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == false ); - - bool expected = false; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak_explicit( &a, &expected, true, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak_explicit( &a, &expected, false, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == true ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == true ); - - atomics::atomic_store( &a, false ); - - expected = false; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong_explicit( &a, &expected, true, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == false ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong_explicit( &a, &expected, false, order, atomics::memory_order_relaxed)); - CPPUNIT_ASSERT( expected == true ); - - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == true ); - - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, false, oExchange ) == true ); - } - - template - void test_atomic_pointer_for_( Atomic& a, Integral * arr, Integral aSize, atomics::memory_order order ) - { - typedef Integral integral_type; - atomics::memory_order oLoad = convert_to_load_order(order); - atomics::memory_order oStore = convert_to_store_order(order); - integral_type * p; - - atomics::atomic_store_explicit( &a, arr, oStore ); - CPPUNIT_ASSERT( *atomics::atomic_load_explicit( &a, oLoad ) == 1 ); - - p = arr; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak_explicit( &a, &p, arr + 5, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( *p == 1 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak_explicit( &a, &p, arr + 3, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong_explicit( &a, &p, arr + 3, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong_explicit( &a, &p, arr + 5, order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 3 ); - CPPUNIT_ASSERT( *p == 4 ); - - CPPUNIT_ASSERT( atomics::atomic_exchange_explicit( &a, arr, order ) == arr + 3 ); - CPPUNIT_ASSERT( atomics::atomic_load_explicit( &a, oLoad ) == arr ); - CPPUNIT_ASSERT( *atomics::atomic_load_explicit( &a, oLoad ) == 1 ); - - for ( integral_type i = 1; i < aSize; ++i ) { - integral_type * p = atomics::atomic_load_explicit( &a, oLoad ); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_add_explicit( &a, 1, order ) == p ); - CPPUNIT_ASSERT( *atomics::atomic_load_explicit( &a, oLoad ) == i + 1 ); - } - - for ( integral_type i = aSize; i > 1; --i ) { - integral_type * p = atomics::atomic_load_explicit( &a, oLoad ); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_sub_explicit( &a, 1, order ) == p ); - CPPUNIT_ASSERT( *atomics::atomic_load_explicit( &a, oLoad ) == i - 1 ); - } - } - - template - void test_atomic_pointer_for() - { - typedef Integral integral_type; - typedef typename add_volatile, Volatile>::type atomic_pointer; - - integral_type arr[8]; - const integral_type aSize = sizeof(arr)/sizeof(arr[0]); - for ( integral_type i = 0; i < aSize; ++i ) { - arr[size_t(i)] = i + 1; - } - - atomic_pointer a; - integral_type * p; - - atomics::atomic_store( &a, arr ); - CPPUNIT_ASSERT( *atomics::atomic_load( &a ) == 1 ); - - p = arr; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak( &a, &p, arr + 5 )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak( &a, &p, arr + 3 )); - CPPUNIT_ASSERT( p == arr + 5 ); - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong( &a, &p, arr + 3 )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong( &a, &p, arr + 5 )); - CPPUNIT_ASSERT( p == arr + 3 ); - - CPPUNIT_ASSERT( atomics::atomic_exchange( &a, arr ) == arr + 3 ); - CPPUNIT_ASSERT( atomics::atomic_load( &a ) == arr ); - CPPUNIT_ASSERT( *atomics::atomic_load( &a ) == 1 ); - - for ( integral_type i = 1; i < aSize; ++i ) { - integral_type * p = atomics::atomic_load( &a ); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_add( &a, 1 ) == p ); - CPPUNIT_ASSERT( *atomics::atomic_load( &a ) == i + 1 ); - } - - for ( integral_type i = aSize; i > 1; --i ) { - integral_type * p = atomics::atomic_load( &a ); - CPPUNIT_ASSERT( *p == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_sub( &a, 1 ) == p ); - CPPUNIT_ASSERT( *atomics::atomic_load( &a ) == i - 1 ); - } - - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_relaxed ); - //test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_consume ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acquire ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_release ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_acq_rel ); - test_atomic_pointer_for_( a, arr, aSize, atomics::memory_order_seq_cst ); - - } - - template - void do_test_atomic_pointer_void_( Atomic& a, char * arr, char aSize, atomics::memory_order order ) - { - atomics::memory_order oLoad = convert_to_load_order(order); - atomics::memory_order oStore = convert_to_store_order(order); - char * p; - - atomics::atomic_store_explicit( &a, (void *) arr, oStore ); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == 1 ); - - p = arr; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak_explicit( &a, (void **) &p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( *p == 1 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak_explicit( &a, (void **) &p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong_explicit( &a, (void **) &p, (void *)(arr + 3), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( *p == 6 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong_explicit( &a, (void **) &p, (void *)(arr + 5), order, atomics::memory_order_relaxed )); - CPPUNIT_ASSERT( p == arr + 3 ); - CPPUNIT_ASSERT( *p == 4 ); - - CPPUNIT_ASSERT( reinterpret_cast(atomics::atomic_exchange_explicit( &a, (void *) arr, order )) == arr + 3 ); - CPPUNIT_ASSERT( reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == arr ); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == 1 ); - - for ( char i = 1; i < aSize; ++i ) { - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_add_explicit( &a, 1, order )); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == i + 1 ); - } - - for ( char i = aSize; i > 1; --i ) { - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_sub_explicit( &a, 1, order )); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load_explicit( &a, oLoad )) == i - 1 ); - } - } - - template - void do_test_atomic_pointer_void() - { - typedef typename add_volatile, Volatile>::type atomic_pointer; - - char arr[8]; - const char aSize = sizeof(arr)/sizeof(arr[0]); - for ( char i = 0; i < aSize; ++i ) { - arr[unsigned(i)] = i + 1; - } - - atomic_pointer a; - char * p; - - atomics::atomic_store( &a, (void *) arr ); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == 1 ); - - p = arr; - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_weak( &a, (void **) &p, (void *)(arr + 5) )); - CPPUNIT_ASSERT( p == arr + 0 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_weak( &a, (void **) &p, (void *)(arr + 3) )); - CPPUNIT_ASSERT( p == arr + 5 ); - - CPPUNIT_ASSERT( atomics::atomic_compare_exchange_strong( &a, (void **) &p, (void *)(arr + 3) )); - CPPUNIT_ASSERT( p == arr + 5 ); - CPPUNIT_ASSERT( !atomics::atomic_compare_exchange_strong( &a, (void **) &p, (void *)(arr + 5) )); - CPPUNIT_ASSERT( p == arr + 3 ); - - CPPUNIT_ASSERT( reinterpret_cast( atomics::atomic_exchange( &a, (void *) arr )) == arr + 3 ); - CPPUNIT_ASSERT( reinterpret_cast( atomics::atomic_load( &a )) == arr ); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == 1 ); - - for ( char i = 1; i < aSize; ++i ) { - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_add( &a, 1 )); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == i + 1 ); - } - - for ( char i = aSize; i > 1; --i ) { - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == i ); - CPPUNIT_ASSERT( atomics::atomic_fetch_sub( &a, 1 )); - CPPUNIT_ASSERT( *reinterpret_cast(atomics::atomic_load( &a )) == i - 1 ); - } - - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_relaxed ); - //do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_consume ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acquire ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_release ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_acq_rel ); - do_test_atomic_pointer_void_( a, arr, aSize, atomics::memory_order_seq_cst ); - } - - public: - void test_atomic_flag() - { - atomics::atomic_flag flags[8]; - for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) - do_test_atomic_flag( flags[i] ); - } - void test_atomic_flag_volatile() - { - atomics::atomic_flag volatile flags[8]; - for ( size_t i = 0; i < sizeof(flags)/sizeof(flags[0]); ++i ) - do_test_atomic_flag( flags[i] ); - } - - template - void test_atomic_bool_() - { - AtomicBool a[8]; - for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) { - do_test_atomic_bool( a[i] ); - - do_test_atomic_bool( a[i], atomics::memory_order_relaxed ); - //do_test_atomic_bool( a[i], atomics::memory_order_consume ); - do_test_atomic_bool( a[i], atomics::memory_order_acquire ); - do_test_atomic_bool( a[i], atomics::memory_order_release ); - do_test_atomic_bool( a[i], atomics::memory_order_acq_rel ); - do_test_atomic_bool( a[i], atomics::memory_order_seq_cst ); - } - } - - void test_atomic_bool() - { - test_atomic_bool_ >(); - } - void test_atomic_bool_volatile() - { - test_atomic_bool_ volatile >(); - } - - void test_atomic_char() { test_atomic_integral(); } - void test_atomic_char_volatile() { test_atomic_integral_volatile(); } - void test_atomic_signed_char() { test_atomic_integral(); } - void test_atomic_signed_char_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_char() { test_atomic_integral(); } - void test_atomic_unsigned_char_volatile(){ test_atomic_integral_volatile(); } - void test_atomic_short_int() { test_atomic_integral(); } - void test_atomic_short_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_short_int() { test_atomic_integral(); } - void test_atomic_unsigned_short_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_int() { test_atomic_integral(); } - void test_atomic_int_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_int() { test_atomic_integral(); } - void test_atomic_unsigned_int_volatile(){ test_atomic_integral_volatile(); } - void test_atomic_long() { test_atomic_integral(); } - void test_atomic_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_long() { test_atomic_integral(); } - void test_atomic_unsigned_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_long_long() { test_atomic_integral(); } - void test_atomic_long_long_volatile() { test_atomic_integral_volatile(); } - void test_atomic_unsigned_long_long() { test_atomic_integral(); } - void test_atomic_unsigned_long_long_volatile() { test_atomic_integral_volatile(); } - - void test_atomic_pointer_void() { do_test_atomic_pointer_void() ;} - void test_atomic_pointer_void_volatile(){ do_test_atomic_pointer_void() ;} - - void test_atomic_pointer_char() { test_atomic_pointer_for() ;} - void test_atomic_pointer_short() { test_atomic_pointer_for() ;} - void test_atomic_pointer_int() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_long() { test_atomic_pointer_for() ;} - - void test_atomic_pointer_char_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_short_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_int_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_volatile() { test_atomic_pointer_for() ;} - void test_atomic_pointer_long_long_volatile() { test_atomic_pointer_for() ;} - - void test_atomic_fence() - { - atomics::atomic_thread_fence(atomics::memory_order_relaxed ); - //atomics::atomic_thread_fence(atomics::memory_order_consume ); - atomics::atomic_thread_fence(atomics::memory_order_acquire ); - atomics::atomic_thread_fence(atomics::memory_order_release ); - atomics::atomic_thread_fence(atomics::memory_order_acq_rel ); - atomics::atomic_thread_fence(atomics::memory_order_seq_cst ); - - atomics::atomic_signal_fence(atomics::memory_order_relaxed ); - //atomics::atomic_signal_fence(atomics::memory_order_consume ); - atomics::atomic_signal_fence(atomics::memory_order_acquire ); - atomics::atomic_signal_fence(atomics::memory_order_release ); - atomics::atomic_signal_fence(atomics::memory_order_acq_rel ); - atomics::atomic_signal_fence(atomics::memory_order_seq_cst ); - } - - public: - CPPUNIT_TEST_SUITE(cxx11_atomic_func) - CPPUNIT_TEST( test_atomic_flag ) - CPPUNIT_TEST( test_atomic_flag_volatile ) - - CPPUNIT_TEST( test_atomic_bool ) - CPPUNIT_TEST( test_atomic_char ) - CPPUNIT_TEST( test_atomic_signed_char) - CPPUNIT_TEST( test_atomic_unsigned_char) - CPPUNIT_TEST( test_atomic_short_int) - CPPUNIT_TEST( test_atomic_unsigned_short_int) - CPPUNIT_TEST( test_atomic_int) - CPPUNIT_TEST( test_atomic_unsigned_int) - CPPUNIT_TEST( test_atomic_long) - CPPUNIT_TEST( test_atomic_unsigned_long) - CPPUNIT_TEST( test_atomic_long_long) - CPPUNIT_TEST( test_atomic_unsigned_long_long) - - CPPUNIT_TEST( test_atomic_bool_volatile ) - CPPUNIT_TEST( test_atomic_char_volatile ) - CPPUNIT_TEST( test_atomic_signed_char_volatile) - CPPUNIT_TEST( test_atomic_unsigned_char_volatile) - CPPUNIT_TEST( test_atomic_short_int_volatile) - CPPUNIT_TEST( test_atomic_unsigned_short_int_volatile) - CPPUNIT_TEST( test_atomic_int_volatile) - CPPUNIT_TEST( test_atomic_unsigned_int_volatile) - CPPUNIT_TEST( test_atomic_long_volatile) - CPPUNIT_TEST( test_atomic_unsigned_long_volatile) - CPPUNIT_TEST( test_atomic_long_long_volatile) - CPPUNIT_TEST( test_atomic_unsigned_long_long_volatile) - - CPPUNIT_TEST( test_atomic_pointer_void) - CPPUNIT_TEST( test_atomic_pointer_void_volatile) - - CPPUNIT_TEST( test_atomic_pointer_char) - CPPUNIT_TEST( test_atomic_pointer_short) - CPPUNIT_TEST( test_atomic_pointer_int) - CPPUNIT_TEST( test_atomic_pointer_long) - CPPUNIT_TEST( test_atomic_pointer_long_long) - - CPPUNIT_TEST( test_atomic_pointer_char_volatile) - CPPUNIT_TEST( test_atomic_pointer_short_volatile) - CPPUNIT_TEST( test_atomic_pointer_int_volatile) - CPPUNIT_TEST( test_atomic_pointer_long_volatile) - CPPUNIT_TEST( test_atomic_pointer_long_long_volatile) - - CPPUNIT_TEST( test_atomic_fence) - - CPPUNIT_TEST_SUITE_END() - }; -} // namespace misc - -CPPUNIT_TEST_SUITE_REGISTRATION(misc::cxx11_atomic_func); - -#endif // #ifndef CDS_USE_BOOST_ATOMIC diff --git a/tests/test-hdr/misc/cxx11_convert_memory_order.h b/tests/test-hdr/misc/cxx11_convert_memory_order.h deleted file mode 100644 index 15859c6d..00000000 --- a/tests/test-hdr/misc/cxx11_convert_memory_order.h +++ /dev/null @@ -1,87 +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. -*/ - -// This header should be included AFTER if needed - -namespace misc { - - static inline atomics::memory_order convert_to_store_order( atomics::memory_order order ) - { - switch ( order ) { - case atomics::memory_order_acquire: - case atomics::memory_order_consume: - return atomics::memory_order_relaxed; - case atomics::memory_order_acq_rel: - return atomics::memory_order_release; - default: - return order; - } - } - - static inline atomics::memory_order convert_to_load_order( atomics::memory_order order ) - { - switch ( order ) { - case atomics::memory_order_release: - return atomics::memory_order_relaxed; - case atomics::memory_order_acq_rel: - return atomics::memory_order_acquire; - default: - return order; - } - } - -#if CDS_COMPILER == CDS_COMPILER_INTEL - static inline atomics::memory_order convert_to_exchange_order( atomics::memory_order order ) - { - return order == atomics::memory_order_consume ? atomics::memory_order_relaxed : order; - } -#else - static inline atomics::memory_order convert_to_exchange_order( atomics::memory_order order ) - { - return order; - } -#endif - - template - struct add_volatile; - - template - struct add_volatile - { - typedef T type; - }; - - template - struct add_volatile - { - typedef T volatile type; - }; - -} // namespace misc diff --git a/tests/test-hdr/misc/find_option.cpp b/tests/test-hdr/misc/find_option.cpp deleted file mode 100644 index ad86faab..00000000 --- a/tests/test-hdr/misc/find_option.cpp +++ /dev/null @@ -1,224 +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 - -// Value options -namespace { - - template - struct int_opt { - static const int value = Val; - }; - - template - struct bool_opt { - static const bool value = Val; - }; - - enum user_enum { - val_zero, val_one, val_two, val_three, val_four, val_five - }; - - template - struct enum_opt { - static const user_enum value = Val; - }; -} - -// Declare necessary cds::opt::find_option specialization for user-provided enum type -CDS_DECLARE_FIND_OPTION_INTEGRAL_SPECIALIZATION( user_enum ) - -#if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500 -// GCC 4.4 does not support local struct declarations -namespace { - struct tag_default; - struct tag_a; - struct tag_b; -} -#endif - -void find_option_compiler_test() -{ - - // ************************************************* - // Type options - // -#if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500) - // GCC 4.4 does not support local struct declarations - struct tag_default; - struct tag_a; - struct tag_b; -#endif - - // Option not found - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag, cds::opt::stat, bool_opt >::type, - cds::opt::tag - >::value), "Result != tag_default" ); - - // Option found once - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag, cds::opt::tag >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag, cds::opt::stat, cds::opt::tag >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - // First option - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag - ,cds::opt::tag // desired - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - // Last option - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::tag // desired - >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - // Middle option - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::tag // desired - ,cds::opt::stat - ,cds::opt::stat - >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - // Option not found - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - >::type, - cds::opt::tag - >::value), "Result != tag_default" ); - - // Multiple options - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag, cds::opt::tag, cds::opt::tag >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - static_assert( (std::is_same< - cds::opt::find_option< cds::opt::tag - ,cds::opt::tag // desired - first accepted - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::stat - ,cds::opt::tag // desired - >::type, - cds::opt::tag - >::value), "Result != tag_a" ); - - - - // ***************************************************** - // Value options - - // Not found - static_assert( (std::is_same< - cds::opt::find_option< int_opt<15>, bool_opt, cds::opt::stat >::type, - int_opt<15> - >::value), "Result != int_opt<15>" ); - - static_assert( (std::is_same< - cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat >::type, - int_opt<100> - >::value), "Result != int_opt<100>" ); - - static_assert( (std::is_same< - cds::opt::find_option< int_opt<15>, int_opt<100>, cds::opt::stat, bool_opt, int_opt<200> >::type, - int_opt<100> - >::value), "Result != int_opt<100>" ); - - // User-provided enum type - static_assert( (std::is_same< - cds::opt::find_option< enum_opt, int_opt<100>, cds::opt::stat, int_opt<200> >::type, - enum_opt - >::value), "Result != enum_opt" ); - - static_assert( (std::is_same< - cds::opt::find_option< enum_opt, int_opt<100>, cds::opt::stat, enum_opt, int_opt<200> >::type, - enum_opt - >::value), "Result != enum_opt" ); - -} - -void test_extracting_option_value() -{ -#if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40500) - // GCC 4.4 does not support local struct declarations - struct tag_a; -#endif - // Define option - typedef cds::opt::tag< tag_a > tag_option; - - // What is the value of the tag_option? - // How we can extract tag_a from tag_option? - // Here is a solution: - typedef cds::opt::value< tag_option >::tag tag_option_value; - - // tag_option_value is the same as tag_a - static_assert( (std::is_same< tag_option_value, tag_a >::value), "Error getting the value of option: tag_option_value != tag_a" ); - - // Value-option - typedef cds::opt::alignment< 16 > align_option; - static_assert( cds::opt::value< align_option >::alignment == 16, "Error getting the value of option: option value != 16" ); -} diff --git a/tests/test-hdr/misc/hash_tuple.cpp b/tests/test-hdr/misc/hash_tuple.cpp deleted file mode 100644 index 04545afb..00000000 --- a/tests/test-hdr/misc/hash_tuple.cpp +++ /dev/null @@ -1,159 +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 "cppunit/cppunit_proxy.h" - -namespace misc { - namespace { - typedef cds::opt::v::hash_selector< cds::opt::none >::type hashing; - -#define HASHING(_n) \ - struct hash##_n: public hashing { \ - template size_t operator()( T const& v ) const { return hashing::operator()(v) + _n ; } \ - }; - - HASHING(2) - HASHING(3) - HASHING(4) - HASHING(5) - HASHING(6) - HASHING(7) - HASHING(8) - HASHING(9) - HASHING(10) -#undef HASHING - } - - class HashTuple: public CppUnitMini::TestCase - { - void test() - { - int nVal = 5; - size_t nHash = hashing()(nVal); - - size_t val[16]; - - cds::opt::hash< std::tuple< hashing, hash2 > >::pack::hash h2; - h2( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3 > >::pack::hash h3; - h3( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4 > >::pack::hash h4; - h4( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5 > >::pack::hash h5; - h5( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - -#if !((CDS_COMPILER == CDS_COMPILER_MSVC || (CDS_COMPILER == CDS_COMPILER_INTEL && CDS_OS_INTERFACE == CDS_OSI_WINDOWS)) && _MSC_VER == 1700) - // MS VC 11: std::tuple suports up to 5 template params only - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6 > >::pack::hash h6; - h6( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - CPPUNIT_ASSERT( val[5] == nHash + 6 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7 > >::pack::hash h7; - h7( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - CPPUNIT_ASSERT( val[5] == nHash + 6 ); - CPPUNIT_ASSERT( val[6] == nHash + 7 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8 > >::pack::hash h8; - h8( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - CPPUNIT_ASSERT( val[5] == nHash + 6 ); - CPPUNIT_ASSERT( val[6] == nHash + 7 ); - CPPUNIT_ASSERT( val[7] == nHash + 8 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9 > >::pack::hash h9; - h9( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - CPPUNIT_ASSERT( val[5] == nHash + 6 ); - CPPUNIT_ASSERT( val[6] == nHash + 7 ); - CPPUNIT_ASSERT( val[7] == nHash + 8 ); - CPPUNIT_ASSERT( val[8] == nHash + 9 ); - - cds::opt::hash< std::tuple< hashing, hash2, hash3, hash4, hash5, hash6, hash7, hash8, hash9, hash10 > >::pack::hash h10; - h10( val, nVal ); - CPPUNIT_ASSERT( val[0] == nHash ); - CPPUNIT_ASSERT( val[1] == nHash + 2 ); - CPPUNIT_ASSERT( val[2] == nHash + 3 ); - CPPUNIT_ASSERT( val[3] == nHash + 4 ); - CPPUNIT_ASSERT( val[4] == nHash + 5 ); - CPPUNIT_ASSERT( val[5] == nHash + 6 ); - CPPUNIT_ASSERT( val[6] == nHash + 7 ); - CPPUNIT_ASSERT( val[7] == nHash + 8 ); - CPPUNIT_ASSERT( val[8] == nHash + 9 ); - CPPUNIT_ASSERT( val[9] == nHash + 10 ); -#endif - } - - public: - CPPUNIT_TEST_SUITE(HashTuple) - CPPUNIT_TEST( test ) - CPPUNIT_TEST_SUITE_END() - - }; -} // namespace misc - -CPPUNIT_TEST_SUITE_REGISTRATION(misc::HashTuple); diff --git a/tests/test-hdr/misc/michael_allocator.cpp b/tests/test-hdr/misc/michael_allocator.cpp deleted file mode 100644 index 94553afb..00000000 --- a/tests/test-hdr/misc/michael_allocator.cpp +++ /dev/null @@ -1,36 +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 "misc/michael_allocator.h" - -namespace misc { - t_MichaelHeap_NoStat s_MichaelHeap_NoStat; - t_MichaelHeap_Stat s_MichaelHeap_Stat; -} diff --git a/tests/test-hdr/misc/michael_allocator.h b/tests/test-hdr/misc/michael_allocator.h deleted file mode 100644 index 86c533be..00000000 --- a/tests/test-hdr/misc/michael_allocator.h +++ /dev/null @@ -1,225 +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 - -namespace misc { - namespace ma = cds::memory::michael; - - typedef ma::Heap< - ma::opt::procheap_stat, - ma::opt::os_allocated_stat, - ma::opt::check_bounds - > t_MichaelHeap_NoStat; - - typedef ma::Heap< - ma::opt::procheap_stat, - ma::opt::os_allocated_stat, - ma::opt::check_bounds - > t_MichaelHeap_Stat; - - typedef ma::summary_stat summary_stat; - - extern t_MichaelHeap_NoStat s_MichaelHeap_NoStat; - extern t_MichaelHeap_Stat s_MichaelHeap_Stat; - - template - class MichaelHeap_NoStat - { - public: - typedef T value_type; - typedef T * pointer; - - enum { - alignment = 1 - }; - - - pointer allocate( size_t nSize, const void * /*pHint*/ ) - { - return reinterpret_cast( s_MichaelHeap_NoStat.alloc( sizeof(T) * nSize ) ); - } - - void deallocate( pointer p, size_t /*nCount*/ ) - { - s_MichaelHeap_NoStat.free( p ); - } - - static void stat(summary_stat& s) - { - s_MichaelHeap_NoStat.summaryStat(s); - } - }; - - template - class std_allocator: public std::allocator - { - public: - enum { - alignment = 1 - }; - - static void stat(summary_stat& /*s*/) - {} - }; - - template - class MichaelHeap_Stat - { - public: - typedef T value_type; - typedef T * pointer; - - enum { - alignment = 1 - }; - - pointer allocate( size_t nSize, const void * /*pHint*/ ) - { - return reinterpret_cast( s_MichaelHeap_Stat.alloc( sizeof(T) * nSize ) ); - } - - void deallocate( pointer p, size_t /*nCount*/ ) - { - s_MichaelHeap_Stat.free( p ); - } - - static void stat(summary_stat& s) - { - s_MichaelHeap_Stat.summaryStat(s); - } - }; - - template - class MichaelAlignHeap_NoStat - { - public: - typedef T value_type; - typedef T * pointer; - - enum { - alignment = ALIGN - }; - - pointer allocate( size_t nSize, const void * /*pHint*/ ) - { - return reinterpret_cast( s_MichaelHeap_NoStat.alloc_aligned( sizeof(T) * nSize, ALIGN ) ); - } - - void deallocate( pointer p, size_t /*nCount*/ ) - { - s_MichaelHeap_NoStat.free_aligned( p ); - } - - static void stat(summary_stat& s) - { - s_MichaelHeap_NoStat.summaryStat(s); - } - }; - - template - class MichaelAlignHeap_Stat { - public: - typedef T value_type; - typedef T * pointer; - - enum { - alignment = ALIGN - }; - - pointer allocate( size_t nSize, const void * /*pHint*/ ) - { - return reinterpret_cast( s_MichaelHeap_Stat.alloc_aligned( sizeof(T) * nSize, ALIGN ) ); - } - - void deallocate( pointer p, size_t /*nCount*/ ) - { - s_MichaelHeap_Stat.free_aligned( p ); - } - - static void stat(summary_stat& s) - { - s_MichaelHeap_Stat.summaryStat(s); - } - }; - - template - class system_aligned_allocator - { - public: - typedef T value_type; - typedef T * pointer; - - enum { - alignment = ALIGN - }; - - pointer allocate( size_t nSize, const void * /*pHint*/ ) - { - return reinterpret_cast( cds::OS::aligned_malloc( sizeof(T) * nSize, ALIGN ) ); - } - - void deallocate( pointer p, size_t /*nCount*/ ) - { - cds::OS::aligned_free( p ); - } - - static void stat(summary_stat& /*s*/) - {} - }; - - static inline std::ostream& operator <<(std::ostream& os, const summary_stat& s) - { - os << "\t alloc from active: " << s.nAllocFromActive << "\n" - << "\t alloc from partial: " << s.nAllocFromPartial << "\n" - << "\t alloc from new: " << s.nAllocFromNew << "\n" - << "\t free call count: " << s.nFreeCount << "\n" - << "\t superblock allocated: " << s.nPageAllocCount << "\n" - << "\t superblock deallocated: " << s.nPageDeallocCount << "\n" - << "\t superblock desc allocated: " << s.nDescAllocCount << "\n" - << "\t superblock full desc: " << s.nDescFull << "\n" - << "\t total allocated bytes: " << s.nBytesAllocated << "\n" - << "\t total deallocated bytes: " << s.nBytesDeallocated << "\n" - << "\tOS-allocated large blocks\n" - << "\t alloc call count: " << s.nSysAllocCount << "\n" - << "\t free call count: " << s.nSysFreeCount << "\n" - << "\t total allocated bytes: " << s.nSysBytesAllocated << "\n" - << "\t total deallocated bytes: " << s.nSysBytesDeallocated << "\n" - << "\tCAS contention indicators\n" - << "\t updating active field of active block: " << s.nActiveDescCASFailureCount << "\n" - << "\t updating anchor field of active block: " << s.nActiveAnchorCASFailureCount << "\n" - << "\tupdating active field of partial block: " << s.nPartialDescCASFailureCount << "\n" - << "\tupdating anchor field of partial block: " << s.nPartialAnchorCASFailureCount - << std::endl; - - return os; - } -} diff --git a/tests/test-hdr/misc/permutation_generator.cpp b/tests/test-hdr/misc/permutation_generator.cpp deleted file mode 100644 index 86dc207c..00000000 --- a/tests/test-hdr/misc/permutation_generator.cpp +++ /dev/null @@ -1,105 +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 "cppunit/cppunit_proxy.h" - -namespace misc { - - class Permutations: public CppUnitMini::TestCase - { - static const size_t c_nMax = 1024; - - template - void test_with( Gen& gen, size_t nLen ) - { - unsigned int arr[c_nMax]; - for ( size_t nPass = 0; nPass < 10; ++nPass ) { - for ( size_t i = 0; i < c_nMax; ++i ) - arr[i] = 0; - - do { - typename Gen::integer_type i = gen; - ++arr[ i ]; - } while ( gen.next() ); - - for ( size_t i = 0; i < nLen; ++i ) - CPPUNIT_CHECK_EX( arr[i] == 1, "arr[" << i << "]=" << arr[i] ); - for ( size_t i = nLen; i < c_nMax; ++i ) - CPPUNIT_CHECK_EX( arr[i] == 0, "arr[" << i << "]=" << arr[i] ); - - gen.reset(); - } - } - - template - void test() - { - for ( size_t nLen = 2; nLen <= c_nMax; ++nLen ) { - Gen gen( nLen ); - test_with( gen, nLen ); - } - } - - template - void test2() - { - for ( size_t nLen = 2; nLen <= c_nMax; nLen *= 2 ) { - Gen gen( nLen ); - test_with( gen, nLen ); - } - } - - void test_random_permutation() - { - test< cds::opt::v::random_permutation<> >(); - } - - void test_random2_permutation() - { - test2< cds::opt::v::random2_permutation<> >(); - } - - void test_random_shuffle_permutation() - { - test< cds::opt::v::random_shuffle_permutation<> >(); - } - - public: - CPPUNIT_TEST_SUITE(Permutations) - CPPUNIT_TEST( test_random_permutation ) - CPPUNIT_TEST( test_random2_permutation ) - CPPUNIT_TEST( test_random_shuffle_permutation ) - CPPUNIT_TEST_SUITE_END() - }; - -} // namespace misc - -CPPUNIT_TEST_SUITE_REGISTRATION(misc::Permutations); diff --git a/tests/test-hdr/misc/split_bitstring.cpp b/tests/test-hdr/misc/split_bitstring.cpp deleted file mode 100644 index f71af5e8..00000000 --- a/tests/test-hdr/misc/split_bitstring.cpp +++ /dev/null @@ -1,333 +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 "cppunit/cppunit_proxy.h" - -#include - -class Split_bitstrig : public CppUnitMini::TestCase -{ -private: - bool is_big_endian() - { - union { - uint32_t ui; - uint8_t ch; - } byte_order; - byte_order.ui = 0xFF000001; - - return byte_order.ch != 0x01; - } -protected: - - void cut_uint() - { - if ( is_big_endian() ) - cut_uint_be(); - else - cut_uint_le(); - } - - void cut_uint16() - { - if ( is_big_endian() ) - cut_small_be(); - else - cut_small_le(); - } - - void cut_uint_le() - { - CPPUNIT_MSG("little-endian byte order"); - - typedef cds::algo::split_bitstring< size_t > split_bitstring; - - size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210; - split_bitstring splitter(src); - size_t res; - - // Trivial case - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = splitter.cut(sizeof(src) * 8); - CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - splitter.reset(); - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = splitter.cut(sizeof(src) * 8); - CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // Cut each hex digit - splitter.reset(); - for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - CPPUNIT_ASSERT( splitter.cut( 4 ) == i ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // by one bit - { - splitter.reset(); - res = 0; - for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = res + (splitter.cut( 1 ) << i); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - - // random cut - { - for ( size_t k = 0; k < 100; ++k ) { - splitter.reset(); - res = 0; - size_t shift = 0; - while ( splitter ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - int bits = rand() % 16; - res = res + ( splitter.safe_cut( bits ) << shift ); - shift += bits; - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - } - } - - void cut_uint_be() - { - CPPUNIT_MSG("big-endian byte order"); - - typedef cds::algo::split_bitstring< size_t > split_bitstring; - - size_t src = sizeof(src) == 8 ? 0xFEDCBA9876543210 : 0x76543210; - split_bitstring splitter(src); - size_t res; - - // Trivial case - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = splitter.cut(sizeof(src) * 8); - CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - splitter.reset(); - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = splitter.cut(sizeof(src) * 8); - CPPUNIT_ASSERT_EX( res == src, "src=" << src << ", result=" << res ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT(splitter.safe_cut(sizeof(src) * 8) == 0 ); - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // Cut each hex digit - splitter.reset(); - for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // by one bit - { - splitter.reset(); - res = 0; - for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = (res << 1) + splitter.cut( 1 ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - - // random cut - { - for ( size_t k = 0; k < 100; ++k ) { - splitter.reset(); - res = 0; - while ( splitter ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - int bits = rand() % 16; - res = (res << bits) + splitter.safe_cut( bits ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - } - } - - -private: - template - void cut_small_le() - { - CPPUNIT_MSG("little-endian byte order"); - typedef PartUInt part_uint; - - typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; - - uint64_t src = 0xFEDCBA9876543210; - split_bitstring splitter(src); - uint64_t res; - - // Cut each hex digit - splitter.reset(); - for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - CPPUNIT_ASSERT( static_cast(splitter.cut( 4 )) == i ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // by one bit - { - splitter.reset(); - res = 0; - for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = res + ( static_cast(splitter.cut( 1 )) << i); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - - // random cut - { - for ( size_t k = 0; k < 100; ++k ) { - splitter.reset(); - res = 0; - size_t shift = 0; - while ( splitter ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - int bits = rand() % 16; - res = res + ( static_cast(splitter.safe_cut( bits )) << shift ); - shift += bits; - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - } - } - - template - void cut_small_be() - { - CPPUNIT_MSG("big-endian byte order"); - typedef PartUInt part_uint; - - typedef cds::algo::split_bitstring< uint64_t, part_uint > split_bitstring; - - uint64_t src = 0xFEDCBA9876543210; - split_bitstring splitter(src); - uint64_t res; - - // Cut each hex digit - splitter.reset(); - for ( size_t i = 0; i < sizeof(size_t) * 2; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - CPPUNIT_ASSERT( splitter.cut( 4 ) == 0x0F - i ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - - // by one bit - { - splitter.reset(); - res = 0; - for ( size_t i = 0; i < sizeof(size_t) * 8; ++i ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - res = (res << 1) + splitter.cut( 1 ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - - // random cut - { - for ( size_t k = 0; k < 100; ++k ) { - splitter.reset(); - res = 0; - while ( splitter ) { - CPPUNIT_ASSERT( !splitter.eos() ); - CPPUNIT_ASSERT( splitter ); - int bits = rand() % 16; - res = (res << bits) + splitter.safe_cut( bits ); - } - CPPUNIT_ASSERT( splitter.eos() ); - CPPUNIT_ASSERT( !splitter ); - CPPUNIT_ASSERT( res == src ); - } - } - } - - - CPPUNIT_TEST_SUITE(Split_bitstrig); - CPPUNIT_TEST(cut_uint) - CPPUNIT_TEST(cut_uint16) - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(Split_bitstrig); diff --git a/tests/test-hdr/misc/thread_init_fini.cpp b/tests/test-hdr/misc/thread_init_fini.cpp deleted file mode 100644 index bdc302a7..00000000 --- a/tests/test-hdr/misc/thread_init_fini.cpp +++ /dev/null @@ -1,105 +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 "cppunit/thread.h" -#include - -namespace { - static size_t s_nThreadCount = 8; - static size_t s_nPassCount = 1000000; -} - -class thread_init_fini: public CppUnitMini::TestCase -{ - class Thread: public CppUnitMini::TestThread - { - virtual TestThread * clone() - { - return new Thread( *this ); - } - - public: - Thread( CppUnitMini::ThreadPool& pool ) - : CppUnitMini::TestThread( pool ) - {} - Thread( Thread& src ) - : CppUnitMini::TestThread( src ) - {} - - thread_init_fini& getTest() - { - return reinterpret_cast( m_Pool.m_Test ); - } - - virtual void init() - {} - virtual void fini() - {} - - virtual void test() - { - for ( size_t i = 0; i < s_nPassCount; ++i ) { - CPPUNIT_ASSERT(!cds::threading::Manager::isThreadAttached()); - if ( !cds::threading::Manager::isThreadAttached() ) - cds::threading::Manager::attachThread(); - CPPUNIT_ASSERT( cds::threading::Manager::isThreadAttached() ); - cds::threading::Manager::detachThread(); - } - } - }; - -protected: - void init_fini() - { - CPPUNIT_MSG( "Thread init/fini test,\n thread count=" << s_nThreadCount << " pass count=" << s_nPassCount << "..." ); - - CppUnitMini::ThreadPool pool( *this ); - - pool.add( new Thread( pool ), s_nThreadCount ); - - cds::OS::Timer timer; - timer.reset(); - - pool.run(); - - CPPUNIT_MSG( " Duration=" << timer.duration() ); - } - - void setUpParams( const CppUnitMini::TestCfg& cfg ) { - s_nThreadCount = cfg.getULong("ThreadCount", 8 ); - s_nPassCount = cfg.getULong("PassCount", 1000000 ); - } - - CPPUNIT_TEST_SUITE(thread_init_fini) - CPPUNIT_TEST(init_fini); - CPPUNIT_TEST_SUITE_END(); -}; - -CPPUNIT_TEST_SUITE_REGISTRATION(thread_init_fini); diff --git a/tests/test-hdr/size_check.h b/tests/test-hdr/size_check.h deleted file mode 100644 index feca79bd..00000000 --- a/tests/test-hdr/size_check.h +++ /dev/null @@ -1,64 +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 CDSTEST_SIZE_CHECK_H -#define CDSTEST_SIZE_CHECK_H - -#include - -namespace misc { - - template - struct size_checker { - template - bool operator()( Container const& c, size_t nSize ) const - { - return c.size() == nSize; - } - }; - - template<> - struct size_checker< cds::atomicity::empty_item_counter > { - template - bool operator()( Container const& /*c*/, size_t /*nSize*/ ) const - { - return true; - } - }; - - template - static inline bool check_size( Container const& cont, size_t nSize ) - { - return size_checker()( cont, nSize ); - } - -} // namespace misc - -#endif // #ifndef CDSTEST_SIZE_CHECK_H