{408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
EndProjectSection\r
EndProject\r
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "single-threaded test", "single-threaded test", "{B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75}"\r
- ProjectSection(SolutionItems) = preProject\r
- ..\..\..\tests\test-hdr\size_check.h = ..\..\..\tests\test-hdr\size_check.h\r
- EndProjectSection\r
-EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hdr-test-misc", "hdr-test-misc.vcxproj", "{C5E76975-B87B-4B9E-8596-B01DDA683FCA}"\r
- ProjectSection(ProjectDependencies) = postProject\r
- {61179F2F-07E1-490D-B64D-D85A90B6EF81} = {61179F2F-07E1-490D-B64D-D85A90B6EF81}\r
- {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
- EndProjectSection\r
-EndProject\r
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "map", "map", "{6BB7A27F-FC59-4267-B6FA-D034176D1459}"\r
ProjectSection(SolutionItems) = preProject\r
..\..\..\tests\unit\map2\map_defs.h = ..\..\..\tests\unit\map2\map_defs.h\r
{408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
EndProjectSection\r
EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gtest-misc", "gtest-misc.vcxproj", "{FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}"\r
+ ProjectSection(ProjectDependencies) = postProject\r
+ {408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
+ EndProjectSection\r
+EndProject\r
Global\r
GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
Debug|Win32 = Debug|Win32\r
{77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|Win32.Build.0 = Release|Win32\r
{77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|x64.ActiveCfg = Release|x64\r
{77350FDC-9E51-438B-9A8F-D2FEA11D46B2}.Release|x64.Build.0 = Release|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|Win32.ActiveCfg = Debug|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|Win32.Build.0 = Debug|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|x64.ActiveCfg = Debug|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Debug|x64.Build.0 = Debug|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|Win32.Build.0 = DebugVLD|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|x64.ActiveCfg = DebugVLD|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.DebugVLD|x64.Build.0 = DebugVLD|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|Win32.ActiveCfg = Release|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|Win32.Build.0 = Release|Win32\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|x64.ActiveCfg = Release|x64\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA}.Release|x64.Build.0 = Release|x64\r
{3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|Win32.ActiveCfg = Debug|Win32\r
{3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|Win32.Build.0 = Debug|Win32\r
{3C598F96-FB84-4D42-9B43-F697F53B0221}.Debug|x64.ActiveCfg = Debug|x64\r
{2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|Win32.Build.0 = Release|Win32\r
{2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|x64.ActiveCfg = Release|x64\r
{2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB}.Release|x64.Build.0 = Release|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|Win32.Build.0 = Debug|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|x64.ActiveCfg = Debug|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Debug|x64.Build.0 = Debug|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|Win32.Build.0 = DebugVLD|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|x64.ActiveCfg = DebugVLD|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.DebugVLD|x64.Build.0 = DebugVLD|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|Win32.ActiveCfg = Release|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|Win32.Build.0 = Release|Win32\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|x64.ActiveCfg = Release|x64\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06}.Release|x64.Build.0 = Release|x64\r
EndGlobalSection\r
GlobalSection(SolutionProperties) = preSolution\r
HideSolutionNode = FALSE\r
GlobalSection(NestedProjects) = preSolution\r
{61179F2F-07E1-490D-B64D-D85A90B6EF81} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
{77350FDC-9E51-438B-9A8F-D2FEA11D46B2} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
- {C5E76975-B87B-4B9E-8596-B01DDA683FCA} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75}\r
{6BB7A27F-FC59-4267-B6FA-D034176D1459} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
{A64449B7-90FB-4E2B-A686-9EFC0E298644} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
{3C598F96-FB84-4D42-9B43-F697F53B0221} = {6BB7A27F-FC59-4267-B6FA-D034176D1459}\r
{42B7E892-DDDA-4D00-9AB7-378E0E7E9433} = {810490B7-31E5-49AE-8455-CAF99A9658B6}\r
{00FD5CB8-E1A4-40CA-B613-30A06A75622B} = {810490B7-31E5-49AE-8455-CAF99A9658B6}\r
{2ABD6A2E-BEA7-4C8C-982B-A609F83D2DCB} = {810490B7-31E5-49AE-8455-CAF99A9658B6}\r
+ {FA22E700-1AE5-4D7B-B9F1-0A919FF7FF06} = {810490B7-31E5-49AE-8455-CAF99A9658B6}\r
EndGlobalSection\r
GlobalSection(DPCodeReviewSolutionGUID) = preSolution\r
DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup Label="ProjectConfigurations">
+ <ProjectConfiguration Include="DebugVLD|Win32">
+ <Configuration>DebugVLD</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="DebugVLD|x64">
+ <Configuration>DebugVLD</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|Win32">
+ <Configuration>Debug</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|Win32">
+ <Configuration>Release</Configuration>
+ <Platform>Win32</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Debug|x64">
+ <Configuration>Debug</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ <ProjectConfiguration Include="Release|x64">
+ <Configuration>Release</Configuration>
+ <Platform>x64</Platform>
+ </ProjectConfiguration>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\test\unit\main.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\bitop.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\cxx11_atomic_class.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\cxx11_atomic_func.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\find_option.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\hash_tuple.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\permutation_generator.cpp" />
+ <ClCompile Include="..\..\..\test\unit\misc\split_bitstring.cpp" />
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\test\unit\misc\cxx11_convert_memory_order.h" />
+ </ItemGroup>
+ <PropertyGroup Label="Globals">
+ <ProjectGuid>{FA22E700-1AE5-4d7b-B9F1-0A919FF7FF06}</ProjectGuid>
+ <Keyword>Win32Proj</Keyword>
+ <RootNamespace>misc</RootNamespace>
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>true</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+ <ConfigurationType>Application</ConfigurationType>
+ <UseDebugLibraries>false</UseDebugLibraries>
+ <PlatformToolset>v140</PlatformToolset>
+ <WholeProgramOptimization>true</WholeProgramOptimization>
+ <CharacterSet>Unicode</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+ <ImportGroup Label="ExtensionSettings">
+ </ImportGroup>
+ <ImportGroup Label="Shared">
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="PropertySheets">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+ </ImportGroup>
+ <PropertyGroup Label="UserMacros" />
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ <TargetName>$(ProjectName)_d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ <TargetName>$(ProjectName)_d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ <TargetName>$(ProjectName)_d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+ <LinkIncremental>true</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ <TargetName>$(ProjectName)_d</TargetName>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <LinkIncremental>false</LinkIncremental>
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
+ </PropertyGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">
+ <ClCompile>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <WarningLevel>Level3</WarningLevel>
+ <Optimization>Disabled</Optimization>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtestd.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+ <ClCompile>
+ <WarningLevel>Level3</WarningLevel>
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>
+ <Optimization>MaxSpeed</Optimization>
+ <FunctionLevelLinking>true</FunctionLevelLinking>
+ <IntrinsicFunctions>true</IntrinsicFunctions>
+ <PreprocessorDefinitions>_ENABLE_ATOMIC_ALIGNMENT_FIX;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+ </ClCompile>
+ <Link>
+ <SubSystem>Console</SubSystem>
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>
+ <OptimizeReferences>true</OptimizeReferences>
+ <GenerateDebugInformation>true</GenerateDebugInformation>
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>
+ <AdditionalDependencies>gtest.lib;%(AdditionalDependencies)</AdditionalDependencies>
+ </Link>
+ </ItemDefinitionGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+ <ImportGroup Label="ExtensionTargets">
+ </ImportGroup>
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <ItemGroup>
+ <Filter Include="Source Files">
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+ </Filter>
+ <Filter Include="Header Files">
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
+ </Filter>
+ <Filter Include="Resource Files">
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+ </Filter>
+ </ItemGroup>
+ <ItemGroup>
+ <ClCompile Include="..\..\..\test\unit\main.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\bitop.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\cxx11_atomic_class.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\cxx11_atomic_func.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\find_option.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\hash_tuple.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\permutation_generator.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ <ClCompile Include="..\..\..\test\unit\misc\split_bitstring.cpp">
+ <Filter>Source Files</Filter>
+ </ClCompile>
+ </ItemGroup>
+ <ItemGroup>
+ <ClInclude Include="..\..\..\test\unit\misc\cxx11_convert_memory_order.h">
+ <Filter>Header Files</Filter>
+ </ClInclude>
+ </ItemGroup>
+</Project>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
- <ItemGroup Label="ProjectConfigurations">\r
- <ProjectConfiguration Include="DebugVLD|Win32">\r
- <Configuration>DebugVLD</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="DebugVLD|x64">\r
- <Configuration>DebugVLD</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Debug|Win32">\r
- <Configuration>Debug</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Debug|x64">\r
- <Configuration>Debug</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Release|Win32">\r
- <Configuration>Release</Configuration>\r
- <Platform>Win32</Platform>\r
- </ProjectConfiguration>\r
- <ProjectConfiguration Include="Release|x64">\r
- <Configuration>Release</Configuration>\r
- <Platform>x64</Platform>\r
- </ProjectConfiguration>\r
- </ItemGroup>\r
- <PropertyGroup Label="Globals">\r
- <ProjectGuid>{C5E76975-B87B-4B9E-8596-B01DDA683FCA}</ProjectGuid>\r
- <RootNamespace>hdrtestmisc</RootNamespace>\r
- <Keyword>Win32Proj</Keyword>\r
- <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
- </PropertyGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <WholeProgramOptimization>true</WholeProgramOptimization>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <WholeProgramOptimization>true</WholeProgramOptimization>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>MultiByte</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
- <ImportGroup Label="ExtensionSettings">\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">\r
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
- </ImportGroup>\r
- <PropertyGroup Label="UserMacros" />\r
- <PropertyGroup>\r
- <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">false</LinkIncremental>\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Release|x64'" />\r
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(ProjectName)_d</TargetName>\r
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(ProjectName)_d</TargetName>\r
- <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">$(ProjectName)_d</TargetName>\r
- <TargetName Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">$(ProjectName)_d</TargetName>\r
- </PropertyGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <MinimalRebuild>true</MinimalRebuild>\r
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX86</TargetMachine>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
- <Midl>\r
- <TargetEnvironment>X64</TargetEnvironment>\r
- </Midl>\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <MinimalRebuild>true</MinimalRebuild>\r
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX64</TargetMachine>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Full</Optimization>\r
- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
- <IntrinsicFunctions>true</IntrinsicFunctions>\r
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
- <OmitFramePointers>false</OmitFramePointers>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <StringPooling>true</StringPooling>\r
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
- <EnableEnhancedInstructionSet>StreamingSIMDExtensions2</EnableEnhancedInstructionSet>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <EnablePREfast>false</EnablePREfast>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <OptimizeReferences>true</OptimizeReferences>\r
- <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX86</TargetMachine>\r
- <Profile>true</Profile>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
- <Midl>\r
- <TargetEnvironment>X64</TargetEnvironment>\r
- </Midl>\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Full</Optimization>\r
- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
- <IntrinsicFunctions>true</IntrinsicFunctions>\r
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
- <OmitFramePointers>false</OmitFramePointers>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <StringPooling>true</StringPooling>\r
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <EnablePREfast>false</EnablePREfast>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <OptimizeReferences>true</OptimizeReferences>\r
- <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
- <LinkTimeCodeGeneration>UseLinkTimeCodeGeneration</LinkTimeCodeGeneration>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX64</TargetMachine>\r
- <Profile>true</Profile>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <MinimalRebuild>true</MinimalRebuild>\r
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX86</TargetMachine>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
- <Midl>\r
- <TargetEnvironment>X64</TargetEnvironment>\r
- </Midl>\r
- <ClCompile>\r
- <AdditionalOptions>/bigobj /Zc:inline %(AdditionalOptions)</AdditionalOptions>\r
- <Optimization>Disabled</Optimization>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\test-hdr;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <MinimalRebuild>true</MinimalRebuild>\r
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>\r
- <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <CallingConvention>Cdecl</CallingConvention>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <AdditionalLibraryDirectories>$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\r
- <GenerateDebugInformation>true</GenerateDebugInformation>\r
- <SubSystem>Console</SubSystem>\r
- <RandomizedBaseAddress>false</RandomizedBaseAddress>\r
- <DataExecutionPrevention>\r
- </DataExecutionPrevention>\r
- <TargetMachine>MachineX64</TargetMachine>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemGroup>\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\allocator_test.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\bitop_st.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\cxx11_atomic_class.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\cxx11_atomic_func.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\find_option.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\hash_tuple.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\michael_allocator.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\split_bitstring.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\thread_init_fini.cpp" />\r
- <ClCompile Include="..\..\..\tests\test-hdr\misc\permutation_generator.cpp" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <ClInclude Include="..\..\..\tests\test-hdr\misc\cxx11_convert_memory_order.h" />\r
- <ClInclude Include="..\..\..\tests\test-hdr\misc\michael_allocator.h" />\r
- </ItemGroup>\r
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
- <ImportGroup Label="ExtensionTargets">\r
- </ImportGroup>\r
-</Project>
\ No newline at end of file
+++ /dev/null
-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)
-
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)
unit-deque
unit-list
unit-map
+ unit-misc
unit-pqueue
unit-queue
unit-intrusive-set
--- /dev/null
+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
--- /dev/null
+/*
+ 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 <gtest/gtest.h>
+
+#include <cds/algo/int_algo.h>
+#include <cds/os/timer.h>
+
+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
--- /dev/null
+/*
+ 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 <gtest/gtest.h>
+#include <cds/algo/atomic.h>
+#include "cxx11_convert_memory_order.h"
+
+namespace {
+ class cxx11_atomic_class: public ::testing::Test
+ {
+ protected:
+ template <typename AtomicFlag>
+ 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 <typename AtomicFlag>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <typename Atomic, typename Integral>
+ void test_atomic_integral_(Atomic& a)
+ {
+ do_test_atomic_integral<Atomic, Integral >(a);
+
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_relaxed );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acquire );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_release );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acq_rel );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_seq_cst );
+ }
+
+ template <typename Integral>
+ void test_atomic_integral()
+ {
+ typedef atomics::atomic<Integral> atomic_type;
+
+ atomic_type a[8];
+ for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
+ test_atomic_integral_<atomic_type, Integral>( a[i] );
+ }
+ }
+ template <typename Integral>
+ void test_atomic_integral_volatile()
+ {
+ typedef atomics::atomic<Integral> volatile atomic_type;
+
+ atomic_type a[8];
+ for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
+ test_atomic_integral_<atomic_type, Integral>( a[i] );
+ }
+ }
+
+ template <class AtomicBool>
+ 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 <class AtomicBool>
+ 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 <typename Atomic>
+ 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<char *>(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<char *>(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<char *>(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<char *>(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<char *>(p), 4 );
+
+ EXPECT_EQ( reinterpret_cast<char *>(a.exchange( (void *) arr, order )), arr + 3 );
+ EXPECT_EQ( reinterpret_cast<char *>(a.load( oLoad )), arr );
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), 1 );
+
+ for ( char i = 1; i < aSize; ++i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i );
+ a.fetch_add( 1, order );
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i + 1 );
+ }
+
+ for ( char i = aSize; i > 1; --i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i );
+ a.fetch_sub( 1, order );
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load( oLoad )), i - 1 );
+ }
+ }
+
+ template <bool Volatile>
+ void do_test_atomic_pointer_void()
+ {
+ typedef typename add_volatile<atomics::atomic< void *>, 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<char *>(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<char *>( a.exchange( (void *) arr )), arr + 3 );
+ EXPECT_EQ( reinterpret_cast<char *>( a.load()), arr );
+ EXPECT_EQ( *reinterpret_cast<char *>( a.load()), 1 );
+
+ for ( char i = 1; i < aSize; ++i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i );
+ a.fetch_add( 1 );
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i + 1 );
+ }
+
+ for ( char i = aSize; i > 1; --i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(a.load()), i );
+ a.fetch_sub( 1 );
+ EXPECT_EQ( *reinterpret_cast<char *>(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 <typename Atomic, typename Integral>
+ 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 <typename Integral, bool Volatile>
+ void test_atomic_pointer_for()
+ {
+ typedef Integral integral_type;
+ typedef typename add_volatile<atomics::atomic< integral_type *>, 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 <typename AtomicBool>
+ 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<bool> >();
+ }
+ void test_atomic_bool_volatile()
+ {
+ test_atomic_bool_< atomics::atomic<bool> volatile >();
+ }
+ };
+
+ TEST_F( cxx11_atomic_class, atomic_char )
+ {
+ test_atomic_integral<char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_signed_char )
+ {
+ test_atomic_integral<signed char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_char )
+ {
+ test_atomic_integral<unsigned char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_short_int )
+ {
+ test_atomic_integral<short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_signed_short_int )
+ {
+ test_atomic_integral<signed short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_short_int )
+ {
+ test_atomic_integral<unsigned short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_int )
+ {
+ test_atomic_integral<int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_int )
+ {
+ test_atomic_integral<unsigned int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_long )
+ {
+ test_atomic_integral<long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_long )
+ {
+ test_atomic_integral<unsigned long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_long_long )
+ {
+ test_atomic_integral<long long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_long_long )
+ {
+ test_atomic_integral<unsigned long long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_char_volatile )
+ {
+ test_atomic_integral_volatile<char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_signed_char_volatile )
+ {
+ test_atomic_integral_volatile<signed char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_char_volatile )
+ {
+ test_atomic_integral_volatile<unsigned char>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_short_int_volatile )
+ {
+ test_atomic_integral_volatile<short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_signed_short_int_volatile )
+ {
+ test_atomic_integral_volatile<signed short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_short_int_volatile )
+ {
+ test_atomic_integral_volatile<unsigned short int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_int_volatile )
+ {
+ test_atomic_integral_volatile<int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_int_volatile )
+ {
+ test_atomic_integral_volatile<unsigned int>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_long_volatile )
+ {
+ test_atomic_integral_volatile<long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_long_volatile )
+ {
+ test_atomic_integral_volatile<unsigned long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_long_long_volatile )
+ {
+ test_atomic_integral_volatile<long long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_unsigned_long_long_volatile )
+ {
+ test_atomic_integral_volatile<unsigned long long>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_void )
+ {
+ do_test_atomic_pointer_void<false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_void_volatile )
+ {
+ do_test_atomic_pointer_void<true>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_char )
+ {
+ test_atomic_pointer_for<char, false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_char_volatile )
+ {
+ test_atomic_pointer_for<char, true>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_short )
+ {
+ test_atomic_pointer_for<short int, false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_short_volatile )
+ {
+ test_atomic_pointer_for<short int, true>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_int )
+ {
+ test_atomic_pointer_for<int, false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_int_volatile )
+ {
+ test_atomic_pointer_for<int, true>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_long )
+ {
+ test_atomic_pointer_for<long, false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_long_volatile )
+ {
+ test_atomic_pointer_for<long, true>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_long_long )
+ {
+ test_atomic_pointer_for<long long, false>();
+ }
+
+ TEST_F( cxx11_atomic_class, atomic_pointer_long_long_volatile )
+ {
+ test_atomic_pointer_for<long long, true>();
+ }
+} // namespace
--- /dev/null
+/*
+ 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 <gtest/gtest.h>
+#include <cds/algo/atomic.h>
+
+#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 <typename AtomicFlag>
+ 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 <typename AtomicFlag>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <class Atomic, typename Integral>
+ 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 <typename Atomic, typename Integral>
+ void test_atomic_integral_(Atomic& a)
+ {
+ do_test_atomic_integral<Atomic, Integral >(a);
+
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_relaxed );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acquire );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_release );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acq_rel );
+ do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_seq_cst );
+ }
+
+ template <typename Integral>
+ void test_atomic_integral()
+ {
+ typedef atomics::atomic<Integral> atomic_type;
+ atomic_type a[8];
+ for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
+ test_atomic_integral_<atomic_type, Integral>( a[i] );
+ }
+ }
+ template <typename Integral>
+ void test_atomic_integral_volatile()
+ {
+ typedef atomics::atomic<Integral> volatile atomic_type;
+ atomic_type a[8];
+ for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
+ test_atomic_integral_<atomic_type, Integral>( a[i] );
+ }
+ }
+
+ template <class AtomicBool>
+ 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 <class AtomicBool>
+ 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 <typename Atomic, typename Integral>
+ 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 <typename Integral, bool Volatile>
+ void test_atomic_pointer_for()
+ {
+ typedef Integral integral_type;
+ typedef typename add_volatile<atomics::atomic< integral_type *>, 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 <typename Atomic>
+ 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<char *>(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<char *>(atomics::atomic_exchange_explicit( &a, (void *) arr, order )), arr + 3 );
+ EXPECT_EQ( reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), arr );
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), 1 );
+
+ for ( char i = 1; i < aSize; ++i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), i );
+ atomics::atomic_fetch_add_explicit( &a, 1, order );
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), i + 1 );
+ }
+
+ for ( char i = aSize; i > 1; --i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), i );
+ atomics::atomic_fetch_sub_explicit( &a, 1, order );
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )), i - 1 );
+ }
+ }
+
+ template <bool Volatile>
+ void do_test_atomic_pointer_void()
+ {
+ typedef typename add_volatile<atomics::atomic< void *>, 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<char *>(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<char *>( atomics::atomic_exchange( &a, (void *) arr )), arr + 3 );
+ EXPECT_EQ( reinterpret_cast<char *>( atomics::atomic_load( &a )), arr );
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load( &a )), 1 );
+
+ for ( char i = 1; i < aSize; ++i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load( &a )), i );
+ atomics::atomic_fetch_add( &a, 1 );
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load( &a )), i + 1 );
+ }
+
+ for ( char i = aSize; i > 1; --i ) {
+ EXPECT_EQ( *reinterpret_cast<char *>(atomics::atomic_load( &a )), i );
+ atomics::atomic_fetch_sub( &a, 1 );
+ EXPECT_EQ( *reinterpret_cast<char *>(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 <typename AtomicBool>
+ 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_<atomics::atomic<bool> >();
+ }
+ void test_atomic_bool_volatile()
+ {
+ test_atomic_bool_<atomics::atomic<bool> volatile >();
+ }
+ };
+
+ TEST_F( cxx11_atomic_func, atomic_char )
+ {
+ test_atomic_integral<char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_char_volatile )
+ {
+ test_atomic_integral_volatile<char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_char )
+ {
+ test_atomic_integral<unsigned char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_char_volatile )
+ {
+ test_atomic_integral_volatile<unsigned char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_signed_char )
+ {
+ test_atomic_integral<signed char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_signed_char_volatile )
+ {
+ test_atomic_integral_volatile<signed char>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_short_int )
+ {
+ test_atomic_integral<short int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_short_int_volatile )
+ {
+ test_atomic_integral_volatile<short int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_short_int )
+ {
+ test_atomic_integral<unsigned short int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_short_int_volatile )
+ {
+ test_atomic_integral_volatile<unsigned short int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_int )
+ {
+ test_atomic_integral<int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_int_volatile )
+ {
+ test_atomic_integral_volatile<int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_int )
+ {
+ test_atomic_integral<unsigned int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_int_volatile )
+ {
+ test_atomic_integral_volatile<unsigned int>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_long )
+ {
+ test_atomic_integral<long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_long_volatile )
+ {
+ test_atomic_integral_volatile<long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_long )
+ {
+ test_atomic_integral<unsigned long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_long_volatile )
+ {
+ test_atomic_integral_volatile<unsigned long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_long_long )
+ {
+ test_atomic_integral<long long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_long_long_volatile )
+ {
+ test_atomic_integral_volatile<long long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_long_long )
+ {
+ test_atomic_integral<unsigned long long>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_unsigned_long_long_volatile )
+ {
+ test_atomic_integral_volatile<unsigned long long>();
+ }
+
+ TEST_F( cxx11_atomic_func, atomic_pointer_void )
+ {
+ do_test_atomic_pointer_void<false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_void_volatile )
+ {
+ do_test_atomic_pointer_void<true>();
+ }
+
+ TEST_F( cxx11_atomic_func, atomic_pointer_char )
+ {
+ test_atomic_pointer_for<char, false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_char_volatile )
+ {
+ test_atomic_pointer_for<char, true>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_short )
+ {
+ test_atomic_pointer_for<short, false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_short_volatile )
+ {
+ test_atomic_pointer_for<short, true>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_int )
+ {
+ test_atomic_pointer_for<int, false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_int_volatile )
+ {
+ test_atomic_pointer_for<int, true>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_long )
+ {
+ test_atomic_pointer_for<long, false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_long_volatile )
+ {
+ test_atomic_pointer_for<long, true>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_long_long )
+ {
+ test_atomic_pointer_for<long long, false>();
+ }
+ TEST_F( cxx11_atomic_func, atomic_pointer_long_long_volatile )
+ {
+ test_atomic_pointer_for<long long, true>();
+ }
+
+ 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
--- /dev/null
+/*
+ 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 <cds/algo/atomic.h> 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 <typename T, bool Volatile>
+ struct add_volatile;
+
+ template <typename T>
+ struct add_volatile<T, false>
+ {
+ typedef T type;
+ };
+
+ template <typename T>
+ struct add_volatile<T, true>
+ {
+ typedef T volatile type;
+ };
+
+} // namespace
--- /dev/null
+/*
+ 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 <type_traits>
+#include <cds/opt/options.h>
+
+// Value options
+namespace {
+
+ template <int Val>
+ struct int_opt {
+ static const int value = Val;
+ };
+
+ template <bool Val>
+ struct bool_opt {
+ static const bool value = Val;
+ };
+
+ enum user_enum {
+ val_zero, val_one, val_two, val_three, val_four, val_five
+ };
+
+ template <user_enum Val>
+ 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<tag_default>, cds::opt::stat<tag_a>, bool_opt<false> >::type,
+ cds::opt::tag<tag_default>
+ >::value), "Result != tag_default" );
+
+ // Option found once
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a> >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, cds::opt::tag<tag_a> >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ // First option
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>
+ ,cds::opt::tag<tag_a> // desired
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ // Last option
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::tag<tag_a> // desired
+ >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ // Middle option
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::tag<tag_a> // desired
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ // Option not found
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_default>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ >::type,
+ cds::opt::tag<tag_default>
+ >::value), "Result != tag_default" );
+
+ // Multiple options
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a>, cds::opt::tag<tag_b> >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+ static_assert( (std::is_same<
+ cds::opt::find_option< cds::opt::tag<tag_default>
+ ,cds::opt::tag<tag_a> // desired - first accepted
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_b>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::stat<tag_a>
+ ,cds::opt::tag<tag_b> // desired
+ >::type,
+ cds::opt::tag<tag_a>
+ >::value), "Result != tag_a" );
+
+
+ // *****************************************************
+ // Value options
+
+ // Not found
+ static_assert( (std::is_same<
+ cds::opt::find_option< int_opt<15>, bool_opt<false>, cds::opt::stat<tag_a> >::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<tag_a> >::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<tag_a>, bool_opt<true>, 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<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, int_opt<200> >::type,
+ enum_opt<val_zero>
+ >::value), "Result != enum_opt<val_zero>" );
+
+ static_assert( (std::is_same<
+ cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, enum_opt<val_three>, int_opt<200> >::type,
+ enum_opt<val_three>
+ >::value), "Result != enum_opt<val_three>" );
+
+}
+
+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" );
+}
--- /dev/null
+/*
+ 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 <gtest/gtest.h>
+#include <cds/opt/hash.h>
+
+namespace {
+ typedef cds::opt::v::hash_selector< cds::opt::none >::type hashing;
+
+#define HASHING(_n) \
+ struct hash##_n: public hashing { \
+ template <typename T> 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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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
--- /dev/null
+/*
+ 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 <cds/opt/permutation.h>
+#include <gtest/gtest.h>
+
+namespace {
+
+ class Permutations: public ::testing::Test
+ {
+ protected:
+ static const size_t c_nMax = 1024;
+
+ template <typename Gen>
+ 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 <typename Gen>
+ void test()
+ {
+ for ( size_t nLen = 2; nLen <= c_nMax; ++nLen ) {
+ Gen gen( nLen );
+ test_with( gen, nLen );
+ }
+ }
+
+ template <typename Gen>
+ 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
--- /dev/null
+/*
+ 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 <cds/algo/split_bitstring.h>
+#include <gtest/gtest.h>
+
+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 <typename PartUInt>
+ 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<size_t>(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<uint64_t>(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<uint64_t>(splitter.safe_cut( bits )) << shift );
+ shift += bits;
+ }
+ ASSERT_TRUE( splitter.eos() );
+ ASSERT_TRUE( !splitter );
+ EXPECT_EQ( res, src );
+ }
+ }
+ }
+
+ template <typename PartUInt>
+ 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<uint16_t>();
+ else
+ cut_small_le<uint16_t>();
+ }
+
+} // namespace
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)
+++ /dev/null
-set(PACKAGE_NAME test-hdr)\r
-\r
-set(CDS_TESTHDR_MISC\r
- misc/cxx11_atomic_class.cpp\r
- misc/cxx11_atomic_func.cpp\r
- misc/find_option.cpp\r
- misc/allocator_test.cpp\r
- misc/michael_allocator.cpp\r
- misc/hash_tuple.cpp\r
- misc/bitop_st.cpp\r
- misc/split_bitstring.cpp\r
- misc/permutation_generator.cpp\r
- misc/thread_init_fini.cpp)\r
-\r
-set(CDS_TESTHDR_SOURCES\r
- ${CDS_TESTHDR_MISC})\r
-\r
-add_executable(${PACKAGE_NAME} ${CDS_TESTHDR_SOURCES} $<TARGET_OBJECTS:test-hdr-offsetof> $<TARGET_OBJECTS:${TEST_COMMON}>)\r
-target_link_libraries(${PACKAGE_NAME} ${CDS_SHARED_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})\r
-add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
\ No newline at end of file
+++ /dev/null
-/*
- 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 <cds/os/timer.h>
-#include <cds/details/allocator.h>
-
-#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 <typename ALLOC>
- 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<MichaelHeap_NoStat<char> >();
- 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<std::allocator<char> >();
- double fDur = timer.duration();
- std::cout << "\tduration=" << fDur << std::endl;
- }
-
- template <typename ALLOC>
- 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<MichaelHeap_NoStat<char> >();
- 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<std::allocator<char> >();
- 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<SimpleStruct> 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 );
+++ /dev/null
-/*
- 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 <cds/algo/int_algo.h>
-#include <cds/os/timer.h>
-
-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);
+++ /dev/null
-/*
- 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 <cds/algo/atomic.h>
-
-#include "misc/cxx11_convert_memory_order.h"
-
-namespace misc {
- class cxx11_atomic_class: public CppUnitMini::TestCase
- {
- template <typename AtomicFlag>
- 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 <typename AtomicFlag>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <typename Atomic, typename Integral>
- void test_atomic_integral_(Atomic& a)
- {
- do_test_atomic_integral<Atomic, Integral >(a);
-
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_relaxed );
-//#if !(CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION < 40900)
-// do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_consume );
-//#endif
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acquire );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_release );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acq_rel );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_seq_cst );
- }
-
- template <typename Integral>
- void test_atomic_integral()
- {
- typedef atomics::atomic<Integral> atomic_type;
-
- atomic_type a[8];
- for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
- test_atomic_integral_<atomic_type, Integral>( a[i] );
- }
- }
- template <typename Integral>
- void test_atomic_integral_volatile()
- {
- typedef atomics::atomic<Integral> volatile atomic_type;
-
- atomic_type a[8];
- for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
- test_atomic_integral_<atomic_type, Integral>( a[i] );
- }
- }
-
- template <class AtomicBool>
- 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 <class AtomicBool>
- 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 <typename Atomic>
- 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<char *>(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<char *>(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<char *>(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<char *>(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<char *>(p) == 4 );
-
- CPPUNIT_ASSERT( reinterpret_cast<char *>(a.exchange( (void *) arr, order )) == arr + 3 );
- CPPUNIT_ASSERT( reinterpret_cast<char *>(a.load( oLoad )) == arr );
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load( oLoad )) == 1 );
-
- for ( char i = 1; i < aSize; ++i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load( oLoad )) == i );
- CPPUNIT_ASSERT( a.fetch_add( 1, order ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load( oLoad )) == i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load( oLoad )) == i );
- CPPUNIT_ASSERT( a.fetch_sub( 1, order ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load( oLoad )) == i - 1 );
- }
- }
-
- template <bool Volatile>
- void do_test_atomic_pointer_void()
- {
- typedef typename add_volatile<atomics::atomic< void *>, 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<void*>::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<void*>::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<char *>(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<char *>( a.exchange( (void *) arr )) == arr + 3 );
- CPPUNIT_ASSERT( reinterpret_cast<char *>( a.load()) == arr );
- CPPUNIT_ASSERT( *reinterpret_cast<char *>( a.load()) == 1 );
-
- for ( char i = 1; i < aSize; ++i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load()) == i );
- CPPUNIT_ASSERT( a.fetch_add( 1 ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load()) == i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(a.load()) == i );
- CPPUNIT_ASSERT( a.fetch_sub( 1 ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(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 <typename Atomic, typename Integral>
- 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 <typename Integral, bool Volatile>
- void test_atomic_pointer_for()
- {
- typedef Integral integral_type;
- typedef typename add_volatile<atomics::atomic< integral_type *>, 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 <typename AtomicBool>
- 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<bool> >();
- }
- void test_atomic_bool_volatile()
- {
- test_atomic_bool_< atomics::atomic<bool> volatile >();
- }
-
- void test_atomic_char() { test_atomic_integral<char>(); }
- void test_atomic_signed_char() { test_atomic_integral<signed char>(); }
- void test_atomic_unsigned_char() { test_atomic_integral<unsigned char>(); }
- void test_atomic_short_int() { test_atomic_integral<short int>(); }
- void test_atomic_unsigned_short_int() { test_atomic_integral<unsigned short int>(); }
- void test_atomic_int() { test_atomic_integral<int>(); }
- void test_atomic_unsigned_int() { test_atomic_integral<unsigned int>(); }
- void test_atomic_long() { test_atomic_integral<long>(); }
- void test_atomic_unsigned_long() { test_atomic_integral<unsigned long>(); }
- void test_atomic_long_long() { test_atomic_integral<long long>(); }
- void test_atomic_unsigned_long_long() { test_atomic_integral<unsigned long long>(); }
-
- void test_atomic_char_volatile() { test_atomic_integral_volatile<char>(); }
- void test_atomic_signed_char_volatile() { test_atomic_integral_volatile<signed char>(); }
- void test_atomic_unsigned_char_volatile() { test_atomic_integral_volatile<unsigned char>(); }
- void test_atomic_short_int_volatile() { test_atomic_integral_volatile<short int>(); }
- void test_atomic_unsigned_short_int_volatile() { test_atomic_integral_volatile<unsigned short int>(); }
- void test_atomic_int_volatile() { test_atomic_integral_volatile<int>(); }
- void test_atomic_unsigned_int_volatile() { test_atomic_integral_volatile<unsigned int>(); }
- void test_atomic_long_volatile() { test_atomic_integral_volatile<long>(); }
- void test_atomic_unsigned_long_volatile() { test_atomic_integral_volatile<unsigned long>(); }
- void test_atomic_long_long_volatile() { test_atomic_integral_volatile<long long>(); }
- void test_atomic_unsigned_long_long_volatile() { test_atomic_integral_volatile<unsigned long long>(); }
-
- void test_atomic_pointer_void() { do_test_atomic_pointer_void<false>() ;}
- void test_atomic_pointer_void_volatile(){ do_test_atomic_pointer_void<true>() ;}
-
- void test_atomic_pointer_char() { test_atomic_pointer_for<char, false>() ;}
- void test_atomic_pointer_short() { test_atomic_pointer_for<short int, false>() ;}
- void test_atomic_pointer_int() { test_atomic_pointer_for<int, false>() ;}
- void test_atomic_pointer_long() { test_atomic_pointer_for<long, false>() ;}
- void test_atomic_pointer_long_long() { test_atomic_pointer_for<long long, false>() ;}
-
- void test_atomic_pointer_char_volatile() { test_atomic_pointer_for<char, true>() ;}
- void test_atomic_pointer_short_volatile() { test_atomic_pointer_for<unsigned short int, true>() ;}
- void test_atomic_pointer_int_volatile() { test_atomic_pointer_for<int, true>() ;}
- void test_atomic_pointer_long_volatile() { test_atomic_pointer_for<long, true>() ;}
- void test_atomic_pointer_long_long_volatile() { test_atomic_pointer_for<long long, true>() ;}
-
- 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);
+++ /dev/null
-/*
- 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 <cds/algo/atomic.h>
-
-#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 <typename AtomicFlag>
- 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 <typename AtomicFlag>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <class Atomic, typename Integral>
- 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 <typename Atomic, typename Integral>
- void test_atomic_integral_(Atomic& a)
- {
- do_test_atomic_integral<Atomic, Integral >(a);
-
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_relaxed );
- //do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_consume );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acquire );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_release );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_acq_rel );
- do_test_atomic_integral<Atomic, Integral >( a, atomics::memory_order_seq_cst );
- }
-
- template <typename Integral>
- void test_atomic_integral()
- {
- typedef atomics::atomic<Integral> atomic_type;
- atomic_type a[8];
- for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
- test_atomic_integral_<atomic_type, Integral>( a[i] );
- }
- }
- template <typename Integral>
- void test_atomic_integral_volatile()
- {
- typedef atomics::atomic<Integral> volatile atomic_type;
- atomic_type a[8];
- for ( size_t i = 0; i < sizeof(a)/sizeof(a[0]); ++i ) {
- test_atomic_integral_<atomic_type, Integral>( a[i] );
- }
- }
-
- template <class AtomicBool>
- 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 <class AtomicBool>
- 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 <typename Atomic, typename Integral>
- 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 <typename Integral, bool Volatile>
- void test_atomic_pointer_for()
- {
- typedef Integral integral_type;
- typedef typename add_volatile<atomics::atomic< integral_type *>, 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 <typename Atomic>
- 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<char *>(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<char *>(atomics::atomic_exchange_explicit( &a, (void *) arr, order )) == arr + 3 );
- CPPUNIT_ASSERT( reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == arr );
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == 1 );
-
- for ( char i = 1; i < aSize; ++i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == i );
- CPPUNIT_ASSERT( atomics::atomic_fetch_add_explicit( &a, 1, order ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == i );
- CPPUNIT_ASSERT( atomics::atomic_fetch_sub_explicit( &a, 1, order ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load_explicit( &a, oLoad )) == i - 1 );
- }
- }
-
- template <bool Volatile>
- void do_test_atomic_pointer_void()
- {
- typedef typename add_volatile<atomics::atomic< void *>, 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<char *>(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<char *>( atomics::atomic_exchange( &a, (void *) arr )) == arr + 3 );
- CPPUNIT_ASSERT( reinterpret_cast<char *>( atomics::atomic_load( &a )) == arr );
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load( &a )) == 1 );
-
- for ( char i = 1; i < aSize; ++i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load( &a )) == i );
- CPPUNIT_ASSERT( atomics::atomic_fetch_add( &a, 1 ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load( &a )) == i + 1 );
- }
-
- for ( char i = aSize; i > 1; --i ) {
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(atomics::atomic_load( &a )) == i );
- CPPUNIT_ASSERT( atomics::atomic_fetch_sub( &a, 1 ));
- CPPUNIT_ASSERT( *reinterpret_cast<char *>(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 <typename AtomicBool>
- 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_<atomics::atomic<bool> >();
- }
- void test_atomic_bool_volatile()
- {
- test_atomic_bool_<atomics::atomic<bool> volatile >();
- }
-
- void test_atomic_char() { test_atomic_integral<char>(); }
- void test_atomic_char_volatile() { test_atomic_integral_volatile<char>(); }
- void test_atomic_signed_char() { test_atomic_integral<signed char>(); }
- void test_atomic_signed_char_volatile() { test_atomic_integral_volatile<signed char>(); }
- void test_atomic_unsigned_char() { test_atomic_integral<unsigned char>(); }
- void test_atomic_unsigned_char_volatile(){ test_atomic_integral_volatile<unsigned char>(); }
- void test_atomic_short_int() { test_atomic_integral<short int>(); }
- void test_atomic_short_int_volatile() { test_atomic_integral_volatile<short int>(); }
- void test_atomic_unsigned_short_int() { test_atomic_integral<unsigned short int>(); }
- void test_atomic_unsigned_short_int_volatile() { test_atomic_integral_volatile<unsigned short int>(); }
- void test_atomic_int() { test_atomic_integral<int>(); }
- void test_atomic_int_volatile() { test_atomic_integral_volatile<int>(); }
- void test_atomic_unsigned_int() { test_atomic_integral<unsigned int>(); }
- void test_atomic_unsigned_int_volatile(){ test_atomic_integral_volatile<unsigned int>(); }
- void test_atomic_long() { test_atomic_integral<long>(); }
- void test_atomic_long_volatile() { test_atomic_integral_volatile<long>(); }
- void test_atomic_unsigned_long() { test_atomic_integral<unsigned long>(); }
- void test_atomic_unsigned_long_volatile() { test_atomic_integral_volatile<unsigned long>(); }
- void test_atomic_long_long() { test_atomic_integral<long long>(); }
- void test_atomic_long_long_volatile() { test_atomic_integral_volatile<long long>(); }
- void test_atomic_unsigned_long_long() { test_atomic_integral<unsigned long long>(); }
- void test_atomic_unsigned_long_long_volatile() { test_atomic_integral_volatile<unsigned long long>(); }
-
- void test_atomic_pointer_void() { do_test_atomic_pointer_void<false>() ;}
- void test_atomic_pointer_void_volatile(){ do_test_atomic_pointer_void<true>() ;}
-
- void test_atomic_pointer_char() { test_atomic_pointer_for<char, false>() ;}
- void test_atomic_pointer_short() { test_atomic_pointer_for<short int, false>() ;}
- void test_atomic_pointer_int() { test_atomic_pointer_for<int, false>() ;}
- void test_atomic_pointer_long() { test_atomic_pointer_for<long, false>() ;}
- void test_atomic_pointer_long_long() { test_atomic_pointer_for<long long, false>() ;}
-
- void test_atomic_pointer_char_volatile() { test_atomic_pointer_for<char, true>() ;}
- void test_atomic_pointer_short_volatile() { test_atomic_pointer_for<unsigned short int, true>() ;}
- void test_atomic_pointer_int_volatile() { test_atomic_pointer_for<int, true>() ;}
- void test_atomic_pointer_long_volatile() { test_atomic_pointer_for<long, true>() ;}
- void test_atomic_pointer_long_long_volatile() { test_atomic_pointer_for<long long, true>() ;}
-
- 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
+++ /dev/null
-/*
- 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 <cds/algo/atomic.h> 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 <typename T, bool Volatile>
- struct add_volatile;
-
- template <typename T>
- struct add_volatile<T, false>
- {
- typedef T type;
- };
-
- template <typename T>
- struct add_volatile<T, true>
- {
- typedef T volatile type;
- };
-
-} // namespace misc
+++ /dev/null
-/*
- 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 <type_traits>
-#include <cds/opt/options.h>
-
-// Value options
-namespace {
-
- template <int Val>
- struct int_opt {
- static const int value = Val;
- };
-
- template <bool Val>
- struct bool_opt {
- static const bool value = Val;
- };
-
- enum user_enum {
- val_zero, val_one, val_two, val_three, val_four, val_five
- };
-
- template <user_enum Val>
- 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<tag_default>, cds::opt::stat<tag_a>, bool_opt<false> >::type,
- cds::opt::tag<tag_default>
- >::value), "Result != tag_default" );
-
- // Option found once
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a> >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::stat<tag_a>, cds::opt::tag<tag_a> >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- // First option
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>
- ,cds::opt::tag<tag_a> // desired
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- // Last option
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::tag<tag_a> // desired
- >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- // Middle option
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::tag<tag_a> // desired
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- // Option not found
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_default>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- >::type,
- cds::opt::tag<tag_default>
- >::value), "Result != tag_default" );
-
- // Multiple options
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>, cds::opt::tag<tag_a>, cds::opt::tag<tag_b> >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
- static_assert( (std::is_same<
- cds::opt::find_option< cds::opt::tag<tag_default>
- ,cds::opt::tag<tag_a> // desired - first accepted
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_b>
- ,cds::opt::stat<tag_a>
- ,cds::opt::stat<tag_a>
- ,cds::opt::tag<tag_b> // desired
- >::type,
- cds::opt::tag<tag_a>
- >::value), "Result != tag_a" );
-
-
-
- // *****************************************************
- // Value options
-
- // Not found
- static_assert( (std::is_same<
- cds::opt::find_option< int_opt<15>, bool_opt<false>, cds::opt::stat<tag_a> >::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<tag_a> >::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<tag_a>, bool_opt<true>, 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<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, int_opt<200> >::type,
- enum_opt<val_zero>
- >::value), "Result != enum_opt<val_zero>" );
-
- static_assert( (std::is_same<
- cds::opt::find_option< enum_opt<val_zero>, int_opt<100>, cds::opt::stat<tag_a>, enum_opt<val_three>, int_opt<200> >::type,
- enum_opt<val_three>
- >::value), "Result != enum_opt<val_three>" );
-
-}
-
-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" );
-}
+++ /dev/null
-/*
- 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 <cds/opt/hash.h>
-
-#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 <typename T> 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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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<cds::opt::none>::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);
+++ /dev/null
-/*
- 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;
-}
+++ /dev/null
-/*
- 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 <cds/memory/michael/allocator.h>
-#include <iostream>
-
-namespace misc {
- namespace ma = cds::memory::michael;
-
- typedef ma::Heap<
- ma::opt::procheap_stat<ma::procheap_empty_stat>,
- ma::opt::os_allocated_stat<ma::os_allocated_empty>,
- ma::opt::check_bounds<ma::debug_bound_checking>
- > t_MichaelHeap_NoStat;
-
- typedef ma::Heap<
- ma::opt::procheap_stat<ma::procheap_atomic_stat >,
- ma::opt::os_allocated_stat<ma::os_allocated_atomic >,
- ma::opt::check_bounds<ma::debug_bound_checking>
- > t_MichaelHeap_Stat;
-
- typedef ma::summary_stat summary_stat;
-
- extern t_MichaelHeap_NoStat s_MichaelHeap_NoStat;
- extern t_MichaelHeap_Stat s_MichaelHeap_Stat;
-
- template <typename T>
- 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<pointer>( 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 <typename T>
- class std_allocator: public std::allocator<T>
- {
- public:
- enum {
- alignment = 1
- };
-
- static void stat(summary_stat& /*s*/)
- {}
- };
-
- template <typename T>
- 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<pointer>( 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 <typename T, size_t ALIGN>
- 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<pointer>( 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 <typename T, size_t ALIGN>
- 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<pointer>( 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 <typename T, size_t ALIGN>
- 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<pointer>( 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;
- }
-}
+++ /dev/null
-/*
- 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 <cds/opt/permutation.h>
-#include "cppunit/cppunit_proxy.h"
-
-namespace misc {
-
- class Permutations: public CppUnitMini::TestCase
- {
- static const size_t c_nMax = 1024;
-
- template <typename Gen>
- 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 <typename Gen>
- void test()
- {
- for ( size_t nLen = 2; nLen <= c_nMax; ++nLen ) {
- Gen gen( nLen );
- test_with( gen, nLen );
- }
- }
-
- template <typename Gen>
- 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);
+++ /dev/null
-/*
- 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 <cds/algo/split_bitstring.h>
-
-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<uint16_t>();
- else
- cut_small_le<uint16_t>();
- }
-
- 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 <typename PartUInt>
- 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<size_t>(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<uint64_t>(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<uint64_t>(splitter.safe_cut( bits )) << shift );
- shift += bits;
- }
- CPPUNIT_ASSERT( splitter.eos() );
- CPPUNIT_ASSERT( !splitter );
- CPPUNIT_ASSERT( res == src );
- }
- }
- }
-
- template <typename PartUInt>
- 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);
+++ /dev/null
-/*
- 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 <cds/threading/model.h>
-
-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<thread_init_fini&>( 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);
+++ /dev/null
-/*
- 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 <cds/algo/atomic.h>
-
-namespace misc {
-
- template <typename ItemCounter>
- struct size_checker {
- template <typename Container>
- bool operator()( Container const& c, size_t nSize ) const
- {
- return c.size() == nSize;
- }
- };
-
- template<>
- struct size_checker< cds::atomicity::empty_item_counter > {
- template <typename Container>
- bool operator()( Container const& /*c*/, size_t /*nSize*/ ) const
- {
- return true;
- }
- };
-
- template <class Container>
- static inline bool check_size( Container const& cont, size_t nSize )
- {
- return size_checker<typename Container::item_counter>()( cont, nSize );
- }
-
-} // namespace misc
-
-#endif // #ifndef CDSTEST_SIZE_CHECK_H