CDSUNIT_SET_SOURCES := $(CDSUNIT_SET_SOURCES:%.cpp=../%.cpp)
CDSUNIT_SET_OBJS := $(CDSUNIT_SET_SOURCES:%.cpp=%.o)
-include ../projects/source.unit.queue.mk
-CDSUNIT_QUEUE_SOURCES := $(CDSUNIT_QUEUE_SOURCES:%.cpp=../%.cpp)
-CDSUNIT_QUEUE_OBJS := $(CDSUNIT_QUEUE_SOURCES:%.cpp=%.o)
-
include ../projects/source.unit.pqueue.mk
CDSUNIT_PQUEUE_SOURCES := $(CDSUNIT_PQUEUE_SOURCES:%.cpp=../%.cpp)
CDSUNIT_PQUEUE_OBJS := $(CDSUNIT_PQUEUE_SOURCES:%.cpp=%.o)
CDSUNIT_MISC_SOURCES := $(CDSUNIT_MISC_SOURCES:%.cpp=../%.cpp)
CDSUNIT_MISC_OBJS := $(CDSUNIT_MISC_SOURCES:%.cpp=%.o)
-TEST_OBJ_FILE := $(CDSUNIT_COMMON_FILE) $(CDSUNIT_MAP_OBJS) $(CDSUNIT_SET_OBJS) $(CDSUNIT_QUEUE_OBJS) $(CDSUNIT_PQUEUE_OBJS) \
+TEST_OBJ_FILE := $(CDSUNIT_COMMON_FILE) $(CDSUNIT_MAP_OBJS) $(CDSUNIT_SET_OBJS) $(CDSUNIT_PQUEUE_OBJS) \
$(CDSUNIT_STACK_OBJS) $(CDSUNIT_MISC_OBJS)
TEST_OBJ_FILE_DEPS := $(TEST_OBJ_FILE:%.o=%.d)
CDSUNIT_MAP_EXE=$(BIN_PATH)/cdsu-map
CDSUNIT_SET_EXE=$(BIN_PATH)/cdsu-set
-CDSUNIT_QUEUE_EXE=$(BIN_PATH)/cdsu-queue
CDSUNIT_PQUEUE_EXE=$(BIN_PATH)/cdsu-pqueue
CDSUNIT_MISC_EXE=$(BIN_PATH)/cdsu-misc
-CDSUNIT_EXE_FILES= $(CDSUNIT_MAP_EXE) $(CDSUNIT_SET_EXE) $(CDSUNIT_QUEUE_EXE) $(CDSUNIT_PQUEUE_EXE) $(CDSUNIT_MISC_EXE)
+CDSUNIT_EXE_FILES= $(CDSUNIT_MAP_EXE) $(CDSUNIT_SET_EXE) $(CDSUNIT_PQUEUE_EXE) $(CDSUNIT_MISC_EXE)
unit-map: $(CDSUNIT_MAP_EXE)
unit-set: $(CDSUNIT_SET_EXE)
-unit-queue: $(CDSUNIT_QUEUE_EXE)
unit-pqueue: $(CDSUNIT_PQUEUE_EXE)
ifeq ($(platform),mingw)
$(CDSUNIT_SET_EXE) : $(CDSUNIT_SET_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
$(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_SET_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_LIBS) $(LDLIBS)
-$(CDSUNIT_QUEUE_EXE) : $(CDSUNIT_QUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
- $(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_QUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_LIBS) $(LDLIBS)
-
$(CDSUNIT_PQUEUE_EXE) : $(CDSUNIT_PQUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
$(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_PQUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_LIBS) $(LDLIBS)
CDSUNIT_MAP_EXE_DBG=$(CDSUNIT_MAP_EXE)-d
CDSUNIT_SET_EXE_DBG=$(CDSUNIT_SET_EXE)-d
-CDSUNIT_QUEUE_EXE_DBG=$(CDSUNIT_QUEUE_EXE)-d
CDSUNIT_PQUEUE_EXE_DBG=$(CDSUNIT_PQUEUE_EXE)-d
CDSUNIT_MISC_EXE_DBG=$(CDSUNIT_MISC_EXE)-d
-CDSUNIT_EXE_DBG_FILES= $(CDSUNIT_MAP_EXE_DBG) $(CDSUNIT_SET_EXE_DBG) $(CDSUNIT_QUEUE_EXE_DBG) $(CDSUNIT_PQUEUE_EXE_DBG) \
+CDSUNIT_EXE_DBG_FILES= $(CDSUNIT_MAP_EXE_DBG) $(CDSUNIT_SET_EXE_DBG) $(CDSUNIT_PQUEUE_EXE_DBG) \
$(CDSUNIT_MISC_EXE_DBG)
unit-map-dbg: $(CDSUNIT_MAP_EXE_DBG)
unit-set-dbg: $(CDSUNIT_SET_EXE_DBG)
-unit-queue-dbg: $(CDSUNIT_QUEUE_EXE_DBG)
unit-pqueue-dbg: $(CDSUNIT_PQUEUE_EXE_DBG)
ifeq ($(platform),mingw)
$(CDSUNIT_SET_EXE_DBG) : $(CDSUNIT_SET_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
$(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_SET_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_DEBUG_LIBS) $(LDLIBS)
-$(CDSUNIT_QUEUE_EXE_DBG) : $(CDSUNIT_QUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
- $(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_QUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_DEBUG_LIBS) $(LDLIBS)
-
$(CDSUNIT_PQUEUE_EXE_DBG) : $(CDSUNIT_PQUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS)
$(CXX) $(LD_OPTS) -L$(BIN_PATH) $(CDSUNIT_PQUEUE_OBJS) $(CDSUNIT_COMMON_FILE) $(TEST_COMMON_OBJS) -o $@ $(LD_BOOST_THREAD_LIB) $(LD_TEST_COMMON_DEBUG_LIBS) $(LDLIBS)
{408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
EndProjectSection\r
EndProject\r
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "unit-queue", "unit-queue.vcxproj", "{6C15AF8A-4A99-49F9-BCF0-1BF36771099A}"\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}") = "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("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "stress", "stress", "{10E1FAF2-904D-405E-8AB5-6878A1B03346}"\r
+ ProjectSection(SolutionItems) = preProject\r
+ ..\..\..\test\stress\michael_alloc.h = ..\..\..\test\stress\michael_alloc.h\r
+ EndProjectSection\r
EndProject\r
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-framework", "stress-framework.vcxproj", "{A34CED07-A442-4FA1-81C4-F8B9CD3C832B}"\r
EndProject\r
{408FE9BC-44F0-4E6A-89FA-D6F952584239} = {408FE9BC-44F0-4E6A-89FA-D6F952584239}\r
EndProjectSection\r
EndProject\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "stress-queue", "stress-queue.vcxproj", "{50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}"\r
+ ProjectSection(ProjectDependencies) = postProject\r
+ {A34CED07-A442-4FA1-81C4-F8B9CD3C832B} = {A34CED07-A442-4FA1-81C4-F8B9CD3C832B}\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
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Debug|Win32.ActiveCfg = Debug|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Debug|Win32.Build.0 = Debug|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Debug|x64.ActiveCfg = Debug|x64\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Debug|x64.Build.0 = Debug|x64\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.DebugVLD|Win32.ActiveCfg = Debug|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.DebugVLD|Win32.Build.0 = Debug|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.DebugVLD|x64.ActiveCfg = DebugVLD|x64\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.DebugVLD|x64.Build.0 = DebugVLD|x64\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Release|Win32.ActiveCfg = Release|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Release|Win32.Build.0 = Release|Win32\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Release|x64.ActiveCfg = Release|x64\r
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A}.Release|x64.Build.0 = Release|x64\r
{282E9A9A-386A-40FB-A483-994BACE24830}.Debug|Win32.ActiveCfg = Debug|Win32\r
{282E9A9A-386A-40FB-A483-994BACE24830}.Debug|Win32.Build.0 = Debug|Win32\r
{282E9A9A-386A-40FB-A483-994BACE24830}.Debug|x64.ActiveCfg = Debug|x64\r
{5E1C3684-9463-4A98-BAFC-9BD51F179BB6}.Release|Win32.Build.0 = Release|Win32\r
{5E1C3684-9463-4A98-BAFC-9BD51F179BB6}.Release|x64.ActiveCfg = Release|x64\r
{5E1C3684-9463-4A98-BAFC-9BD51F179BB6}.Release|x64.Build.0 = Release|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Debug|Win32.ActiveCfg = Debug|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Debug|Win32.Build.0 = Debug|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Debug|x64.ActiveCfg = Debug|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Debug|x64.Build.0 = Debug|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.DebugVLD|Win32.ActiveCfg = DebugVLD|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.DebugVLD|Win32.Build.0 = DebugVLD|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.DebugVLD|x64.ActiveCfg = DebugVLD|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.DebugVLD|x64.Build.0 = DebugVLD|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Release|Win32.ActiveCfg = Release|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Release|Win32.Build.0 = Release|Win32\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.Release|x64.ActiveCfg = Release|x64\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}.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
- {6C15AF8A-4A99-49F9-BCF0-1BF36771099A} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
{282E9A9A-386A-40FB-A483-994BACE24830} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75}\r
{C5E76975-B87B-4B9E-8596-B01DDA683FCA} = {B8C24D26-A3BF-4DA6-B64C-142CBA4BFE75}\r
{6BB7A27F-FC59-4267-B6FA-D034176D1459} = {B30CA283-1796-4763-92C3-2E4848D443F7}\r
{83FC591C-2CA2-4631-AD13-218FF4C27692} = {810490B7-31E5-49AE-8455-CAF99A9658B6}\r
{A34CED07-A442-4FA1-81C4-F8B9CD3C832B} = {10E1FAF2-904D-405E-8AB5-6878A1B03346}\r
{5E1C3684-9463-4A98-BAFC-9BD51F179BB6} = {10E1FAF2-904D-405E-8AB5-6878A1B03346}\r
+ {50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C} = {10E1FAF2-904D-405E-8AB5-6878A1B03346}\r
EndGlobalSection\r
GlobalSection(DPCodeReviewSolutionGUID) = preSolution\r
DPCodeReviewSolutionGUID = {00000000-0000-0000-0000-000000000000}\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\..\test\include\cds_test\stress_test.h" />\r
+ <ClInclude Include="..\..\..\test\stress\framework\michael_alloc.h" />\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="..\..\..\test\stress\framework\city.cpp">\r
<DisableSpecificWarnings Condition="'$(Configuration)|$(Platform)'=='Release|x64'">4267</DisableSpecificWarnings>\r
</ClCompile>\r
<ClCompile Include="..\..\..\test\stress\framework\config.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\framework\michael_alloc.cpp" />\r
<ClCompile Include="..\..\..\test\stress\framework\stress_test.cpp" />\r
</ItemGroup>\r
<ItemGroup>\r
<ClInclude Include="..\..\..\test\include\cds_test\stress_test.h">\r
<Filter>Header Files</Filter>\r
</ClInclude>\r
+ <ClInclude Include="..\..\..\test\stress\framework\michael_alloc.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
</ItemGroup>\r
<ItemGroup>\r
<ClCompile Include="..\..\..\test\stress\framework\config.cpp">\r
<ClCompile Include="..\..\..\test\stress\framework\stress_test.cpp">\r
<Filter>Source Files</Filter>\r
</ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\framework\michael_alloc.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
</ItemGroup>\r
<ItemGroup>\r
<CustomBuild Include="..\..\..\test\stress\data\text.txt" />\r
--- /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="Release|Win32">\r
+ <Configuration>Release</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|x64">\r
+ <Configuration>Release</Configuration>\r
+ <Platform>x64</Platform>\r
+ </ProjectConfiguration>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\test\stress\main.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\queue\bounded_queue_fulness.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\queue\intrusive_push_pop.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\queue\pop.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\queue\push.cpp" />\r
+ <ClCompile Include="..\..\..\test\stress\queue\push_pop.cpp">\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ <AdditionalOptions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">/bigobj %(AdditionalOptions)</AdditionalOptions>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\random.cpp" />\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="..\..\..\test\stress\queue\intrusive_queue_type.h" />\r
+ <ClInclude Include="..\..\..\test\stress\queue\print_stat.h" />\r
+ <ClInclude Include="..\..\..\test\stress\queue\queue_type.h" />\r
+ <ClInclude Include="..\..\..\test\stress\queue\std_queue.h" />\r
+ </ItemGroup>\r
+ <PropertyGroup Label="Globals">\r
+ <ProjectGuid>{50B2EC4B-A118-4E7B-ABC7-2EA8B685A58C}</ProjectGuid>\r
+ <Keyword>Win32Proj</Keyword>\r
+ <RootNamespace>stress_queue</RootNamespace>\r
+ <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
+ <ProjectName>stress-queue</ProjectName>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>true</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
+ <ConfigurationType>Application</ConfigurationType>\r
+ <UseDebugLibraries>false</UseDebugLibraries>\r
+ <PlatformToolset>v140</PlatformToolset>\r
+ <WholeProgramOptimization>true</WholeProgramOptimization>\r
+ <CharacterSet>Unicode</CharacterSet>\r
+ </PropertyGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
+ <ImportGroup Label="ExtensionSettings">\r
+ </ImportGroup>\r
+ <ImportGroup Label="Shared">\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\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|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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />\r
+ </ImportGroup>\r
+ <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\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 Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\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 Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <TargetName>$(ProjectName)_d</TargetName>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <TargetName>$(ProjectName)_d</TargetName>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <TargetName>$(ProjectName)_d</TargetName>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
+ <LinkIncremental>true</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ <TargetName>$(ProjectName)_d</TargetName>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <LinkIncremental>false</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <LinkIncremental>false</LinkIncremental>\r
+ <OutDir>$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)-release\</OutDir>\r
+ <IntDir>$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
+ </PropertyGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">\r
+ <ClCompile>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <Optimization>Disabled</Optimization>\r
+ <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtestd.lib;stress-framework_d.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB32);$(GTEST_ROOT)/lib/x86;$(BOOST_PATH)/stage32/lib;$(BOOST_PATH)/stage/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtest.lib;stres-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">\r
+ <ClCompile>\r
+ <WarningLevel>Level3</WarningLevel>\r
+ <PrecompiledHeader>NotUsing</PrecompiledHeader>\r
+ <Optimization>MaxSpeed</Optimization>\r
+ <FunctionLevelLinking>true</FunctionLevelLinking>\r
+ <IntrinsicFunctions>true</IntrinsicFunctions>\r
+ <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
+ <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(GTEST_ROOT)/include;$(SolutionDir)..\..\..\test\include;$(SolutionDir)..\..\..\test\stress;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
+ </ClCompile>\r
+ <Link>\r
+ <SubSystem>Console</SubSystem>\r
+ <EnableCOMDATFolding>true</EnableCOMDATFolding>\r
+ <OptimizeReferences>true</OptimizeReferences>\r
+ <GenerateDebugInformation>true</GenerateDebugInformation>\r
+ <AdditionalLibraryDirectories>$(GTEST_LIB64);$(GTEST_ROOT)/lib/x64;$(BOOST_PATH)/stage64/lib;$(BOOST_PATH)/bin;%(AdditionalLibraryDirectories);$(OutDir)</AdditionalLibraryDirectories>\r
+ <AdditionalDependencies>gtest.lib;stres-framework.lib;%(AdditionalDependencies)</AdditionalDependencies>\r
+ </Link>\r
+ </ItemDefinitionGroup>\r
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />\r
+ <ImportGroup Label="ExtensionTargets">\r
+ </ImportGroup>\r
+</Project>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+ <ItemGroup>\r
+ <Filter Include="Source Files">\r
+ <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>\r
+ <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>\r
+ </Filter>\r
+ <Filter Include="Header Files">\r
+ <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>\r
+ <Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>\r
+ </Filter>\r
+ <Filter Include="Resource Files">\r
+ <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>\r
+ <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>\r
+ </Filter>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClCompile Include="..\..\..\test\stress\main.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\push.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\pop.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\push_pop.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\random.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\bounded_queue_fulness.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ <ClCompile Include="..\..\..\test\stress\queue\intrusive_push_pop.cpp">\r
+ <Filter>Source Files</Filter>\r
+ </ClCompile>\r
+ </ItemGroup>\r
+ <ItemGroup>\r
+ <ClInclude Include="..\..\..\test\stress\queue\queue_type.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\test\stress\queue\std_queue.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\test\stress\queue\intrusive_queue_type.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ <ClInclude Include="..\..\..\test\stress\queue\print_stat.h">\r
+ <Filter>Header Files</Filter>\r
+ </ClInclude>\r
+ </ItemGroup>\r
+</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>{6C15AF8A-4A99-49F9-BCF0-1BF36771099A}</ProjectGuid>\r
- <RootNamespace>unitqueue</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)'=='Release|Win32'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>Unicode</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>Unicode</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>Unicode</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>Unicode</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>Unicode</CharacterSet>\r
- <PlatformToolset>v140</PlatformToolset>\r
- </PropertyGroup>\r
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" Label="Configuration">\r
- <ConfigurationType>Application</ConfigurationType>\r
- <CharacterSet>Unicode</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)'=='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|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|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
- <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
- <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
- <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</LinkIncremental>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">false</LinkIncremental>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <OutDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">$(SolutionDir)..\..\..\bin\vc.$(PlatformToolset)\$(Platform)\</OutDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <IntDir Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">$(SolutionDir)..\..\..\obj\vc.$(PlatformToolset)\$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</LinkIncremental>\r
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='DebugVLD|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
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugVLD|Win32'" />\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'">AllRules.ruleset</CodeAnalysisRuleSet>\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
- <CodeAnalysisRules Condition="'$(Configuration)|$(Platform)'=='DebugVLD|x64'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" />\r
- <CodeAnalysisRuleAssemblies Condition="'$(Configuration)|$(Platform)'=='DebugVLD|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)'=='DebugVLD|Win32'">$(ProjectName)_d</TargetName>\r
- <TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(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\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_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
- <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
- <TargetMachine>MachineX86</TargetMachine>\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\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_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
- <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
- <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\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_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
- <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
- <TargetMachine>MachineX64</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\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>CDS_USE_VLD;WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_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
- <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
- <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>MaxSpeed</Optimization>\r
- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
- <IntrinsicFunctions>true</IntrinsicFunctions>\r
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
- <FunctionLevelLinking>true</FunctionLevelLinking>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites.lib;%(AdditionalDependencies)</AdditionalDependencies>\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
- <TargetMachine>MachineX86</TargetMachine>\r
- <OutputFile>$(TargetPath)</OutputFile>\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>MaxSpeed</Optimization>\r
- <InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>\r
- <IntrinsicFunctions>true</IntrinsicFunctions>\r
- <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>\r
- <AdditionalIncludeDirectories>$(SolutionDir)..\..\..;$(SolutionDir)..\..\..\tests\unit;$(SolutionDir)..\..\..\tests;$(BOOST_PATH);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\r
- <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_SCL_SECURE=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>\r
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\r
- <FunctionLevelLinking>true</FunctionLevelLinking>\r
- <PrecompiledHeader>\r
- </PrecompiledHeader>\r
- <WarningLevel>Level3</WarningLevel>\r
- <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>\r
- <DisableSpecificWarnings>4520</DisableSpecificWarnings>\r
- </ClCompile>\r
- <Link>\r
- <AdditionalDependencies>unit-prerequisites.lib;%(AdditionalDependencies)</AdditionalDependencies>\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
- <TargetMachine>MachineX64</TargetMachine>\r
- <OutputFile>$(TargetPath)</OutputFile>\r
- <ForceFileOutput>MultiplyDefinedSymbolOnly</ForceFileOutput>\r
- </Link>\r
- </ItemDefinitionGroup>\r
- <ItemGroup>\r
- <ClCompile Include="..\..\..\tests\unit\queue\bounded_queue_fulness.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\queue\intrusive_queue_reader_writer.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\queue\queue_pop.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\queue\queue_push.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\queue\queue_random.cpp" />\r
- <ClCompile Include="..\..\..\tests\unit\queue\queue_reader_writer.cpp" />\r
- </ItemGroup>\r
- <ItemGroup>\r
- <ClInclude Include="..\..\..\tests\unit\queue\intrusive_queue_defs.h" />\r
- <ClInclude Include="..\..\..\tests\unit\queue\intrusive_queue_type.h" />\r
- <ClInclude Include="..\..\..\tests\unit\queue\queue_defs.h" />\r
- <ClInclude Include="..\..\..\tests\unit\queue\queue_type.h" />\r
- <ClInclude Include="..\..\..\tests\unit\queue\std_queue.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
-
-CDSUNIT_QUEUE_SOURCES := \
- tests/unit/queue/bounded_queue_fulness.cpp \
- tests/unit/queue/queue_pop.cpp \
- tests/unit/queue/queue_push.cpp \
- tests/unit/queue/queue_random.cpp \
- tests/unit/queue/queue_reader_writer.cpp \
- tests/unit/queue/intrusive_queue_reader_writer.cpp
set(CDSSTRESS_FRAMEWORK_SOURCES
framework/city.cpp
framework/config.cpp
+ framework/michael_alloc.cpp
framework/stress_test.cpp
)
add_library(${CDSSTRESS_FRAMEWORK_LIBRARY} OBJECT ${CDSSTRESS_FRAMEWORK_SOURCES})
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/queue)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/stack)
file(GLOB CONF_FILES ${PROJECT_SOURCE_DIR}/test/stress/data/*.conf)
FCCombinePassCount=4\r
FCCompactFactor=64\r
\r
-[Queue_Push]\r
-ThreadCount=8\r
+[queue_push]\r
+ThreadCount=4\r
QueueSize=100000\r
-\r
-[Queue_Pop]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_pop]\r
ThreadCount=8\r
QueueSize=100000\r
-\r
-[Queue_ReaderWriter]\r
-ReaderCount=3\r
-WriterCount=3\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_push_pop]\r
+ProducerCount=3\r
+ConsumerCount=3\r
QueueSize=100000\r
-\r
-[IntrusiveQueue_ReaderWriter]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_random]\r
+ThreadCount=4\r
+QueueSize=500000\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[intrusive_queue_push_pop]\r
ReaderCount=3\r
WriterCount=3\r
QueueSize=100000\r
-\r
-[Queue_Random]\r
-ThreadCount=4\r
-QueueSize=500000\r
-\r
-[BoundedQueue_Fullness]\r
+# Flat combining queue parameters\r
+FCCompactFactor=64\r
+FCPassCount=8\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[bounded_queue_fulness]\r
ThreadCount=4\r
QueueSize=1024\r
PassCount=100000\r
FCCombinePassCount=4\r
FCCompactFactor=64\r
\r
-[Queue_Push]\r
+[queue_push]\r
ThreadCount=8\r
QueueSize=500000\r
-\r
-[Queue_Pop]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_pop]\r
ThreadCount=8\r
QueueSize=500000\r
-\r
-[Queue_ReaderWriter]\r
-ReaderCount=4\r
-WriterCount=4\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_push_pop]\r
+ConsumerCount=4\r
+ProducerCount=4\r
QueueSize=500000\r
-\r
-[IntrusiveQueue_ReaderWriter]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[queue_random]\r
+ThreadCount=8\r
+QueueSize=500000\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[intrusive_queue_push_pop]\r
ReaderCount=4\r
WriterCount=4\r
QueueSize=500000\r
-\r
-[Queue_Random]\r
-ThreadCount=8\r
-QueueSize=500000\r
-\r
-[BoundedQueue_Fullness]\r
+# Flat combining queue parameters\r
+FCCompactFactor=64\r
+FCPassCount=8\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=64\r
+\r
+[bounded_queue_fulness]\r
ThreadCount=4\r
QueueSize=1024\r
PassCount=100000\r
FCCombinePassCount=8\r
FCCompactFactor=64\r
\r
-[Queue_Push]\r
+[queue_push]\r
ThreadCount=8\r
QueueSize=5000000\r
-\r
-[Queue_Pop]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=256\r
+\r
+[queue_pop]\r
ThreadCount=8\r
QueueSize=5000000\r
-\r
-[Queue_ReaderWriter]\r
-ReaderCount=4\r
-WriterCount=4\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=256\r
+\r
+[queue_push_pop]\r
+ConsumerCount=4\r
+ProducerCount=4\r
QueueSize=5000000\r
-\r
-[IntrusiveQueue_ReaderWriter]\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=256\r
+\r
+[queue_random]\r
+ThreadCount=8\r
+QueueSize=5000000\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=256\r
+\r
+[intrusive_queue_push_pop]\r
ReaderCount=4\r
WriterCount=4\r
QueueSize=5000000\r
-\r
-[Queue_Random]\r
-ThreadCount=8\r
-QueueSize=5000000\r
-\r
-[BoundedQueue_Fullness]\r
+# Flat combining queue parameters\r
+FCCompactFactor=64\r
+FCPassCount=8\r
+# SegmentedQueue parameters:\r
+# SegmentedQueue_Iterate: \r
+# 1 - run test iteratively for segment size from 4 up to SegmentedQueue_SegmentSize\r
+# 0 - run test for segment size equal to SegmentedQueue_SegmentSize\r
+SegmentedQueue_Iterate=0\r
+SegmentedQueue_SegmentSize=256\r
+\r
+[bounded_queue_fulness]\r
ThreadCount=8\r
QueueSize=1024\r
PassCount=1000000\r
--- /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 "michael_alloc.h"
+
+namespace memory {
+ michael_heap s_MichaelHeap;
+}
--- /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 CDSSTRESS_MICHAEL_ALLOC_H
+#define CDSSTRESS_MICHAEL_ALLOC_H
+
+#include <cds/memory/michael/allocator.h>
+#include <memory>
+
+namespace memory {
+
+ typedef cds::memory::michael::Heap<
+ cds::memory::michael::opt::check_bounds< cds::memory::michael::debug_bound_checking >
+ > michael_heap;
+ extern michael_heap s_MichaelHeap;
+
+ template <class T>
+ class MichaelAllocator
+ {
+ typedef std::allocator<T> std_allocator;
+ public:
+ // Declare typedefs from std::allocator
+ typedef typename std_allocator::const_pointer const_pointer;
+ typedef typename std_allocator::pointer pointer;
+ typedef typename std_allocator::const_reference const_reference;
+ typedef typename std_allocator::reference reference;
+ typedef typename std_allocator::difference_type difference_type;
+ typedef typename std_allocator::size_type size_type;
+ typedef typename std_allocator::value_type value_type;
+
+ // Allocation function
+ pointer allocate( size_type _Count, const void* /*_Hint*/ = nullptr )
+ {
+ return reinterpret_cast<pointer>( s_MichaelHeap.alloc( sizeof(T) * _Count ));
+ }
+
+ // Deallocation function
+ void deallocate( pointer _Ptr, size_type /*_Count*/ )
+ {
+ s_MichaelHeap.free( _Ptr );
+ }
+
+ pointer address( reference r ) const
+ {
+ return &r;
+ }
+ const_pointer address( const_reference r ) const
+ {
+ return &r;
+ }
+ void construct( pointer p, const T& val )
+ {
+ return new( p ) T( val );
+ }
+ void destroy( pointer p )
+ {
+ p->T::~T();
+ }
+
+ // Rebinding allocator to other type
+ template <class Other>
+ struct rebind {
+ typedef MichaelAllocator<Other> other;
+ };
+ };
+} // namespace memory
+
+#endif // #ifndef CDSSTRESS_MICHAEL_ALLOC_H
--- /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 CDSUNIT_LOCK_WIN32_LOCK_H
+#define CDSUNIT_LOCK_WIN32_LOCK_H
+
+#if defined(_WIN32) || defined(_WIN64)
+#define NOMINMAX
+#include <windows.h>
+
+#define UNIT_LOCK_WIN_CS
+
+namespace lock {
+ namespace win {
+ // Win32 critical section
+ class CS {
+ CRITICAL_SECTION m_cs;
+
+ public:
+ CS() { ::InitializeCriticalSection( &m_cs ) ; }
+ ~CS() { ::DeleteCriticalSection( &m_cs ) ; }
+
+ void lock() { ::EnterCriticalSection( &m_cs ) ; }
+ void unlock() { ::LeaveCriticalSection( &m_cs) ; }
+ bool try_lock() { return ::TryEnterCriticalSection( &m_cs ) != 0 ; }
+ };
+
+ class Mutex {
+ HANDLE m_hMutex;
+ public:
+
+ Mutex() { m_hMutex = ::CreateMutex( nullptr, false, nullptr ); }
+ ~Mutex() { ::CloseHandle( m_hMutex ) ; }
+
+ void lock() { ::WaitForSingleObject( m_hMutex, INFINITE ); }
+ void unlock() { ::ReleaseMutex( m_hMutex ); }
+ bool try_lock() { return ::WaitForSingleObject( m_hMutex, 0) == WAIT_OBJECT_0; }
+ };
+
+ } // namespace win
+} // namespace lock
+
+#endif // defined(_WIN32) || defined(_WIN64)
+#endif // #ifndef CDSUNIT_LOCK_WIN32_LOCK_H
--- /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 CDSUNIT_MICHAEL_ALLOC_H
+#define CDSUNIT_MICHAEL_ALLOC_H
+
+#include <cds/memory/michael/allocator.h>
+#include <memory>
+
+namespace memory {
+
+ typedef cds::memory::michael::Heap<
+ cds::memory::michael::opt::check_bounds< cds::memory::michael::debug_bound_checking >
+ > michael_heap;
+ extern michael_heap s_MichaelHeap;
+
+ template <class T>
+ class MichaelAllocator
+ {
+ typedef std::allocator<T> std_allocator;
+ public:
+ // Declare typedefs from std::allocator
+ typedef typename std_allocator::const_pointer const_pointer;
+ typedef typename std_allocator::pointer pointer;
+ typedef typename std_allocator::const_reference const_reference;
+ typedef typename std_allocator::reference reference;
+ typedef typename std_allocator::difference_type difference_type;
+ typedef typename std_allocator::size_type size_type;
+ typedef typename std_allocator::value_type value_type;
+
+ // Allocation function
+ pointer allocate( size_type _Count, const void* /*_Hint*/ = nullptr )
+ {
+ return reinterpret_cast<pointer>( s_MichaelHeap.alloc( sizeof(T) * _Count ));
+ }
+
+ // Deallocation function
+ void deallocate( pointer _Ptr, size_type /*_Count*/ )
+ {
+ s_MichaelHeap.free( _Ptr );
+ }
+
+ pointer address( reference r ) const
+ {
+ return &r;
+ }
+ const_pointer address( const_reference r ) const
+ {
+ return &r;
+ }
+ void construct( pointer p, const T& val )
+ {
+ return new( p ) T( val );
+ }
+ void destroy( pointer p )
+ {
+ p->T::~T();
+ }
+
+ // Rebinding allocator to other type
+ template <class Other>
+ struct rebind {
+ typedef MichaelAllocator<Other> other;
+ };
+ };
+} // namespace memory
+
+#endif // #ifndef CDSUNIT_MICHAEL_ALLOC_H
--- /dev/null
+set(PACKAGE_NAME stress-queue)
+
+set(CDSSTRESS_QUEUE_SOURCES
+ ../main.cpp
+ bounded_queue_fulness.cpp
+ intrusive_push_pop.cpp
+ pop.cpp
+ push.cpp
+ push_pop.cpp
+ random.cpp
+)
+
+include_directories(
+ ${CMAKE_CURRENT_SOURCE_DIR}
+)
+
+add_executable(${PACKAGE_NAME} ${CDSSTRESS_QUEUE_SOURCES} $<TARGET_OBJECTS:${CDSSTRESS_FRAMEWORK_LIBRARY}>)
+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 "queue_type.h"
+
+
+/*
+ Bounded queue test.
+ The test checks the behaviour of bounded queue when it is almost full.
+ Many algorithms says the queue is full when it is not, and vice versa.
+*/
+namespace {
+
+ static size_t s_nThreadCount = 8;
+ static size_t s_nQueueSize = 1024;
+ static size_t s_nPassCount = 1000000;
+
+ class bounded_queue_fulness: public cds_test::stress_fixture
+ {
+ typedef cds_test::stress_fixture base_class;
+
+ protected:
+ template <class Queue>
+ class Strain: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Queue& m_Queue;
+ size_t m_nPushError = 0;
+ size_t m_nPopError = 0;
+
+ public:
+ Strain( cds_test::thread_pool& pool, Queue& q )
+ : base_class( pool )
+ , m_Queue( q )
+ {}
+
+ Strain( Strain& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Strain( *this );
+ }
+
+ virtual void test()
+ {
+ for ( size_t i = 0; i < s_nPassCount; ++i ) {
+ if ( !m_Queue.push( i ))
+ ++m_nPushError;
+ size_t item;
+ if ( !m_Queue.pop( item ))
+ ++m_nPopError;
+ }
+ }
+ };
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "bounded_queue_fulness" );\r
+\r
+ s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+ s_nPassCount = cfg.get_size_t( "PassCount", s_nPassCount );
+
+ if ( s_nThreadCount == 0 )
+ s_nThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1024;
+ if ( s_nPassCount == 0 )
+ s_nPassCount = 1;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+
+ protected:
+ template <class Queue>
+ void analyze( Queue& q )
+ {
+ cds_test::thread_pool& pool = get_pool();
+
+ size_t nPushError = 0;
+ size_t nPopError = 0;
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Strain<Queue>& strain = static_cast<Strain<Queue> &>(pool.get( i ));
+ nPushError += strain.m_nPushError;
+ nPopError += strain.m_nPopError;
+ }
+ EXPECT_TRUE( !q.empty());
+ EXPECT_EQ( nPushError, 0 );
+ EXPECT_EQ( nPopError, 0 );
+ }
+
+ template <class Queue>
+ void test( Queue& q )
+ {
+ cds_test::thread_pool& pool = get_pool();
+ pool.add( new Strain<Queue>( pool, q ), s_nThreadCount );
+
+ size_t nSize = q.capacity() - s_nThreadCount;
+ for ( size_t i = 0; i < nSize; ++i )
+ q.push( i );
+
+ propout() << std::make_pair( "thread_count", s_nThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize )
+ << std::make_pair( "pass_count", s_nPassCount );
+
+ std::chrono::milliseconds duration = pool.run();
+ propout() << std::make_pair( "duration", duration );
+
+ analyze( q );
+
+ propout() << q.statistics();
+ }
+ };
+
+#undef CDSSTRESS_Queue_F
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< size_t >::type_name queue_type; \
+ queue_type queue( s_nQueueSize ); \
+ test( queue ); \
+ }
+
+ CDSSTRESS_TsigasQueue( bounded_queue_fulness )
+ CDSSTRESS_VyukovQueue( bounded_queue_fulness )
+
+#undef CDSSTRESS_Queue_F
+
+} // namespace queue
--- /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 "intrusive_queue_type.h"
+#include <vector>
+#include <algorithm>
+
+// Multi-threaded random queue test
+namespace {
+
+ static size_t s_nReaderThreadCount = 4;
+ static size_t s_nWriterThreadCount = 4;
+ static size_t s_nQueueSize = 4000000;
+
+ static unsigned int s_nFCPassCount = 8;
+ static unsigned int s_nFCCompactFactor = 64;
+
+ static atomics::atomic< size_t > s_nProducerCount(0);
+ static size_t s_nThreadPushCount;
+ static CDS_CONSTEXPR const size_t c_nBadConsumer = 0xbadc0ffe;
+
+ struct empty {};
+
+ template <typename Base = empty >
+ struct value_type: public Base
+ {
+ size_t nNo;
+ size_t nWriterNo;
+ size_t nConsumer;
+ };
+
+ class intrusive_queue_push_pop: public cds_test::stress_fixture
+ {
+ typedef cds_test::stress_fixture base_class;
+
+ protected:
+ enum {
+ producer_thread,
+ consumer_thread
+ };
+
+ template <class Queue>
+ class Producer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Producer( cds_test::thread_pool& pool, Queue& q )
+ : base_class( pool, producer_thread )
+ , m_Queue( q )
+ {}
+ Producer( Producer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Producer( *this );
+ }
+
+ virtual void test()
+ {
+ size_t i = 0;
+ for ( typename Queue::value_type * p = m_pStart; p < m_pEnd; ) {
+ p->nNo = i;
+ p->nWriterNo = id();
+ CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( &p->nWriterNo );
+ if ( m_Queue.push( *p )) {
+ ++p;
+ ++i;
+ }
+ else
+ ++m_nPushFailed;
+ }
+ s_nProducerCount.fetch_sub( 1, atomics::memory_order_release );
+ }
+
+ public:
+ Queue& m_Queue;
+ size_t m_nPushFailed = 0;
+
+ // Interval in m_arrValue
+ typename Queue::value_type * m_pStart;
+ typename Queue::value_type * m_pEnd;
+ };
+
+ template <class Queue>
+ class Consumer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Queue& m_Queue;
+ size_t m_nPopEmpty = 0;
+ size_t m_nPopped = 0;
+ size_t m_nBadWriter = 0;
+
+ typedef std::vector<size_t> TPoppedData;
+ typedef std::vector<size_t>::iterator data_iterator;
+ typedef std::vector<size_t>::const_iterator const_data_iterator;
+
+ std::vector<TPoppedData> m_WriterData;
+
+ private:
+ void initPoppedData()
+ {
+ const size_t nWriterCount = s_nWriterThreadCount;
+ const size_t nWriterPushCount = s_nThreadPushCount;
+ m_WriterData.resize( nWriterCount );
+ for ( size_t i = 0; i < nWriterCount; ++i )
+ m_WriterData[i].reserve( nWriterPushCount );
+ }
+
+ public:
+ Consumer( cds_test::thread_pool& pool, Queue& q )
+ : base_class( pool, consumer_thread )
+ , m_Queue( q )
+ {
+ initPoppedData();
+ }
+ Consumer( Consumer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ {
+ initPoppedData();
+ }
+
+ virtual thread * clone()
+ {
+ return new Consumer( *this );
+ }
+
+ virtual void test()
+ {
+ size_t const nTotalWriters = s_nWriterThreadCount;
+
+ while ( true ) {
+ typename Queue::value_type * p = m_Queue.pop();
+ if ( p ) {
+ p->nConsumer = id();
+ ++m_nPopped;
+ CDS_TSAN_ANNOTATE_HAPPENS_AFTER( &p->nWriterNo );
+ if ( p->nWriterNo < nTotalWriters )
+ m_WriterData[ p->nWriterNo ].push_back( p->nNo );
+ else
+ ++m_nBadWriter;
+ }
+ else {
+ ++m_nPopEmpty;
+ if ( s_nProducerCount.load( atomics::memory_order_acquire ) == 0 && m_Queue.empty() )
+ break;
+ }
+ }
+ }
+ };
+
+ template <typename T>
+ class value_array
+ {
+ std::unique_ptr<T[]> m_pArr;
+ public:
+ value_array( size_t nSize )
+ : m_pArr( new T[nSize] )
+ {}
+
+ T * get() const { return m_pArr.get(); }
+ };
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "queue_random" );\r
+\r
+ s_nReaderThreadCount = cfg.get_size_t( "ReaderCount", s_nReaderThreadCount );
+ s_nWriterThreadCount = cfg.get_size_t( "WriterCount", s_nWriterThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+
+ s_nFCPassCount = cfg.get_uint( "FCPassCount", s_nFCPassCount );
+ s_nFCCompactFactor = cfg.get_uint( "FCCompactFactor", s_nFCCompactFactor );
+
+ if ( s_nReaderThreadCount == 0 )
+ s_nReaderThreadCount = 1;
+ if ( s_nWriterThreadCount == 0 )
+ s_nWriterThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1000;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+
+ protected:
+ template <class Queue>
+ void analyze( Queue& testQueue, size_t /*nLeftOffset*/, size_t nRightOffset )
+ {
+ typedef Consumer<Queue> Reader;
+ typedef Producer<Queue> Writer;
+ typedef typename Reader::const_data_iterator ReaderIterator;
+
+ size_t nPostTestPops = 0;
+ while ( testQueue.pop() )
+ ++nPostTestPops;
+
+ size_t nTotalPops = 0;
+ size_t nPopFalse = 0;
+ size_t nPoppedItems = 0;
+ size_t nPushFailed = 0;
+
+ std::vector< Reader * > arrReaders;
+
+ cds_test::thread_pool& pool = get_pool();
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ cds_test::thread& thr = pool.get( i );
+ if ( thr.type() == consumer_thread ) {
+ Consumer<Queue>& consumer = static_cast<Consumer<Queue>&>( thr );
+ nTotalPops += consumer.m_nPopped;
+ nPopFalse += consumer.m_nPopEmpty;
+ arrReaders.push_back( &consumer );
+ EXPECT_EQ( consumer.m_nBadWriter, 0 ) << "consumer " << (i - s_nWriterThreadCount);
+
+ size_t nPopped = 0;
+ for ( size_t n = 0; n < s_nWriterThreadCount; ++n )
+ nPopped += consumer.m_WriterData[n].size();
+
+ {
+ std::stringstream s;
+ s << "consumer" << (i - s_nWriterThreadCount) << "_popped";
+ propout() << std::make_pair( s.str().c_str(), nPopped );
+ }
+ nPoppedItems += nPopped;
+ }
+ else {
+ Producer<Queue>& producer = static_cast<Producer<Queue>&>( thr );
+ nPushFailed += producer.m_nPushFailed;
+ if ( !std::is_base_of<cds::bounded_container, Queue>::value ) {
+ EXPECT_EQ( producer.m_nPushFailed, 0 ) << "producer " << i;
+ }
+ }
+ }
+ EXPECT_EQ( nTotalPops, nPoppedItems );
+
+ propout() << std::make_pair( "success_pop", nTotalPops )
+ << std::make_pair( "empty_pop", nPopFalse )
+ << std::make_pair( "failed_push", nPushFailed );
+
+ size_t nQueueSize = s_nThreadPushCount * s_nWriterThreadCount;
+ EXPECT_EQ( nTotalPops + nPostTestPops, nQueueSize );
+ EXPECT_TRUE( testQueue.empty() );
+
+ // Test that all items have been popped
+ // Test FIFO order
+ for ( size_t nWriter = 0; nWriter < s_nWriterThreadCount; ++nWriter ) {
+ std::vector<size_t> arrData;
+ arrData.reserve( s_nThreadPushCount );
+ for ( size_t nReader = 0; nReader < arrReaders.size(); ++nReader ) {
+ ReaderIterator it = arrReaders[nReader]->m_WriterData[nWriter].begin();
+ ReaderIterator itEnd = arrReaders[nReader]->m_WriterData[nWriter].end();
+ if ( it != itEnd ) {
+ ReaderIterator itPrev = it;
+ for ( ++it; it != itEnd; ++it ) {
+ EXPECT_LT( *itPrev, *it + nRightOffset )
+ << "Reader " << nReader << ", Writer " << nWriter << ": prev=" << *itPrev << ", cur=" << *it;
+ itPrev = it;
+ }
+ }
+
+ for ( it = arrReaders[nReader]->m_WriterData[nWriter].begin(); it != itEnd; ++it )
+ arrData.push_back( *it );
+ }
+ std::sort( arrData.begin(), arrData.end() );
+ for ( size_t i=1; i < arrData.size(); ++i ) {
+ if ( arrData[i-1] + 1 != arrData[i] ) {
+ EXPECT_EQ( arrData[i-1] + 1, arrData[i] ) << "Writer " << nWriter << ": [" << (i-1) << "]=" << arrData[i-1]
+ << ", [" << i << "]=" << arrData[i];
+ }
+ }
+
+ EXPECT_EQ( arrData[0], 0 ) << "Writer " << nWriter;
+ EXPECT_EQ( arrData[arrData.size() - 1], s_nThreadPushCount - 1 ) << "Writer " << nWriter;
+ }
+ }
+
+ template <class Queue>
+ void test( Queue& q, value_array<typename Queue::value_type>& arrValue, size_t nLeftOffset, size_t nRightOffset )
+ {
+ s_nThreadPushCount = s_nQueueSize / s_nWriterThreadCount;
+ s_nQueueSize = s_nThreadPushCount * s_nWriterThreadCount;
+ propout() << std::make_pair( "producer_count", s_nWriterThreadCount )
+ << std::make_pair( "consumer_count", s_nReaderThreadCount )
+ << std::make_pair( "queue_size", s_nQueueSize );
+
+ typename Queue::value_type * pValStart = arrValue.get();
+ typename Queue::value_type * pValEnd = pValStart + s_nQueueSize;
+
+ cds_test::thread_pool& pool = get_pool();
+ s_nProducerCount.store( s_nWriterThreadCount, atomics::memory_order_release );
+
+ // Writers must be first
+ pool.add( new Producer<Queue>( pool, q ), s_nWriterThreadCount );
+ {
+ for ( typename Queue::value_type * it = pValStart; it != pValEnd; ++it ) {
+ it->nNo = 0;
+ it->nWriterNo = 0;
+ it->nConsumer = c_nBadConsumer;
+ }
+
+ typename Queue::value_type * pStart = pValStart;
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Producer<Queue>& producer = static_cast<Producer<Queue>&>( pool.get( i ));
+ producer.m_pStart = pStart;
+ pStart += s_nThreadPushCount;
+ producer.m_pEnd = pStart;
+ }
+ }
+ pool.add( new Consumer<Queue>( pool, q ), s_nReaderThreadCount );
+
+ std::chrono::milliseconds duration = pool.run();
+ propout() << std::make_pair( "duration", duration );
+
+ // Check that all values have been dequeued
+ {
+ size_t nBadConsumerCount = 0;
+ typename Queue::value_type * pEnd = pValStart + s_nQueueSize;
+ for ( typename Queue::value_type * it = pValStart; it != pEnd; ++it ) {
+ if ( it->nConsumer == c_nBadConsumer )
+ ++nBadConsumerCount;
+ }
+ EXPECT_EQ( nBadConsumerCount, 0 );
+ }
+
+ analyze( q, nLeftOffset, nRightOffset );
+
+ propout() << q.statistics();
+ }
+
+/*
+ template <typename Queue>
+ void test( Queue& q )
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ {
+ {
+ Queue q;
+ test_with( q, arrValue, 0, 0 );
+ }
+ Queue::gc::force_dispose();
+ }
+ }
+
+ template <typename Queue>
+ void test_boost()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ {
+ Queue q;
+ test_with(q, arrValue, 0, 0);
+ }
+ }
+
+ template <typename Queue>
+ void test_bounded()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ Queue q;
+ test_with(q, arrValue, 0, 0);
+ }
+
+ template <typename Queue>
+ void test_fcqueue()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ CPPUNIT_MSG( "Combining pass count: " << s_nFCPassCount << ", compact factor: " << s_nFCCompactFactor );
+ Queue q( s_nFCCompactFactor, s_nFCPassCount );
+ test_with(q, arrValue, 0, 0);
+ }
+
+ template <typename Queue>
+ void test_segmented()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
+ CPPUNIT_MSG( "Segment size: " << nSegmentSize );
+ {
+ Queue q( nSegmentSize );
+ test_with( q, arrValue, nSegmentSize * 2, nSegmentSize );
+ }
+ Queue::gc::force_dispose();
+ }
+ }
+
+ template <typename Queue>
+ void test_spqueue()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize );
+ for ( size_t nArraySize = 2; nArraySize <= 64; nArraySize *= 2 ) {
+ CPPUNIT_MSG( "Array size: " << nArraySize );
+ {
+ Queue q( nArraySize );
+ test_with( q, arrValue, 0, 0 );
+ }
+ Queue::gc::force_dispose();
+ }
+ }
+*/
+ };
+
+#define CDSSTRESS_QUEUE_F( QueueType, NodeType ) \
+ TEST_F( intrusive_queue_push_pop, QueueType ) \
+ { \
+ typedef value_type<NodeType> node_type; \
+ typedef typename queue::Types< node_type >::QueueType queue_type; \
+ value_array<typename queue_type::value_type> arrValue( s_nQueueSize ); \
+ { \
+ queue_type q; \
+ test( q, arrValue, 0, 0 ); \
+ } \
+ queue_type::gc::force_dispose(); \
+ }
+
+ CDSSTRESS_QUEUE_F( MSQueue_HP, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MSQueue_HP_ic, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MSQueue_HP_stat, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MSQueue_DHP, cds::intrusive::msqueue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( MSQueue_DHP_ic, cds::intrusive::msqueue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( MSQueue_DHP_stat, cds::intrusive::msqueue::node<cds::gc::DHP> )
+
+ CDSSTRESS_QUEUE_F( MoirQueue_HP, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MoirQueue_HP_ic, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MoirQueue_HP_stat, cds::intrusive::msqueue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( MoirQueue_DHP, cds::intrusive::msqueue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( MoirQueue_DHP_ic, cds::intrusive::msqueue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( MoirQueue_DHP_stat, cds::intrusive::msqueue::node<cds::gc::DHP> )
+
+ CDSSTRESS_QUEUE_F( OptimisticQueue_HP, cds::intrusive::optimistic_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( OptimisticQueue_HP_ic, cds::intrusive::optimistic_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( OptimisticQueue_HP_stat, cds::intrusive::optimistic_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( OptimisticQueue_DHP, cds::intrusive::optimistic_queue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( OptimisticQueue_DHP_ic, cds::intrusive::optimistic_queue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( OptimisticQueue_DHP_stat, cds::intrusive::optimistic_queue::node<cds::gc::DHP> )
+
+ CDSSTRESS_QUEUE_F( BasketQueue_HP, cds::intrusive::basket_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( BasketQueue_HP_ic, cds::intrusive::basket_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( BasketQueue_HP_stat, cds::intrusive::basket_queue::node<cds::gc::HP> )
+ CDSSTRESS_QUEUE_F( BasketQueue_DHP, cds::intrusive::basket_queue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( BasketQueue_DHP_ic, cds::intrusive::basket_queue::node<cds::gc::DHP> )
+ CDSSTRESS_QUEUE_F( BasketQueue_DHP_stat, cds::intrusive::basket_queue::node<cds::gc::DHP> )
+#undef CDSSTRESS_QUEUE_F
+
+
+#define CDSSTRESS_QUEUE_F( QueueType, NodeType ) \
+ TEST_F( intrusive_queue_push_pop, QueueType ) \
+ { \
+ typedef value_type<NodeType> node_type; \
+ typedef typename queue::Types< node_type >::QueueType queue_type; \
+ value_array<typename queue_type::value_type> arrValue( s_nQueueSize ); \
+ queue_type q( s_nFCCompactFactor, s_nFCPassCount ); \
+ test( q, arrValue, 0, 0 ); \
+ }
+
+ CDSSTRESS_QUEUE_F(FCQueue_list_delay2, boost::intrusive::list_base_hook<> )
+ CDSSTRESS_QUEUE_F(FCQueue_list_delay2_elimination, boost::intrusive::list_base_hook<> )
+ CDSSTRESS_QUEUE_F(FCQueue_list_delay2_elimination_stat, boost::intrusive::list_base_hook<> )
+ CDSSTRESS_QUEUE_F(FCQueue_list_expbackoff_elimination, boost::intrusive::list_base_hook<> )
+ CDSSTRESS_QUEUE_F(FCQueue_list_expbackoff_elimination_stat, boost::intrusive::list_base_hook<> )
+#undef CDSSTRESS_QUEUE_F
+
+
+#define CDSSTRESS_QUEUE_F( QueueType ) \
+ TEST_F( intrusive_queue_push_pop, QueueType ) \
+ { \
+ typedef typename queue::Types< value_type<> >::QueueType queue_type; \
+ value_array<typename queue_type::value_type> arrValue( s_nQueueSize ); \
+ queue_type q( s_nQueueSize ); \
+ test( q, arrValue, 0, 0 ); \
+ }
+
+ CDSSTRESS_QUEUE_F( TsigasCycleQueue_dyn )
+ CDSSTRESS_QUEUE_F( TsigasCycleQueue_dyn_ic )
+ CDSSTRESS_QUEUE_F( VyukovMPMCCycleQueue_dyn )
+ CDSSTRESS_QUEUE_F( VyukovMPMCCycleQueue_dyn_ic )
+#undef CDSSTRESS_QUEUE_F
+
+
+ // ********************************************************************
+ // SegmentedQueue test
+
+ class intrusive_segmented_queue_push_pop
+ : public intrusive_queue_push_pop
+ , public ::testing::WithParamInterface< size_t >
+ {
+ typedef intrusive_queue_push_pop base_class;
+
+ protected:
+ template <typename Queue>
+ void test()
+ {
+ value_array<typename Queue::value_type> arrValue( s_nQueueSize ); \
+ {
+ size_t quasi_factor = GetParam();
+
+ Queue q( quasi_factor );
+ propout() << std::make_pair( "quasi_factor", quasi_factor );
+
+ base_class::test( q, arrValue, quasi_factor * 2, quasi_factor );
+ }
+ Queue::gc::force_dispose();
+ }
+
+ public:
+ static std::vector< size_t > get_test_parameters()
+ {
+ cds_test::config const& cfg = cds_test::stress_fixture::get_config( "intrusive_queue_push_pop" );
+ bool bIterative = cfg.get_bool( "SegmentedQueue_Iterate", false );
+ size_t quasi_factor = cfg.get_size_t( "SegmentedQueue_SegmentSize", 256 );
+
+ std::vector<size_t> args;
+ if ( bIterative && quasi_factor > 4 ) {
+ for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 )
+ args.push_back( qf );
+ }
+ else {
+ if ( quasi_factor > 2 )
+ args.push_back( quasi_factor );
+ else
+ args.push_back( 2 );
+ }
+
+ return args;
+ }
+ };
+
+#define CDSSTRESS_QUEUE_F( type_name ) \
+ TEST_P( intrusive_segmented_queue_push_pop, type_name ) \
+ { \
+ typedef typename queue::Types<value_type<>>::type_name queue_type; \
+ test< queue_type >(); \
+ }
+
+ CDSSTRESS_QUEUE_F( SegmentedQueue_HP_spin )
+ //CDSSTRESS_QUEUE_F( SegmentedQueue_HP_spin_padding )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_HP_spin_stat )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_HP_mutex )
+ //CDSSTRESS_QUEUE_F( SegmentedQueue_HP_mutex_padding )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_HP_mutex_stat )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_spin )
+ //CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_spin_padding )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_spin_stat )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_mutex )
+ //CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_mutex_padding )
+ CDSSTRESS_QUEUE_F( SegmentedQueue_DHP_mutex_stat )
+
+ INSTANTIATE_TEST_CASE_P( SQ,
+ intrusive_segmented_queue_push_pop,
+ ::testing::ValuesIn( intrusive_segmented_queue_push_pop::get_test_parameters() ) );
+
+} // 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.
+*/
+
+#ifndef CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H
+#define CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H
+
+#include <cds/intrusive/msqueue.h>
+#include <cds/intrusive/moir_queue.h>
+#include <cds/intrusive/optimistic_queue.h>
+#include <cds/intrusive/tsigas_cycle_queue.h>
+#include <cds/intrusive/vyukov_mpmc_cycle_queue.h>
+#include <cds/intrusive/basket_queue.h>
+#include <cds/intrusive/fcqueue.h>
+#include <cds/intrusive/segmented_queue.h>
+
+#include <cds/gc/hp.h>
+#include <cds/gc/dhp.h>
+
+#include <boost/intrusive/slist.hpp>
+
+#include <cds_test/stress_test.h>
+#include "print_stat.h"
+
+namespace queue {
+
+ namespace details {
+ struct empty_stat {};
+
+ template <typename T, typename Lock=std::mutex>
+ class BoostSList
+ {
+ typedef boost::intrusive::slist< T, boost::intrusive::cache_last<true> > slist_type;
+ typedef Lock lock_type;
+ typedef std::lock_guard<lock_type> lock_guard;
+
+ slist_type m_List;
+ mutable lock_type m_Lock;
+ public:
+ typedef T value_type;
+
+ public:
+ bool push( value_type& v )
+ {
+ lock_guard l( m_Lock );
+ m_List.push_back( v );
+ return true;
+ }
+
+ bool enqueue( value_type& v )
+ {
+ return push( v );
+ }
+
+ value_type * pop()
+ {
+ lock_guard l( m_Lock );
+ if ( m_List.empty() )
+ return nullptr;
+ value_type& v = m_List.front();
+ m_List.pop_front();
+ return &v;
+ }
+ value_type * deque()
+ {
+ return pop();
+ }
+
+ bool empty() const
+ {
+ lock_guard l( m_Lock );
+ return m_List.empty();
+ }
+
+ size_t size() const
+ {
+ lock_guard l( m_Lock );
+ return m_List.size();
+ }
+
+ empty_stat statistics() const
+ {
+ return empty_stat();
+ }
+ };
+ } // namespace details
+
+ template <typename T>
+ struct Types
+ {
+ // MSQueue, MoirQueue
+ struct traits_MSQueue_HP : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP > MSQueue_HP;
+ typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP > MoirQueue_HP;
+
+ struct traits_MSQueue_HP_seqcst : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
+ typedef cds::opt::v::sequential_consistent memory_model;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_seqcst > MSQueue_HP_seqcst;
+ typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_seqcst > MoirQueue_HP_seqcst;
+
+ struct traits_MSQueue_DHP : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP > MSQueue_DHP;
+ typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP > MoirQueue_DHP;
+
+ struct traits_MSQueue_DHP_seqcst : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
+ typedef cds::opt::v::sequential_consistent memory_model;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_seqcst > MSQueue_DHP_seqcst;
+ typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_seqcst > MoirQueue_DHP_seqcst;
+
+ // MSQueue + item counter
+ struct traits_MSQueue_HP_ic : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_ic > MSQueue_HP_ic;
+ typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_ic > MoirQueue_HP_ic;
+
+ struct traits_MSQueue_DHP_ic : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MSQueue_DHP_ic;
+ typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MoirQueue_DHP_ic;
+
+ // MSQueue + stat
+ struct traits_MSQueue_HP_stat : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
+ typedef cds::intrusive::msqueue::stat<> stat;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_stat > MSQueue_HP_stat;
+ typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_stat > MoirQueue_HP_stat;
+
+ struct traits_MSQueue_DHP_stat : public cds::intrusive::msqueue::traits
+ {
+ typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
+ typedef cds::intrusive::msqueue::stat<> stat;
+ };
+ typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_stat > MSQueue_DHP_stat;
+ typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_stat > MoirQueue_DHP_stat;
+
+
+ // OptimisticQueue
+ struct traits_OptimisticQueue_HP : public cds::intrusive::optimistic_queue::traits
+ {
+ typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
+ };
+ typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP > OptimisticQueue_HP;
+
+ struct traits_OptimisticQueue_HP_seqcst : public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_seqcst > OptimisticQueue_HP_seqcst;
+
+ struct traits_OptimisticQueue_DHP : public cds::intrusive::optimistic_queue::traits
+ {
+ typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
+ };
+ typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP > OptimisticQueue_DHP;
+
+ struct traits_OptimisticQueue_DHP_seqcst: public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_seqcst > OptimisticQueue_DHP_seqcst;
+
+ // OptimisticQueue + item counter
+ struct traits_OptimisticQueue_HP_ic: public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_ic > OptimisticQueue_HP_ic;
+
+ struct traits_OptimisticQueue_DHP_ic: public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_ic > OptimisticQueue_DHP_ic;
+
+ // OptimisticQueue + stat
+ struct traits_OptimisticQueue_HP_stat: public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_stat > OptimisticQueue_HP_stat;
+
+ struct traits_OptimisticQueue_DHP_stat: public
+ cds::intrusive::optimistic_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> >
+ >::type
+ {};
+ typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_stat > OptimisticQueue_DHP_stat;
+
+ // TsigasCycleQueue
+ class TsigasCycleQueue_dyn
+ : public cds::intrusive::TsigasCycleQueue< T,
+ typename cds::intrusive::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ >::type
+ >
+ {
+ typedef cds::intrusive::TsigasCycleQueue< T,
+ typename cds::intrusive::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ >::type
+ > base_class;
+ public:
+ TsigasCycleQueue_dyn()
+ : base_class( 1024 * 64 )
+ {}
+
+ TsigasCycleQueue_dyn( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ class TsigasCycleQueue_dyn_ic
+ : public cds::intrusive::TsigasCycleQueue< T,
+ typename cds::intrusive::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ >
+ {
+ typedef cds::intrusive::TsigasCycleQueue< T,
+ typename cds::intrusive::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ > base_class;
+ public:
+ TsigasCycleQueue_dyn_ic()
+ : base_class( 1024 * 64 )
+ {}
+ TsigasCycleQueue_dyn_ic( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ // VyukovMPMCCycleQueue
+ struct traits_VyukovMPMCCycleQueue_dyn : public cds::intrusive::vyukov_queue::traits
+ {
+ typedef cds::opt::v::dynamic_buffer< int > buffer;
+ };
+ class VyukovMPMCCycleQueue_dyn
+ : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn >
+ {
+ typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn > base_class;
+ public:
+ VyukovMPMCCycleQueue_dyn()
+ : base_class( 1024 * 64 )
+ {}
+ VyukovMPMCCycleQueue_dyn( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ class VyukovMPMCCycleQueue_dyn_ic
+ : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic >
+ {
+ typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
+ public:
+ VyukovMPMCCycleQueue_dyn_ic()
+ : base_class( 1024 * 64 )
+ {}
+ VyukovMPMCCycleQueue_dyn_ic( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ // BasketQueue
+ struct traits_BasketQueue_HP : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP > BasketQueue_HP;
+
+ struct traits_BasketQueue_HP_seqcst: public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue<cds::gc::HP, T, traits_BasketQueue_HP_seqcst > BasketQueue_HP_seqcst;
+
+ struct traits_BasketQueue_DHP : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP > BasketQueue_DHP;
+
+ struct traits_BasketQueue_DHP_seqcst: public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::memory_model< cds::opt::v::sequential_consistent >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_seqcst > BasketQueue_DHP_seqcst;
+
+ // BasketQueue + item counter
+ struct traits_BasketQueue_HP_ic : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_ic > BasketQueue_HP_ic;
+
+ struct traits_BasketQueue_DHP_ic : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_ic > BasketQueue_DHP_ic;
+
+ // BasketQueue + stat
+ struct traits_BasketQueue_HP_stat : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
+ , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_stat > BasketQueue_HP_stat;
+
+ struct traits_BasketQueue_DHP_stat : public
+ cds::intrusive::basket_queue::make_traits <
+ cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
+ , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
+ > ::type
+ {};
+ typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_stat > BasketQueue_DHP_stat;
+
+ // FCQueue
+ class traits_FCQueue_delay2:
+ public cds::intrusive::fcqueue::make_traits<
+ cds::opt::back_off< cds::backoff::delay_of<2> >
+ >::type
+ {};
+ class traits_FCQueue_delay2_elimination:
+ public cds::intrusive::fcqueue::make_traits<
+ cds::opt::back_off< cds::backoff::delay_of<2> >
+ ,cds::opt::enable_elimination< true >
+ >::type
+ {};
+ class traits_FCQueue_delay2_elimination_stat:
+ public cds::intrusive::fcqueue::make_traits<
+ cds::opt::back_off< cds::backoff::delay_of<2> >
+ ,cds::opt::stat< cds::intrusive::fcqueue::stat<> >
+ ,cds::opt::enable_elimination< true >
+ >::type
+ {};
+ class traits_FCQueue_expbackoff_elimination:
+ public cds::intrusive::fcqueue::make_traits<
+ cds::opt::enable_elimination< true >
+ ,cds::opt::elimination_backoff< cds::backoff::Default >
+ >::type
+ {};
+ class traits_FCQueue_expbackoff_elimination_stat:
+ public cds::intrusive::fcqueue::make_traits<
+ cds::opt::enable_elimination< true >
+ ,cds::opt::stat< cds::intrusive::fcqueue::stat<> >
+ ,cds::opt::elimination_backoff< cds::backoff::Default >
+ >::type
+ {};
+
+ typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2 > FCQueue_list_delay2;
+ typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2_elimination > FCQueue_list_delay2_elimination;
+ typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2_elimination_stat > FCQueue_list_delay2_elimination_stat;
+ typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_expbackoff_elimination > FCQueue_list_expbackoff_elimination;
+ typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_expbackoff_elimination_stat > FCQueue_list_expbackoff_elimination_stat;
+
+ // SegmentedQueue
+ class traits_SegmentedQueue_spin_stat:
+ public cds::intrusive::segmented_queue::make_traits<
+ cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
+ >::type
+ {};
+ class traits_SegmentedQueue_spin_padding :
+ public cds::intrusive::segmented_queue::make_traits<
+ cds::opt::padding< cds::opt::cache_line_padding >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex_stat :
+ public cds::intrusive::segmented_queue::make_traits<
+ cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
+ ,cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex:
+ public cds::intrusive::segmented_queue::make_traits<
+ cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex_padding:
+ public cds::intrusive::segmented_queue::make_traits<
+ cds::opt::lock_type< std::mutex >
+ ,cds::opt::padding< cds::opt::cache_line_padding >
+ >::type
+ {};
+
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T > SegmentedQueue_HP_spin;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_spin_padding > SegmentedQueue_HP_spin_padding;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_spin_stat > SegmentedQueue_HP_spin_stat;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex > SegmentedQueue_HP_mutex;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex_padding > SegmentedQueue_HP_mutex_padding;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex_stat > SegmentedQueue_HP_mutex_stat;
+
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T > SegmentedQueue_DHP_spin;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_spin_padding > SegmentedQueue_DHP_spin_padding;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_spin_stat > SegmentedQueue_DHP_spin_stat;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex > SegmentedQueue_DHP_mutex;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex_padding > SegmentedQueue_DHP_mutex_padding;
+ typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex_stat > SegmentedQueue_DHP_mutex_stat;
+
+ // Boost SList
+ typedef details::BoostSList< T, std::mutex > BoostSList_mutex;
+ typedef details::BoostSList< T, cds::sync::spin > BoostSList_spin;
+ };
+} // namespace queue
+
+namespace cds_test {
+
+ // cds::container::fcqueue::stat
+ template <typename Counter>
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::fcqueue::stat<Counter> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_nEnqueue )
+ << CDSSTRESS_STAT_OUT( s, m_nDequeue )
+ << CDSSTRESS_STAT_OUT( s, m_nFailedDeq )
+ << CDSSTRESS_STAT_OUT( s, m_nCollided )
+ << CDSSTRESS_STAT_OUT_( "combining_factor", s.combining_factor() )
+ << CDSSTRESS_STAT_OUT( s, m_nOperationCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCombiningCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCompactPublicationList )
+ << CDSSTRESS_STAT_OUT( s, m_nDeactivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nActivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordCreated )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordDeteted )
+ << CDSSTRESS_STAT_OUT( s, m_nAcquirePubRecCount )
+ << CDSSTRESS_STAT_OUT( s, m_nReleasePubRecCount );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::fcqueue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+} // namespace cds_test
+
+#endif // #ifndef CDSSTRESS_INTRUSIVE_QUEUE_TYPES_H
--- /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 "queue_type.h"
+
+// Multi-threaded queue test for pop operation
+namespace {
+
+ static size_t s_nThreadCount = 8;
+ static size_t s_nQueueSize = 20000000 ; // no more than 20 million records
+
+ struct SimpleValue {
+ size_t nNo;
+
+ SimpleValue(): nNo(0) {}
+ SimpleValue( size_t n ): nNo(n) {}
+ size_t getNo() const { return nNo; }
+ };
+
+ class queue_pop: public cds_test::stress_fixture
+ {
+ protected:
+ struct value_type
+ {
+ size_t nNo;
+
+ value_type()
+ : nNo( 0 )
+ {}
+
+ value_type( size_t n )
+ : nNo( n )
+ {}
+ };
+
+ template <class Queue>
+ class Consumer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Consumer( cds_test::thread_pool& pool, Queue& queue )
+ : base_class( pool )
+ , m_Queue( queue )
+ , m_arr( new uint8_t[ s_nQueueSize ])
+ , m_nPopCount( 0 )
+ {}
+
+ Consumer( Consumer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ , m_arr( new uint8_t[ s_nQueueSize ])
+ , m_nPopCount( 0 )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Consumer( *this );
+ }
+
+ virtual void test()
+ {
+ memset( m_arr.get(), 0, sizeof( m_arr[0] ) * s_nQueueSize );
+ typedef typename Queue::value_type value_type;
+ value_type value;
+ size_t nPopCount = 0;
+ while ( m_Queue.pop( value ) ) {
+ ++m_arr[ value.nNo ];
+ ++nPopCount;
+ }
+ m_nPopCount = nPopCount;
+ }
+
+ public:
+ Queue& m_Queue;
+ std::unique_ptr< uint8_t[] > m_arr;
+ size_t m_nPopCount;
+ };
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "queue_pop" );\r
+\r
+ s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+
+ if ( s_nThreadCount == 0 )
+ s_nThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1000;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+
+ protected:
+ template <class Queue>
+ void analyze( Queue& q )
+ {
+ cds_test::thread_pool& pool = get_pool();
+ std::unique_ptr< uint8_t[] > arr( new uint8_t[s_nQueueSize] );
+ memset(arr.get(), 0, sizeof(arr[0]) * s_nQueueSize );
+
+ size_t nTotalPops = 0;
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Consumer<Queue>& thread = static_cast<Consumer<Queue>&>(pool.get( i ));
+ for ( size_t i = 0; i < s_nQueueSize; ++i )
+ arr[i] += thread.m_arr[i];
+ nTotalPops += thread.m_nPopCount;
+ }
+ EXPECT_EQ( nTotalPops, s_nQueueSize );
+ EXPECT_TRUE( q.empty());
+
+ for ( size_t i = 0; i < s_nQueueSize; ++i ) {
+ EXPECT_EQ( arr[i], 1 ) << "i=" << i;
+ }
+ }
+
+ template <class Queue>
+ void test( Queue& q )
+ {
+ cds_test::thread_pool& pool = get_pool();
+
+ pool.add( new Consumer<Queue>( pool, q ), s_nThreadCount );
+
+ for ( size_t i = 0; i < s_nQueueSize; ++i )
+ q.push( i );
+
+ propout() << std::make_pair( "thread_count", s_nThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize );
+
+ std::chrono::milliseconds duration = pool.run();
+
+ propout() << std::make_pair( "duration", duration );
+
+ analyze( q );
+
+ propout() << q.statistics();
+ }
+ };
+
+ CDSSTRESS_MSQueue( queue_pop )
+ CDSSTRESS_MoirQueue( queue_pop )
+ CDSSTRESS_BasketQueue( queue_pop )
+ CDSSTRESS_OptimsticQueue( queue_pop )
+ CDSSTRESS_FCQueue( queue_pop )
+ CDSSTRESS_FCDeque( queue_pop )
+ CDSSTRESS_RWQueue( queue_pop )
+ CDSSTRESS_StdQueue( queue_pop )
+
+#undef CDSSTRESS_Queue_F
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< value_type >::type_name queue_type; \
+ queue_type queue( s_nQueueSize ); \
+ test( queue ); \
+ }
+
+ CDSSTRESS_TsigasQueue( queue_pop )
+ CDSSTRESS_VyukovQueue( queue_pop )
+
+#undef CDSSTRESS_Queue_F
+
+
+ // ********************************************************************
+ // SegmentedQueue test
+
+ class segmented_queue_pop
+ : public queue_pop
+ , public ::testing::WithParamInterface< size_t >
+ {
+ typedef queue_pop base_class;
+
+ protected:
+ template <typename Queue>
+ void test()
+ {
+ size_t quasi_factor = GetParam();
+
+ Queue q( quasi_factor );
+ propout() << std::make_pair( "quasi_factor", quasi_factor );
+ base_class::test( q );
+ }
+
+ public:
+ static std::vector< size_t > get_test_parameters()
+ {
+ cds_test::config const& cfg = cds_test::stress_fixture::get_config( "queue_pop" );
+ bool bIterative = cfg.get_bool( "SegmentedQueue_Iterate", false );
+ size_t quasi_factor = cfg.get_size_t( "SegmentedQueue_SegmentSize", 256 );
+
+ std::vector<size_t> args;
+ if ( bIterative && quasi_factor > 4 ) {
+ for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 )
+ args.push_back( qf );
+ }
+ else {
+ if ( quasi_factor > 2 )
+ args.push_back( quasi_factor );
+ else
+ args.push_back( 2 );
+ }
+
+ return args;
+ }
+ };
+
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_P( test_fixture, type_name ) \
+ { \
+ typedef typename queue::Types<value_type>::type_name queue_type; \
+ test< queue_type >(); \
+ }
+
+ CDSSTRESS_SegmentedQueue( segmented_queue_pop )
+
+ INSTANTIATE_TEST_CASE_P( SQ,
+ segmented_queue_pop,
+ ::testing::ValuesIn( segmented_queue_pop::get_test_parameters()));
+
+} // 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.
+*/
+
+#ifndef CDSSTRESS_QUEUE_PRINT_STAT_H
+#define CDSSTRESS_QUEUE_PRINT_STAT_H
+
+namespace cds_test {
+
+ template <typename Counter>
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::basket_queue::stat<Counter> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueRace )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EmptyDequeue )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueRace )
+ << CDSSTRESS_STAT_OUT( s, m_AdvanceTailError )
+ << CDSSTRESS_STAT_OUT( s, m_BadTail )
+ << CDSSTRESS_STAT_OUT( s, m_TryAddBasket )
+ << CDSSTRESS_STAT_OUT( s, m_AddBasketCount );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::basket_queue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+ template <typename Counter>
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::msqueue::stat<Counter> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueRace )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EmptyDequeue )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueRace )
+ << CDSSTRESS_STAT_OUT( s, m_AdvanceTailError )
+ << CDSSTRESS_STAT_OUT( s, m_BadTail );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::msqueue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::opt::none )
+ {
+ return o;
+ }
+
+ template <typename Counter>
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::optimistic_queue::stat<Counter> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EnqueueRace )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueCount )
+ << CDSSTRESS_STAT_OUT( s, m_EmptyDequeue )
+ << CDSSTRESS_STAT_OUT( s, m_DequeueRace )
+ << CDSSTRESS_STAT_OUT( s, m_AdvanceTailError )
+ << CDSSTRESS_STAT_OUT( s, m_BadTail )
+ << CDSSTRESS_STAT_OUT( s, m_FixListCount );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::optimistic_queue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+ static inline property_stream& operator <<( property_stream& o, std::nullptr_t /*s*/ )
+ {
+ return o;
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::segmented_queue::stat<> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_nPush )
+ << CDSSTRESS_STAT_OUT( s, m_nPushPopulated )
+ << CDSSTRESS_STAT_OUT( s, m_nPushContended )
+ << CDSSTRESS_STAT_OUT( s, m_nPop )
+ << CDSSTRESS_STAT_OUT( s, m_nPopEmpty )
+ << CDSSTRESS_STAT_OUT( s, m_nPopContended )
+ << CDSSTRESS_STAT_OUT( s, m_nCreateSegmentReq )
+ << CDSSTRESS_STAT_OUT( s, m_nDeleteSegmentReq )
+ << CDSSTRESS_STAT_OUT( s, m_nSegmentCreated )
+ << CDSSTRESS_STAT_OUT( s, m_nSegmentDeleted );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::intrusive::segmented_queue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+} // namespace cds_test
+
+#endif // CDSSTRESS_QUEUE_PRINT_STAT_H
--- /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 "queue_type.h"
+
+// Multi-threaded queue test for push operation
+namespace {
+
+ static size_t s_nThreadCount = 8;
+ static size_t s_nQueueSize = 20000000 ; // no more than 20 million records
+
+ class queue_push: public cds_test::stress_fixture
+ {
+ protected:
+ struct value_type
+ {
+ size_t nNo;
+
+ value_type()
+ : nNo( 0 )
+ {}
+
+ value_type( size_t n )
+ : nNo( n )
+ {}
+ };
+
+ template <class Queue>
+ class Producer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Producer( cds_test::thread_pool& pool, Queue& queue )
+ : base_class( pool )
+ , m_Queue( queue )
+ , m_nStartItem( 0 )
+ , m_nEndItem( 0 )
+ , m_nPushError( 0 )
+ {}
+
+ Producer( Producer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ , m_nStartItem( 0 )
+ , m_nEndItem( 0 )
+ , m_nPushError( 0 )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Producer( *this );
+ }
+
+ virtual void test()
+ {
+ for ( size_t nItem = m_nStartItem; nItem < m_nEndItem; ++nItem ) {
+ if ( !m_Queue.push( nItem ))
+ ++m_nPushError;
+ }
+ }
+
+ public:
+ Queue& m_Queue;
+ size_t m_nStartItem;
+ size_t m_nEndItem;
+ size_t m_nPushError;
+ };
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "queue_push" );\r
+\r
+ s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+
+ if ( s_nThreadCount == 0 )
+ s_nThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1000;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+
+ protected:
+ template <class Queue>
+ void test( Queue& q )
+ {
+ cds_test::thread_pool& pool = get_pool();
+
+ pool.add( new Producer<Queue>( pool, q ), s_nThreadCount );
+
+ size_t nStart = 0;
+ size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Producer<Queue>& thread = static_cast<Producer<Queue>&>(pool.get( i ));
+ thread.m_nStartItem = nStart;
+ nStart += nThreadItemCount;
+ thread.m_nEndItem = nStart;
+ }
+
+ s_nQueueSize = nThreadItemCount * s_nThreadCount;
+ propout() << std::make_pair( "thread_count", s_nThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize );
+
+ std::chrono::milliseconds duration = pool.run();
+
+ propout() << std::make_pair( "duration", duration );
+
+ analyze( q );
+
+ propout() << q.statistics();
+ }
+
+ template <class Queue>
+ void analyze( Queue& q )
+ {
+ size_t nThreadItems = s_nQueueSize / s_nThreadCount;
+ cds_test::thread_pool& pool = get_pool();
+
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Producer<Queue>& thread = static_cast<Producer<Queue>&>(pool.get( i ));
+ EXPECT_EQ( thread.m_nPushError, 0 ) << " producer thread " << i;
+ }
+ EXPECT_TRUE( !q.empty() );
+
+ std::unique_ptr< uint8_t[] > arr( new uint8_t[s_nQueueSize] );
+ memset( arr.get(), 0, sizeof(arr[0]) * s_nQueueSize );
+
+ size_t nPopped = 0;
+ value_type val;
+ while ( q.pop( val )) {
+ nPopped++;
+ ++arr[ val.nNo ];
+ }
+
+ size_t nTotalItems = nThreadItems * s_nThreadCount;
+ for ( size_t i = 0; i < nTotalItems; ++i ) {
+ EXPECT_EQ( arr[i], 1 ) << "i=" << i;
+ }
+ }
+ };
+
+ CDSSTRESS_MSQueue( queue_push )
+ CDSSTRESS_MoirQueue( queue_push )
+ CDSSTRESS_BasketQueue( queue_push )
+ CDSSTRESS_OptimsticQueue( queue_push )
+ CDSSTRESS_FCQueue( queue_push )
+ CDSSTRESS_FCDeque( queue_push )
+ CDSSTRESS_RWQueue( queue_push )
+ CDSSTRESS_StdQueue( queue_push )
+
+#undef CDSSTRESS_Queue_F
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< value_type >::type_name queue_type; \
+ queue_type queue( s_nQueueSize ); \
+ test( queue ); \
+ }
+
+ CDSSTRESS_TsigasQueue( queue_push )
+ CDSSTRESS_VyukovQueue( queue_push )
+
+#undef CDSSTRESS_Queue_F
+
+
+ // ********************************************************************
+ // SegmentedQueue test
+
+ class segmented_queue_push
+ : public queue_push
+ , public ::testing::WithParamInterface< size_t >
+ {
+ typedef queue_push base_class;
+
+ protected:
+ template <typename Queue>
+ void test()
+ {
+ size_t quasi_factor = GetParam();
+
+ Queue q( quasi_factor );
+ propout() << std::make_pair( "quasi_factor", quasi_factor );
+ base_class::test( q );
+ }
+
+ public:
+ static std::vector< size_t > get_test_parameters()
+ {
+ cds_test::config const& cfg = cds_test::stress_fixture::get_config( "queue_push" );
+ bool bIterative = cfg.get_bool( "SegmentedQueue_Iterate", false );
+ size_t quasi_factor = cfg.get_size_t( "SegmentedQueue_SegmentSize", 256 );
+
+ std::vector<size_t> args;
+ if ( bIterative && quasi_factor > 4 ) {
+ for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 )
+ args.push_back( qf );
+ }
+ else {
+ if ( quasi_factor > 2 )
+ args.push_back( quasi_factor );
+ else
+ args.push_back( 2 );
+ }
+
+ return args;
+ }
+ };
+
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_P( test_fixture, type_name ) \
+ { \
+ typedef typename queue::Types<value_type>::type_name queue_type; \
+ test< queue_type >(); \
+ }
+
+ CDSSTRESS_SegmentedQueue( segmented_queue_push )
+
+ INSTANTIATE_TEST_CASE_P( SQ,
+ segmented_queue_push,
+ ::testing::ValuesIn( segmented_queue_push::get_test_parameters()));
+
+} // 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 "queue_type.h"
+
+#include <vector>
+#include <algorithm>
+
+// Multi-threaded queue push/pop test
+namespace {
+
+ static size_t s_nConsumerThreadCount = 4;
+ static size_t s_nProducerThreadCount = 4;
+ static size_t s_nQueueSize = 4000000;
+
+ static std::atomic<size_t> s_nProducerDone( 0 );
+
+ class queue_push_pop: public cds_test::stress_fixture
+ {
+ protected:
+ struct value_type
+ {
+ size_t nNo;
+ size_t nWriterNo;
+ };
+
+ enum {
+ producer_thread,
+ consumer_thread
+ };
+
+ template <class Queue>
+ class Producer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Producer( cds_test::thread_pool& pool, Queue& queue, size_t nPushCount )
+ : base_class( pool, producer_thread )
+ , m_Queue( queue )
+ , m_nPushFailed( 0 )
+ , m_nPushCount( nPushCount )
+ {}
+
+ Producer( Producer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ , m_nPushFailed( 0 )
+ , m_nPushCount( src.m_nPushCount )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Producer( *this );
+ }
+
+ virtual void test()
+ {
+ size_t const nPushCount = m_nPushCount;
+ value_type v;
+ v.nWriterNo = id();
+ v.nNo = 0;
+ m_nPushFailed = 0;
+
+ while ( v.nNo < nPushCount ) {
+ if ( m_Queue.push( v ))
+ ++v.nNo;
+ else
+ ++m_nPushFailed;
+ }
+
+ s_nProducerDone.fetch_add( 1 );
+ }
+ public:
+ Queue& m_Queue;
+ size_t m_nPushFailed;
+ size_t const m_nPushCount;
+ };
+
+ template <class Queue>
+ class Consumer: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Queue& m_Queue;
+ size_t const m_nPushPerProducer;
+ size_t m_nPopEmpty;
+ size_t m_nPopped;
+ size_t m_nBadWriter;
+
+ typedef std::vector<size_t> popped_data;
+ typedef std::vector<size_t>::iterator data_iterator;
+ typedef std::vector<size_t>::const_iterator const_data_iterator;
+
+ std::vector<popped_data> m_WriterData;
+
+ private:
+ void initPoppedData()
+ {
+ const size_t nProducerCount = s_nProducerThreadCount;
+ m_WriterData.resize( nProducerCount );
+ for ( size_t i = 0; i < nProducerCount; ++i )
+ m_WriterData[i].reserve( m_nPushPerProducer );
+ }
+
+ public:
+ Consumer( cds_test::thread_pool& pool, Queue& queue, size_t nPushPerProducer )
+ : base_class( pool, consumer_thread )
+ , m_Queue( queue )
+ , m_nPushPerProducer( nPushPerProducer )
+ , m_nPopEmpty( 0 )
+ , m_nPopped( 0 )
+ , m_nBadWriter( 0 )
+ {
+ initPoppedData();
+ }
+ Consumer( Consumer& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ , m_nPushPerProducer( src.m_nPushPerProducer )
+ , m_nPopEmpty( 0 )
+ , m_nPopped( 0 )
+ , m_nBadWriter( 0 )
+ {
+ initPoppedData();
+ }
+
+ virtual thread * clone()
+ {
+ return new Consumer( *this );
+ }
+
+ virtual void test()
+ {
+ m_nPopEmpty = 0;
+ m_nPopped = 0;
+ m_nBadWriter = 0;
+ const size_t nTotalWriters = s_nProducerThreadCount;
+ value_type v;
+ while ( true ) {
+ if ( m_Queue.pop( v ) ) {
+ ++m_nPopped;
+ if ( v.nWriterNo < nTotalWriters )
+ m_WriterData[ v.nWriterNo ].push_back( v.nNo );
+ else
+ ++m_nBadWriter;
+ }
+ else
+ ++m_nPopEmpty;
+
+ if ( m_Queue.empty() ) {
+ if ( s_nProducerDone.load() >= nTotalWriters ) {
+ if ( m_Queue.empty() )
+ break;
+ }
+ }
+ }
+ }
+ };
+
+ protected:
+ size_t m_nThreadPushCount;
+
+ protected:
+ template <class Queue>
+ void analyze( Queue& q, size_t /*nLeftOffset*/ = 0, size_t nRightOffset = 0 )
+ {
+ cds_test::thread_pool& pool = get_pool();
+
+ typedef Consumer<Queue> Consumer;
+ typedef Producer<Queue> Producer;
+
+ size_t nPostTestPops = 0;
+ {
+ value_type v;
+ while ( q.pop( v ))
+ ++nPostTestPops;
+ }
+
+ size_t nTotalPops = 0;
+ size_t nPopFalse = 0;
+ size_t nPoppedItems = 0;
+ size_t nPushFailed = 0;
+
+ std::vector< Consumer * > arrConsumer;
+
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ cds_test::thread& thr = pool.get(i);
+ if ( thr.type() == consumer_thread ) {
+ Consumer& consumer = static_cast<Consumer&>( thr );
+ nTotalPops += consumer.m_nPopped;
+ nPopFalse += consumer.m_nPopEmpty;
+ arrConsumer.push_back( &consumer );
+ EXPECT_EQ( consumer.m_nBadWriter, 0 ) << "consumer_thread_no " << i;
+
+ size_t nPopped = 0;
+ for ( size_t n = 0; n < s_nProducerThreadCount; ++n )
+ nPopped += consumer.m_WriterData[n].size();
+
+ nPoppedItems += nPopped;
+ }
+ else {
+ assert( thr.type() == producer_thread );
+
+ Producer& producer = static_cast<Producer&>( thr );
+ nPushFailed += producer.m_nPushFailed;
+ EXPECT_EQ( producer.m_nPushFailed, 0 ) << "producer_thread_no " << i;
+ }
+ }
+ EXPECT_EQ( nTotalPops, nPoppedItems );
+
+ EXPECT_EQ( nTotalPops + nPostTestPops, s_nQueueSize ) << "nTotalPops=" << nTotalPops << ", nPostTestPops=" << nPostTestPops;
+ EXPECT_TRUE( q.empty() );
+
+ // Test consistency of popped sequence
+ for ( size_t nWriter = 0; nWriter < s_nProducerThreadCount; ++nWriter ) {
+ std::vector<size_t> arrData;
+ arrData.reserve( m_nThreadPushCount );
+ for ( size_t nReader = 0; nReader < arrConsumer.size(); ++nReader ) {
+ auto it = arrConsumer[nReader]->m_WriterData[nWriter].begin();
+ auto itEnd = arrConsumer[nReader]->m_WriterData[nWriter].end();
+ if ( it != itEnd ) {
+ auto itPrev = it;
+ for ( ++it; it != itEnd; ++it ) {
+ EXPECT_LT( *itPrev, *it + nRightOffset ) << "consumer=" << nReader << ", producer=" << nWriter;
+ itPrev = it;
+ }
+ }
+
+ for ( it = arrConsumer[nReader]->m_WriterData[nWriter].begin(); it != itEnd; ++it )
+ arrData.push_back( *it );
+ }
+
+ std::sort( arrData.begin(), arrData.end() );
+ for ( size_t i=1; i < arrData.size(); ++i ) {
+ EXPECT_EQ( arrData[i - 1] + 1, arrData[i] ) << "producer=" << nWriter;
+ }
+
+ EXPECT_EQ( arrData[0], 0 ) << "producer=" << nWriter;
+ EXPECT_EQ( arrData[arrData.size() - 1], m_nThreadPushCount - 1 ) << "producer=" << nWriter;
+ }
+ }
+
+ template <class Queue>
+ void test_queue( Queue& q )
+ {
+ m_nThreadPushCount = s_nQueueSize / s_nProducerThreadCount;
+
+ cds_test::thread_pool& pool = get_pool();
+ pool.add( new Producer<Queue>( pool, q, m_nThreadPushCount ), s_nProducerThreadCount );
+ pool.add( new Consumer<Queue>( pool, q, m_nThreadPushCount ), s_nConsumerThreadCount );
+
+ s_nProducerDone.store( 0 );
+ s_nQueueSize = m_nThreadPushCount * s_nProducerThreadCount;
+
+ propout() << std::make_pair( "producer_count", s_nProducerThreadCount )
+ << std::make_pair( "consumer_count", s_nConsumerThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize );
+
+ std::chrono::milliseconds duration = pool.run();
+
+ propout() << std::make_pair( "duration", duration );
+ }
+
+ template <class Queue>
+ void test( Queue& q )
+ {
+ test_queue( q );
+ analyze( q );
+ propout() << q.statistics();
+ }
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "queue_push_pop" );\r
+\r
+ s_nConsumerThreadCount = cfg.get_size_t( "ConsumerCount", s_nConsumerThreadCount );
+ s_nProducerThreadCount = cfg.get_size_t( "ProducerCount", s_nProducerThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+
+ if ( s_nConsumerThreadCount == 0 )
+ s_nConsumerThreadCount = 1;
+ if ( s_nProducerThreadCount == 0 )
+ s_nProducerThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1000;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+ };
+
+ CDSSTRESS_MSQueue( queue_push_pop )
+ CDSSTRESS_MoirQueue( queue_push_pop )
+ CDSSTRESS_BasketQueue( queue_push_pop )
+ CDSSTRESS_OptimsticQueue( queue_push_pop )
+ CDSSTRESS_FCQueue( queue_push_pop )
+ CDSSTRESS_FCDeque( queue_push_pop )
+ CDSSTRESS_RWQueue( queue_push_pop )
+ CDSSTRESS_StdQueue( queue_push_pop )
+
+#undef CDSSTRESS_Queue_F
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< value_type >::type_name queue_type; \
+ queue_type queue( s_nQueueSize ); \
+ test( queue ); \
+ }
+
+ CDSSTRESS_TsigasQueue( queue_push_pop )
+ CDSSTRESS_VyukovQueue( queue_push_pop )
+
+#undef CDSSTRESS_Queue_F
+
+
+ // ********************************************************************
+ // SegmentedQueue test
+
+ class segmented_queue_push_pop
+ : public queue_push_pop
+ , public ::testing::WithParamInterface< size_t >
+ {
+ typedef queue_push_pop base_class;
+
+ protected:
+
+ template <typename Queue>
+ void test()
+ {
+ size_t quasi_factor = GetParam();
+
+ Queue q( quasi_factor );
+ propout() << std::make_pair( "quasi_factor", quasi_factor );
+ base_class::test_queue( q );
+ analyze( q, quasi_factor * 2, quasi_factor );
+ propout() << q.statistics();
+ }
+
+ public:
+ static std::vector< size_t > get_test_parameters()
+ {
+ cds_test::config const& cfg = cds_test::stress_fixture::get_config( "queue_push_pop" );
+ bool bIterative = cfg.get_bool( "SegmentedQueue_Iterate", false );
+ size_t quasi_factor = cfg.get_size_t( "SegmentedQueue_SegmentSize", 256 );
+
+ std::vector<size_t> args;
+ if ( bIterative && quasi_factor > 4 ) {
+ for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 )
+ args.push_back( qf );
+ }
+ else {
+ if ( quasi_factor > 2 )
+ args.push_back( quasi_factor );
+ else
+ args.push_back( 2 );
+ }
+
+ return args;
+ }
+ };
+
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_P( test_fixture, type_name ) \
+ { \
+ typedef typename queue::Types<value_type>::type_name queue_type; \
+ test< queue_type >(); \
+ }
+
+ CDSSTRESS_SegmentedQueue( segmented_queue_push_pop )
+
+ INSTANTIATE_TEST_CASE_P( SQ,
+ segmented_queue_push_pop,
+ ::testing::ValuesIn( segmented_queue_push_pop::get_test_parameters()));
+
+} // 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.
+*/
+
+#ifndef CDSSTRESS_QUEUE_TYPES_H
+#define CDSSTRESS_QUEUE_TYPES_H
+
+#include <cds/container/msqueue.h>
+#include <cds/container/moir_queue.h>
+#include <cds/container/rwqueue.h>
+#include <cds/container/optimistic_queue.h>
+#include <cds/container/tsigas_cycle_queue.h>
+#include <cds/container/vyukov_mpmc_cycle_queue.h>
+#include <cds/container/basket_queue.h>
+#include <cds/container/fcqueue.h>
+#include <cds/container/fcdeque.h>
+#include <cds/container/segmented_queue.h>
+
+#include <cds/gc/hp.h>
+#include <cds/gc/dhp.h>
+
+#include "std_queue.h"
+#include "lock/win32_lock.h"
+#include "framework/michael_alloc.h"
+
+#include <boost/container/deque.hpp>
+
+#include <cds_test/stress_test.h>
+#include "print_stat.h"
+
+namespace queue {
+
+ namespace details {
+ template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque=std::deque<T> >
+ class FCDequeL: public cds::container::FCDeque<T, Deque, Traits >
+ {
+ typedef cds::container::FCDeque<T, Deque, Traits > base_class;
+ public:
+ FCDequeL()
+ {}
+
+ FCDequeL(
+ unsigned int nCompactFactor ///< Flat combining: publication list compacting factor
+ ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
+ )
+ : base_class( nCompactFactor, nCombinePassCount )
+ {}
+
+ bool push( T const& v )
+ {
+ return base_class::push_front( v );
+ }
+ bool enqueue( T const& v )
+ {
+ return push( v );
+ }
+
+ bool pop( T& v )
+ {
+ return base_class::pop_back( v );
+ }
+ bool deque( T& v )
+ {
+ return pop(v);
+ }
+ };
+
+ template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque = std::deque<T> >
+ class FCDequeR: public cds::container::FCDeque<T, Deque, Traits >
+ {
+ typedef cds::container::FCDeque<T, Deque, Traits > base_class;
+ public:
+ FCDequeR()
+ {}
+
+ FCDequeR(
+ unsigned int nCompactFactor ///< Flat combining: publication list compacting factor
+ ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
+ )
+ : base_class( nCompactFactor, nCombinePassCount )
+ {}
+
+ bool push( T const& v )
+ {
+ return base_class::push_back( v );
+ }
+ bool enqueue( T const& v )
+ {
+ return push( v );
+ }
+
+ bool pop( T& v )
+ {
+ return base_class::pop_front( v );
+ }
+ bool deque( T& v )
+ {
+ return pop(v);
+ }
+ };
+
+ } // namespace details
+
+ template <typename Value>
+ struct Types {
+
+ // MSQueue
+ typedef cds::container::MSQueue<cds::gc::HP, Value > MSQueue_HP;
+ typedef cds::container::MSQueue<cds::gc::DHP, Value > MSQueue_DHP;
+ typedef cds::container::MoirQueue<cds::gc::HP, Value > MoirQueue_HP;
+ typedef cds::container::MoirQueue<cds::gc::DHP, Value > MoirQueue_DHP;
+
+ struct traits_MSQueue_michaelAlloc : public cds::container::msqueue::traits
+ {
+ typedef memory::MichaelAllocator<int> allocator;
+ };
+ typedef cds::container::MSQueue<cds::gc::HP, Value, traits_MSQueue_michaelAlloc > MSQueue_HP_michaelAlloc;
+ typedef cds::container::MSQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MSQueue_DHP_michaelAlloc;
+ typedef cds::container::MoirQueue<cds::gc::HP, Value, traits_MSQueue_michaelAlloc > MoirQueue_HP_michaelAlloc;
+ typedef cds::container::MoirQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MoirQueue_DHP_michaelAlloc;
+
+ struct traits_MSQueue_seqcst : public
+ cds::container::msqueue::make_traits <
+ cds::opt::memory_model < cds::opt::v::sequential_consistent >
+ > ::type
+ {};
+ typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_seqcst > MSQueue_HP_seqcst;
+ typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MSQueue_DHP_seqcst;
+ typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_seqcst > MoirQueue_HP_seqcst;
+ typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MoirQueue_DHP_seqcst;
+
+ // MSQueue + item counter
+ struct traits_MSQueue_ic : public
+ cds::container::msqueue::make_traits <
+ cds::opt::item_counter < cds::atomicity::item_counter >
+ >::type
+ {};
+ typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_ic > MSQueue_HP_ic;
+ typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MSQueue_DHP_ic;
+ typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_ic > MoirQueue_HP_ic;
+ typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MoirQueue_DHP_ic;
+
+ // MSQueue + stat
+ struct traits_MSQueue_stat: public
+ cds::container::msqueue::make_traits <
+ cds::opt::stat< cds::container::msqueue::stat<> >
+ >::type
+ {};
+ typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_stat > MSQueue_HP_stat;
+ typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MSQueue_DHP_stat;
+ typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_stat > MoirQueue_HP_stat;
+ typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MoirQueue_DHP_stat;
+
+
+ // OptimisticQueue
+ typedef cds::container::OptimisticQueue< cds::gc::HP, Value > OptimisticQueue_HP;
+ typedef cds::container::OptimisticQueue< cds::gc::DHP, Value > OptimisticQueue_DHP;
+
+ struct traits_OptimisticQueue_michaelAlloc : public cds::container::optimistic_queue::traits
+ {
+ typedef memory::MichaelAllocator<int> allocator;
+ };
+ typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_HP_michaelAlloc;
+ typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_DHP_michaelAlloc;
+
+ struct traits_OptimisticQueue_seqcst : public cds::container::optimistic_queue::traits
+ {
+ typedef cds::opt::v::sequential_consistent memory_model;
+ };
+ typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_seqcst > OptimisticQueue_HP_seqcst;
+ typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_seqcst > OptimisticQueue_DHP_seqcst;
+
+ struct traits_OptimisticQueue_ic : public cds::container::optimistic_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_ic > OptimisticQueue_HP_ic;
+ typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_ic > OptimisticQueue_DHP_ic;
+
+ struct traits_OptimisticQueue_stat : public
+ cds::container::optimistic_queue::make_traits <
+ cds::opt::stat < cds::intrusive::optimistic_queue::stat<> >
+ > ::type
+ {};
+ typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_stat > OptimisticQueue_HP_stat;
+ typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_stat > OptimisticQueue_DHP_stat;
+
+
+ // TsigasCycleQueue
+
+ class TsigasCycleQueue_dyn
+ : public cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ >::type
+ >
+ {
+ typedef cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ >::type
+ > base_class;
+ public:
+ TsigasCycleQueue_dyn()
+ : base_class( 1024 * 64 )
+ {}
+
+ TsigasCycleQueue_dyn( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ class TsigasCycleQueue_dyn_michaelAlloc
+ : public cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ ,cds::opt::allocator< memory::MichaelAllocator<int> >
+ >::type
+ >
+ {
+ typedef cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ , cds::opt::allocator< memory::MichaelAllocator<int> >
+ >::type
+ > base_class;
+ public:
+ TsigasCycleQueue_dyn_michaelAlloc()
+ : base_class( 1024 * 64 )
+ {}
+
+ TsigasCycleQueue_dyn_michaelAlloc( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ class TsigasCycleQueue_dyn_ic
+ : public cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ >
+ {
+ typedef cds::container::TsigasCycleQueue< Value,
+ typename cds::container::tsigas_queue::make_traits<
+ cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
+ ,cds::opt::item_counter< cds::atomicity::item_counter >
+ >::type
+ > base_class;
+ public:
+ TsigasCycleQueue_dyn_ic()
+ : base_class( 1024 * 64 )
+ {}
+ TsigasCycleQueue_dyn_ic( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ // VyukovMPMCCycleQueue
+ struct traits_VyukovMPMCCycleQueue_dyn : public cds::container::vyukov_queue::traits
+ {
+ typedef cds::opt::v::dynamic_buffer< int > buffer;
+ };
+ class VyukovMPMCCycleQueue_dyn
+ : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn >
+ {
+ typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn > base_class;
+ public:
+ VyukovMPMCCycleQueue_dyn()
+ : base_class( 1024 * 64 )
+ {}
+ VyukovMPMCCycleQueue_dyn( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ struct traits_VyukovMPMCCycleQueue_dyn_michaelAlloc : public cds::container::vyukov_queue::traits
+ {
+ typedef cds::opt::v::dynamic_buffer< int, memory::MichaelAllocator<int> > buffer;
+ };
+ class VyukovMPMCCycleQueue_dyn_michaelAlloc
+ : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc >
+ {
+ typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc > base_class;
+ public:
+ VyukovMPMCCycleQueue_dyn_michaelAlloc()
+ : base_class( 1024 * 64 )
+ {}
+ VyukovMPMCCycleQueue_dyn_michaelAlloc( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ class VyukovMPMCCycleQueue_dyn_ic
+ : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic >
+ {
+ typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
+ public:
+ VyukovMPMCCycleQueue_dyn_ic()
+ : base_class( 1024 * 64 )
+ {}
+ VyukovMPMCCycleQueue_dyn_ic( size_t nCapacity )
+ : base_class( nCapacity )
+ {}
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+
+ // BasketQueue
+
+ typedef cds::container::BasketQueue< cds::gc::HP , Value > BasketQueue_HP;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value > BasketQueue_DHP;
+
+ struct traits_BasketQueue_michaelAlloc : public cds::container::basket_queue::traits
+ {
+ typedef memory::MichaelAllocator<int> allocator;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_HP_michaelAlloc;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_DHP_michaelAlloc;
+
+ struct traits_BasketQueue_seqcst : public cds::container::basket_queue::traits
+ {
+ typedef cds::opt::v::sequential_consistent mamory_model;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_seqcst > BasketQueue_HP_seqcst;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_seqcst > BasketQueue_DHP_seqcst;
+
+ struct traits_BasketQueue_ic : public cds::container::basket_queue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_ic >BasketQueue_HP_ic;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_ic >BasketQueue_DHP_ic;
+
+ struct traits_BasketQueue_stat : public cds::container::basket_queue::traits
+ {
+ typedef cds::container::basket_queue::stat<> stat;
+ };
+ typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_stat > BasketQueue_HP_stat;
+ typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_stat > BasketQueue_DHP_stat;
+
+
+ // RWQueue
+ typedef cds::container::RWQueue< Value > RWQueue_Spin;
+
+ struct traits_RWQueue_Spin_ic : public cds::container::rwqueue::traits
+ {
+ typedef cds::atomicity::item_counter item_counter;
+ };
+ typedef cds::container::RWQueue< Value, traits_RWQueue_Spin_ic > RWQueue_Spin_ic;
+
+ struct traits_RWQueue_mutex : public
+ cds::container::rwqueue::make_traits<
+ cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+ typedef cds::container::RWQueue< Value, traits_RWQueue_mutex > RWQueue_mutex;
+
+ // FCQueue
+ class traits_FCQueue_elimination:
+ public cds::container::fcqueue::make_traits<
+ cds::opt::enable_elimination< true >
+ >::type
+ {};
+ class traits_FCQueue_elimination_stat:
+ public cds::container::fcqueue::make_traits<
+ cds::opt::enable_elimination< true >
+ ,cds::opt::stat< cds::container::fcqueue::stat<> >
+ >::type
+ {};
+
+ typedef cds::container::FCQueue< Value > FCQueue_deque;
+ typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination > FCQueue_deque_elimination;
+ typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination_stat > FCQueue_deque_elimination_stat;
+
+ typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> > > FCQueue_list;
+ typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination > FCQueue_list_elimination;
+ typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination_stat > FCQueue_list_elimination_stat;
+
+
+ // FCDeque
+ struct traits_FCDeque_stat:
+ public cds::container::fcdeque::make_traits<
+ cds::opt::stat< cds::container::fcdeque::stat<> >
+ >::type
+ {};
+ struct traits_FCDeque_elimination:
+ public cds::container::fcdeque::make_traits<
+ cds::opt::enable_elimination< true >
+ >::type
+ {};
+ struct traits_FCDeque_elimination_stat:
+ public cds::container::fcdeque::make_traits<
+ cds::opt::stat< cds::container::fcdeque::stat<> >,
+ cds::opt::enable_elimination< true >
+ >::type
+ {};
+ struct traits_FCDeque_mutex:
+ public cds::container::fcdeque::make_traits<
+ cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+
+ typedef details::FCDequeL< Value > FCDequeL_default;
+ typedef details::FCDequeL< Value, traits_FCDeque_mutex > FCDequeL_mutex;
+ typedef details::FCDequeL< Value, traits_FCDeque_stat > FCDequeL_stat;
+ typedef details::FCDequeL< Value, traits_FCDeque_elimination > FCDequeL_elimination;
+ typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat > FCDequeL_elimination_stat;
+
+ typedef details::FCDequeL< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeL_boost;
+ typedef details::FCDequeL< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeL_boost_stat;
+ typedef details::FCDequeL< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeL_boost_elimination;
+ typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeL_boost_elimination_stat;
+
+ typedef details::FCDequeR< Value > FCDequeR_default;
+ typedef details::FCDequeR< Value, traits_FCDeque_mutex > FCDequeR_mutex;
+ typedef details::FCDequeR< Value, traits_FCDeque_stat > FCDequeR_stat;
+ typedef details::FCDequeR< Value, traits_FCDeque_elimination > FCDequeR_elimination;
+ typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat > FCDequeR_elimination_stat;
+
+ typedef details::FCDequeR< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeR_boost;
+ typedef details::FCDequeR< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeR_boost_stat;
+ typedef details::FCDequeR< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeR_boost_elimination;
+ typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeR_boost_elimination_stat;
+
+ typedef StdQueue_deque<Value> StdQueue_deque_Spinlock;
+ typedef StdQueue_list<Value> StdQueue_list_Spinlock;
+ typedef StdQueue_deque<Value, std::mutex> StdQueue_deque_Mutex;
+ typedef StdQueue_list<Value, std::mutex> StdQueue_list_Mutex;
+#ifdef UNIT_LOCK_WIN_CS
+ typedef StdQueue_deque<Value, lock::win::CS> StdQueue_deque_WinCS;
+ typedef StdQueue_list<Value, lock::win::CS> StdQueue_list_WinCS;
+ typedef StdQueue_deque<Value, lock::win::Mutex> StdQueue_deque_WinMutex;
+ typedef StdQueue_list<Value, lock::win::Mutex> StdQueue_list_WinMutex;
+#endif
+
+ // SegmentedQueue
+ class traits_SegmentedQueue_spin_stat:
+ public cds::container::segmented_queue::make_traits<
+ cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
+ >::type
+ {};
+ class traits_SegmentedQueue_spin_padding:
+ public cds::container::segmented_queue::make_traits<
+ cds::opt::padding< cds::opt::cache_line_padding >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex_stat:
+ public cds::container::segmented_queue::make_traits<
+ cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
+ ,cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex:
+ public cds::container::segmented_queue::make_traits<
+ cds::opt::lock_type< std::mutex >
+ >::type
+ {};
+ class traits_SegmentedQueue_mutex_padding:
+ public cds::container::segmented_queue::make_traits<
+ cds::opt::lock_type< std::mutex >
+ , cds::opt::padding< cds::opt::cache_line_padding >
+ >::type
+ {};
+
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value > SegmentedQueue_HP_spin;
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_padding > SegmentedQueue_HP_spin_padding;
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_stat > SegmentedQueue_HP_spin_stat;
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex > SegmentedQueue_HP_mutex;
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_padding > SegmentedQueue_HP_mutex_padding;
+ typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_stat > SegmentedQueue_HP_mutex_stat;
+
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value > SegmentedQueue_DHP_spin;
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_padding > SegmentedQueue_DHP_spin_padding;
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_stat > SegmentedQueue_DHP_spin_stat;
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex > SegmentedQueue_DHP_mutex;
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_padding > SegmentedQueue_DHP_mutex_padding;
+ typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_stat > SegmentedQueue_DHP_mutex_stat;
+ };
+}
+
+
+// *********************************************
+// Queue statistics
+namespace cds_test {
+
+ template <typename Counter>
+ static inline property_stream& operator <<( property_stream& o, cds::container::fcqueue::stat<Counter> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_nEnqueue )
+ << CDSSTRESS_STAT_OUT( s, m_nEnqMove )
+ << CDSSTRESS_STAT_OUT( s, m_nDequeue )
+ << CDSSTRESS_STAT_OUT( s, m_nFailedDeq )
+ << CDSSTRESS_STAT_OUT( s, m_nCollided )
+ << CDSSTRESS_STAT_OUT_( "combining_factor", s.combining_factor() )
+ << CDSSTRESS_STAT_OUT( s, m_nOperationCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCombiningCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCompactPublicationList )
+ << CDSSTRESS_STAT_OUT( s, m_nDeactivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nActivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordCreated )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordDeteted )
+ << CDSSTRESS_STAT_OUT( s, m_nAcquirePubRecCount )
+ << CDSSTRESS_STAT_OUT( s, m_nReleasePubRecCount );
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::container::fcqueue::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::container::fcdeque::empty_stat const& /*s*/ )
+ {
+ return o;
+ }
+
+ static inline property_stream& operator <<( property_stream& o, cds::container::fcdeque::stat<> const& s )
+ {
+ return o
+ << CDSSTRESS_STAT_OUT( s, m_nPushFront )
+ << CDSSTRESS_STAT_OUT( s, m_nPushFrontMove )
+ << CDSSTRESS_STAT_OUT( s, m_nPushBack )
+ << CDSSTRESS_STAT_OUT( s, m_nPushBackMove )
+ << CDSSTRESS_STAT_OUT( s, m_nPopFront )
+ << CDSSTRESS_STAT_OUT( s, m_nFailedPopFront )
+ << CDSSTRESS_STAT_OUT( s, m_nPopBack )
+ << CDSSTRESS_STAT_OUT( s, m_nFailedPopBack )
+ << CDSSTRESS_STAT_OUT( s, m_nCollided )
+ << CDSSTRESS_STAT_OUT_( "combining_factor", s.combining_factor() )
+ << CDSSTRESS_STAT_OUT( s, m_nOperationCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCombiningCount )
+ << CDSSTRESS_STAT_OUT( s, m_nCompactPublicationList )
+ << CDSSTRESS_STAT_OUT( s, m_nDeactivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nActivatePubRecord )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordCreated )
+ << CDSSTRESS_STAT_OUT( s, m_nPubRecordDeteted )
+ << CDSSTRESS_STAT_OUT( s, m_nAcquirePubRecCount )
+ << CDSSTRESS_STAT_OUT( s, m_nReleasePubRecCount );
+ }
+
+} // namespace cds_test
+
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< value_type >::type_name queue_type; \
+ queue_type queue; \
+ test( queue ); \
+ }
+
+#define CDSSTRESS_MSQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_HP ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_HP_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, MSQueue_DHP_stat )
+
+#define CDSSTRESS_MoirQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_HP_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, MoirQueue_DHP_stat )
+
+#define CDSSTRESS_OptimsticQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_HP_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, OptimisticQueue_DHP_stat )
+
+#define CDSSTRESS_BasketQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_HP_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_seqcst ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, BasketQueue_DHP_stat )
+
+#define CDSSTRESS_FCQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_deque ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_deque_elimination_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_list ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_list_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCQueue_list_elimination_stat )
+
+#define CDSSTRESS_FCDeque( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_default ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_mutex ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_elimination_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeL_boost_elimination_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_default ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_mutex ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_elimination_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_elimination ) \
+ CDSSTRESS_Queue_F( test_fixture, FCDequeR_boost_elimination_stat )
+
+#define CDSSTRESS_RWQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, RWQueue_Spin ) \
+ CDSSTRESS_Queue_F( test_fixture, RWQueue_Spin_ic ) \
+ CDSSTRESS_Queue_F( test_fixture, RWQueue_mutex )
+
+#define CDSSTRESS_SegmentedQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin_padding ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_spin_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex_padding ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_HP_mutex_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin_padding ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_spin_stat ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex_padding ) \
+ CDSSTRESS_Queue_F( test_fixture, SegmentedQueue_DHP_mutex_stat )
+
+
+#define CDSSTRESS_TsigasQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn ) \
+ CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, TsigasCycleQueue_dyn_ic )
+
+#define CDSSTRESS_VyukovQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn ) \
+ CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn_michaelAlloc ) \
+ CDSSTRESS_Queue_F( test_fixture, VyukovMPMCCycleQueue_dyn_ic )
+
+#define CDSSTRESS_StdQueue( test_fixture ) \
+ CDSSTRESS_Queue_F( test_fixture, StdQueue_deque_Spinlock ) \
+ CDSSTRESS_Queue_F( test_fixture, StdQueue_list_Spinlock ) \
+ CDSSTRESS_Queue_F( test_fixture, StdQueue_deque_Mutex ) \
+ CDSSTRESS_Queue_F( test_fixture, StdQueue_list_Mutex )
+
+#endif // #ifndef CDSSTRESS_QUEUE_TYPES_H
--- /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 "queue_type.h"
+
+#include <vector>
+
+// Multi-threaded queue test for random push/pop operation
+namespace {
+
+ static size_t s_nThreadCount = 16;
+ static size_t s_nQueueSize = 10000000;
+
+ std::atomic< size_t > s_nProducerCount(0);
+
+ class queue_random: public cds_test::stress_fixture
+ {
+ typedef cds_test::stress_fixture base_class;
+
+ protected:
+ struct value_type {
+ size_t nNo;
+ size_t nThread;
+
+ value_type() {}
+ value_type( size_t n ) : nNo( n ) {}
+ };
+
+ template <class Queue>
+ class Strain: public cds_test::thread
+ {
+ typedef cds_test::thread base_class;
+
+ public:
+ Strain( cds_test::thread_pool& pool, Queue& q, size_t nPushCount, size_t nSpread = 0 )
+ : base_class( pool )
+ , m_Queue( q )
+ , m_nSpread( nSpread )
+ , m_nTotalPushCount( nPushCount )
+ {}
+
+ Strain( Strain& src )
+ : base_class( src )
+ , m_Queue( src.m_Queue )
+ , m_nSpread( src.m_nSpread )
+ , m_nTotalPushCount( src.m_nTotalPushCount )
+ {}
+
+ virtual thread * clone()
+ {
+ return new Strain( *this );
+ }
+
+ virtual void test()
+ {
+ size_t const nThreadCount = s_nThreadCount;
+ size_t const nTotalPush = m_nTotalPushCount;
+
+ m_arrLastRead.resize( nThreadCount, 0 );
+ m_arrPopCountPerThread.resize( nThreadCount, 0 );
+
+ value_type node;
+
+ while ( m_nPushCount < nTotalPush ) {
+ if ( (rand() & 3) != 3 ) {
+ node.nThread = id();
+ node.nNo = ++m_nPushCount;
+ if ( !m_Queue.push( node )) {
+ ++m_nPushError;
+ --m_nPushCount;
+ }
+ }
+ else
+ pop( nThreadCount );
+ }
+
+ s_nProducerCount.fetch_sub( 1, std::memory_order_relaxed );
+
+ while ( !m_Queue.empty() || s_nProducerCount.load( std::memory_order_relaxed ) != 0 )
+ pop( nThreadCount );
+ }
+
+ bool pop( size_t nThreadCount )
+ {
+ value_type node;
+ node.nThread = nThreadCount;
+ node.nNo = ~0;
+ if ( m_Queue.pop( node )) {
+ ++m_nPopCount;
+ if ( node.nThread < nThreadCount ) {
+ m_arrPopCountPerThread[ node.nThread ] += 1;
+ if ( m_nSpread ) {
+ if ( m_arrLastRead[ node.nThread ] > node.nNo ) {
+ if ( m_arrLastRead[ node.nThread ] - node.nNo > m_nSpread )
+ ++m_nRepeatValue;
+ }
+ else if ( m_arrLastRead[ node.nThread ] == node.nNo )
+ ++m_nRepeatValue;
+ m_arrLastRead[ node.nThread ] = node.nNo;
+ }
+ else {
+ if ( m_arrLastRead[ node.nThread ] < node.nNo )
+ m_arrLastRead[ node.nThread ] = node.nNo;
+ else
+ ++m_nRepeatValue;
+ }
+ }
+ else
+ ++m_nUndefWriter;
+ }
+ else {
+ ++m_nEmptyPop;
+ return false;
+ }
+ return true;
+ }
+
+ public:
+ Queue& m_Queue;
+
+ size_t m_nPushCount = 0;
+ size_t m_nPopCount = 0;
+ size_t m_nEmptyPop = 0;
+
+ size_t m_nUndefWriter = 0;
+ size_t m_nRepeatValue = 0;
+ size_t m_nPushError = 0;
+
+ std::vector<size_t> m_arrLastRead;
+ std::vector<size_t> m_arrPopCountPerThread;
+
+ size_t const m_nSpread;
+ size_t const m_nTotalPushCount;
+ };
+
+ public:
+ static void SetUpTestCase()\r
+ {\r
+ cds_test::config const& cfg = get_config( "queue_random" );\r
+\r
+ s_nThreadCount = cfg.get_size_t( "ThreadCount", s_nThreadCount );
+ s_nQueueSize = cfg.get_size_t( "QueueSize", s_nQueueSize );
+
+ if ( s_nThreadCount == 0 )
+ s_nThreadCount = 1;
+ if ( s_nQueueSize == 0 )
+ s_nQueueSize = 1000;
+ }\r
+\r
+ //static void TearDownTestCase();\r
+
+ protected:
+ template <class Queue>
+ void analyze( Queue& q )
+ {
+ EXPECT_TRUE( q.empty() );
+
+ std::vector< size_t > arrPushCount;
+ arrPushCount.resize( s_nThreadCount, 0 );
+
+ size_t nPushTotal = 0;
+ size_t nPopTotal = 0;
+ size_t nPushError = 0;
+
+ cds_test::thread_pool& pool = get_pool();
+ for ( size_t i = 0; i < pool.size(); ++i ) {
+ Strain<Queue>& thr = static_cast<Strain<Queue> &>( pool.get(i));
+ EXPECT_EQ( thr.m_nUndefWriter, 0 );
+ EXPECT_EQ( thr.m_nRepeatValue, 0 );
+ EXPECT_EQ( thr.m_nPushError, 0 );
+ nPushError += thr.m_nPushError;
+
+ arrPushCount[ thr.id() ] += thr.m_nPushCount;
+
+ nPushTotal += thr.m_nPushCount;
+ nPopTotal += thr.m_nPopCount;
+ }
+
+ EXPECT_EQ( nPushTotal, s_nQueueSize );
+ EXPECT_EQ( nPopTotal, s_nQueueSize );
+
+ size_t const nThreadPushCount = s_nQueueSize / s_nThreadCount;
+ for ( size_t i = 0; i < s_nThreadCount; ++i )
+ EXPECT_EQ( arrPushCount[i], nThreadPushCount ) << "thread=" << i;
+ }
+
+ template <class Queue>
+ void test( Queue& q )
+ {
+ size_t nThreadPushCount = s_nQueueSize / s_nThreadCount;
+
+ cds_test::thread_pool& pool = get_pool();
+ pool.add( new Strain<Queue>( pool, q, nThreadPushCount ), s_nThreadCount );
+
+ s_nQueueSize = nThreadPushCount * s_nThreadCount;
+ propout() << std::make_pair( "thread_count", s_nThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize );
+
+ s_nProducerCount.store( pool.size(), std::memory_order_release );
+ std::chrono::milliseconds duration = pool.run();
+ propout() << std::make_pair( "duration", duration );
+
+ analyze( q );
+
+ propout() << q.statistics();
+ }
+ };
+
+ CDSSTRESS_MSQueue( queue_random )
+ CDSSTRESS_MoirQueue( queue_random )
+ CDSSTRESS_BasketQueue( queue_random )
+ CDSSTRESS_OptimsticQueue( queue_random )
+ CDSSTRESS_FCQueue( queue_random )
+ CDSSTRESS_FCDeque( queue_random )
+ CDSSTRESS_RWQueue( queue_random )
+ CDSSTRESS_StdQueue( queue_random )
+
+#undef CDSSTRESS_Queue_F
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_F( test_fixture, type_name ) \
+ { \
+ typedef queue::Types< value_type >::type_name queue_type; \
+ queue_type queue( s_nQueueSize ); \
+ test( queue ); \
+ }
+
+ CDSSTRESS_TsigasQueue( queue_random )
+ CDSSTRESS_VyukovQueue( queue_random )
+
+#undef CDSSTRESS_Queue_F
+
+ // ********************************************************************
+ // SegmentedQueue test
+
+ class segmented_queue_random
+ : public queue_random
+ , public ::testing::WithParamInterface< size_t >
+ {
+ typedef queue_random base_class;
+
+ protected:
+ template <typename Queue>
+ void test()
+ {
+ size_t quasi_factor = GetParam();
+
+ Queue q( quasi_factor );
+ propout() << std::make_pair( "quasi_factor", quasi_factor );
+
+ size_t nThreadPushCount = s_nQueueSize / s_nThreadCount;
+
+ cds_test::thread_pool& pool = get_pool();
+ pool.add( new Strain<Queue>( pool, q, nThreadPushCount, quasi_factor * 2 ), s_nThreadCount );
+
+ s_nQueueSize = nThreadPushCount * s_nThreadCount;
+ propout() << std::make_pair( "thread_count", s_nThreadCount )
+ << std::make_pair( "push_count", s_nQueueSize );
+
+ s_nProducerCount.store( pool.size(), std::memory_order_release );
+ std::chrono::milliseconds duration = pool.run();
+ propout() << std::make_pair( "duration", duration );
+
+ analyze( q );
+
+ propout() << q.statistics();
+ }
+
+ public:
+ static std::vector< size_t > get_test_parameters()
+ {
+ cds_test::config const& cfg = cds_test::stress_fixture::get_config( "queue_push" );
+ bool bIterative = cfg.get_bool( "SegmentedQueue_Iterate", false );
+ size_t quasi_factor = cfg.get_size_t( "SegmentedQueue_SegmentSize", 256 );
+
+ std::vector<size_t> args;
+ if ( bIterative && quasi_factor > 4 ) {
+ for ( size_t qf = 4; qf <= quasi_factor; qf *= 2 )
+ args.push_back( qf );
+ }
+ else {
+ if ( quasi_factor > 2 )
+ args.push_back( quasi_factor );
+ else
+ args.push_back( 2 );
+ }
+
+ return args;
+ }
+ };
+
+#define CDSSTRESS_Queue_F( test_fixture, type_name ) \
+ TEST_P( test_fixture, type_name ) \
+ { \
+ typedef typename queue::Types<value_type>::type_name queue_type; \
+ test< queue_type >(); \
+ }
+
+ CDSSTRESS_SegmentedQueue( segmented_queue_random )
+
+ INSTANTIATE_TEST_CASE_P( SQ,
+ segmented_queue_random,
+ ::testing::ValuesIn( segmented_queue_random::get_test_parameters()));
+} // 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.
+*/
+
+#ifndef CDSUNIT_QUEUE_STD_QUEUE_H
+#define CDSUNIT_QUEUE_STD_QUEUE_H
+
+#include <mutex> //unique_lock
+#include <queue>
+#include <list>
+#include <cds/sync/spinlock.h>
+
+namespace queue {
+
+ template <typename T, class Container, class Lock = cds::sync::spin >
+ class StdQueue: public std::queue<T, Container >
+ {
+ typedef std::queue<T, Container > base_class;
+ Lock m_Locker;
+
+ public:
+ bool enqueue( const T& data )
+ {
+ std::unique_lock<Lock> a(m_Locker);
+
+ base_class::push( data );
+ return true;
+ }
+ bool push( const T& data ) { return enqueue( data ) ; }
+ bool dequeue( T& data )
+ {
+ std::unique_lock<Lock> a(m_Locker);
+ if ( base_class::empty() )
+ return false;
+
+ data = base_class::front();
+ base_class::pop();
+ return true;
+ }
+ bool pop( T& data ) { return dequeue( data ) ; }
+
+ cds::opt::none statistics() const
+ {
+ return cds::opt::none();
+ }
+ };
+
+ template <typename T, class Lock = cds::sync::spin >
+ using StdQueue_deque = StdQueue<T, std::deque<T>, Lock >;
+
+ template <typename T, class Lock = cds::sync::spin >
+ using StdQueue_list = StdQueue<T, std::list<T>, Lock >;
+}
+
+#endif // #ifndef CDSUNIT_QUEUE_STD_QUEUE_H
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)
-file(COPY ${CONF_FILES} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
\ No newline at end of file
+#file(GLOB CONF_FILES ${PROJECT_SOURCE_DIR}/tests/data/*.conf)
+#file(COPY ${CONF_FILES} DESTINATION ${EXECUTABLE_OUTPUT_PATH})
\ No newline at end of file
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/map2)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/pqueue)
-add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/queue)
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/set2)
+++ /dev/null
-set(PACKAGE_NAME cdsu-queue)
-
-set(CDSUNIT_QUEUE_SOURCES
- bounded_queue_fulness.cpp
- queue_pop.cpp
- queue_push.cpp
- queue_random.cpp
- queue_reader_writer.cpp
- intrusive_queue_reader_writer.cpp)
-
-add_executable(${PACKAGE_NAME} ${CDSUNIT_QUEUE_SOURCES} $<TARGET_OBJECTS:${TEST_COMMON}>)
-target_link_libraries(${PACKAGE_NAME} ${CDS_SHARED_LIBRARY} ${Boost_THREAD_LIBRARY} ${Boost_SYSTEM_LIBRARY} ${CMAKE_THREAD_LIBS_INIT})
-add_test(NAME ${PACKAGE_NAME} COMMAND ${PACKAGE_NAME} WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH})
\ No newline at end of file
+++ /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 "queue/queue_type.h"
-#include "queue/queue_defs.h"
-
-
-/*
- Bounded queue test.
- The test checks the behaviour of bounded queue when it is almost full.
- Many algorithms says the queue is full when it is not, and vice versa.
-*/
-namespace queue {
-
-#define TEST_BOUNDED( Q, V ) void Q() { test< Types<V>::Q >(); }
-
- namespace ns_BoundedQueue_Fullness {
- static size_t s_nThreadCount = 8;
- static size_t s_nQueueSize = 1024;
- static size_t s_nPassCount = 1000000;
- }
- using namespace ns_BoundedQueue_Fullness;
-
- class BoundedQueue_Fullness: public CppUnitMini::TestCase
- {
- template <class Queue>
- class Thread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Thread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nPushError;
- size_t m_nPopError;
-
- public:
- Thread( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {}
- Thread( Thread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {}
-
- BoundedQueue_Fullness& getTest()
- {
- return reinterpret_cast<BoundedQueue_Fullness&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_fTime = m_Timer.duration();
-
- m_nPushError = 0;
- m_nPopError = 0;
- for ( size_t i = 0; i < s_nPassCount; ++i ) {
- if ( !m_Queue.push( i ))
- ++m_nPushError;
- size_t item;
- if ( !m_Queue.pop( item ))
- ++m_nPopError;
- }
- m_fTime = m_Timer.duration() - m_fTime;
- }
- };
-
- protected:
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue )
- {
- double fTime = 0;
- size_t nPushError = 0;
- size_t nPopError = 0;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- fTime += pThread->m_fTime;
- nPushError += pThread->m_nPushError;
- nPopError += pThread->m_nPopError;
- }
- CPPUNIT_MSG( " Duration=" << (fTime / s_nThreadCount) );
- CPPUNIT_MSG( " Errors: push=" << nPushError << ", pop=" << nPopError );
- CPPUNIT_CHECK( !testQueue.empty());
- CPPUNIT_CHECK( nPushError == 0 );
- CPPUNIT_CHECK( nPopError == 0 );
- }
-
- template <class Queue>
- void test()
- {
- Queue testQueue( s_nQueueSize );
-
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- size_t nSize = testQueue.capacity() - s_nThreadCount;
- for ( size_t i = 0; i < nSize; ++i )
- testQueue.push( i );
-
- CPPUNIT_MSG( " Thread count=" << s_nThreadCount << ", push/pop pairs=" << s_nPassCount
-
- << ", queue capacity=" << testQueue.capacity() << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nThreadCount = cfg.getULong("ThreadCount", 8 );
- s_nQueueSize = cfg.getULong("QueueSize", 1024 );
- s_nPassCount = cfg.getULong( "PassCount", 1000000 );
- }
-
- protected:
- CDSUNIT_DECLARE_TsigasCycleQueue( size_t )
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue( size_t )
-
- CPPUNIT_TEST_SUITE( BoundedQueue_Fullness )
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::BoundedQueue_Fullness );
+++ /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 CDSUNIT_INTRUSIVE_QUEUE_DEFS_H
-#define CDSUNIT_INTRUSIVE_QUEUE_DEFS_H
-
-// MSQueue
-#define CDSUNIT_DECLARE_MSQueue \
- TEST_CASE(MSQueue_HP, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MSQueue_HP_ic, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MSQueue_HP_stat, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MSQueue_HP_seqcst, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MSQueue_DHP, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MSQueue_DHP_ic, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MSQueue_DHP_stat, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MSQueue_DHP_seqcst, cds::intrusive::msqueue::node< cds::gc::DHP > )
-
-#define CDSUNIT_TEST_MSQueue \
- CPPUNIT_TEST(MSQueue_HP) \
- CPPUNIT_TEST(MSQueue_HP_ic) \
- CPPUNIT_TEST(MSQueue_HP_stat) \
- CPPUNIT_TEST(MSQueue_HP_seqcst) \
- CPPUNIT_TEST(MSQueue_DHP) \
- CPPUNIT_TEST(MSQueue_DHP_ic) \
- CPPUNIT_TEST(MSQueue_DHP_stat) \
- CPPUNIT_TEST(MSQueue_DHP_seqcst)
-
-// MoirQueue
-#define CDSUNIT_DECLARE_MoirQueue \
- TEST_CASE(MoirQueue_HP, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MoirQueue_HP_ic, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MoirQueue_HP_stat, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MoirQueue_HP_seqcst, cds::intrusive::msqueue::node< cds::gc::HP > ) \
- TEST_CASE(MoirQueue_DHP, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MoirQueue_DHP_ic, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MoirQueue_DHP_stat, cds::intrusive::msqueue::node< cds::gc::DHP > ) \
- TEST_CASE(MoirQueue_DHP_seqcst, cds::intrusive::msqueue::node< cds::gc::DHP > )
-
-#define CDSUNIT_TEST_MoirQueue \
- CPPUNIT_TEST(MoirQueue_HP) \
- CPPUNIT_TEST(MoirQueue_HP_ic) \
- CPPUNIT_TEST(MoirQueue_HP_stat) \
- CPPUNIT_TEST(MoirQueue_HP_seqcst) \
- CPPUNIT_TEST(MoirQueue_DHP) \
- CPPUNIT_TEST(MoirQueue_DHP_ic) \
- CPPUNIT_TEST(MoirQueue_DHP_stat) \
- CPPUNIT_TEST(MoirQueue_DHP_seqcst)
-
-
-// OptimisticQueue
-#define CDSUNIT_DECLARE_OptimisticQueue \
- TEST_CASE(OptimisticQueue_HP, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \
- TEST_CASE(OptimisticQueue_HP_ic, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \
- TEST_CASE(OptimisticQueue_HP_stat, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \
- TEST_CASE(OptimisticQueue_HP_seqcst, cds::intrusive::optimistic_queue::node< cds::gc::HP > ) \
- TEST_CASE(OptimisticQueue_DHP, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \
- TEST_CASE(OptimisticQueue_DHP_ic, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \
- TEST_CASE(OptimisticQueue_DHP_stat, cds::intrusive::optimistic_queue::node< cds::gc::DHP > ) \
- TEST_CASE(OptimisticQueue_DHP_seqcst, cds::intrusive::optimistic_queue::node< cds::gc::DHP > )
-
-#define CDSUNIT_TEST_OptimisticQueue \
- CPPUNIT_TEST(OptimisticQueue_HP) \
- CPPUNIT_TEST(OptimisticQueue_HP_ic) \
- CPPUNIT_TEST(OptimisticQueue_HP_stat) \
- CPPUNIT_TEST(OptimisticQueue_HP_seqcst) \
- CPPUNIT_TEST(OptimisticQueue_DHP) \
- CPPUNIT_TEST(OptimisticQueue_DHP_ic) \
- CPPUNIT_TEST(OptimisticQueue_DHP_stat) \
- CPPUNIT_TEST(OptimisticQueue_DHP_seqcst)
-
-
-// BasketQueue
-#define CDSUNIT_DECLARE_BasketQueue \
- TEST_CASE(BasketQueue_HP, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
- TEST_CASE(BasketQueue_HP_ic, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
- TEST_CASE(BasketQueue_HP_stat, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
- TEST_CASE(BasketQueue_HP_seqcst, cds::intrusive::basket_queue::node< cds::gc::HP > ) \
- TEST_CASE(BasketQueue_DHP, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
- TEST_CASE(BasketQueue_DHP_ic, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
- TEST_CASE(BasketQueue_DHP_stat, cds::intrusive::basket_queue::node< cds::gc::DHP > ) \
- TEST_CASE(BasketQueue_DHP_seqcst, cds::intrusive::basket_queue::node< cds::gc::DHP > )
-
-#define CDSUNIT_TEST_BasketQueue \
- CPPUNIT_TEST(BasketQueue_HP) \
- CPPUNIT_TEST(BasketQueue_HP_ic) \
- CPPUNIT_TEST(BasketQueue_HP_stat) \
- CPPUNIT_TEST(BasketQueue_HP_seqcst) \
- CPPUNIT_TEST(BasketQueue_DHP) \
- CPPUNIT_TEST(BasketQueue_DHP_ic) \
- CPPUNIT_TEST(BasketQueue_DHP_stat) \
- CPPUNIT_TEST(BasketQueue_DHP_seqcst)
-
-// TsigasCycleQueue
-#define CDSUNIT_DECLARE_TsigasCycleQueue \
- TEST_BOUNDED(TsigasCycleQueue_dyn) \
- TEST_BOUNDED(TsigasCycleQueue_dyn_ic)
-
-#define CDSUNIT_TEST_TsigasCycleQueue \
- CPPUNIT_TEST(TsigasCycleQueue_dyn) \
- CPPUNIT_TEST(TsigasCycleQueue_dyn_ic)
-
-
-// VyukovMPMCCycleQueue
-#define CDSUNIT_DECLARE_VyukovMPMCCycleQueue \
- TEST_BOUNDED(VyukovMPMCCycleQueue_dyn) \
- TEST_BOUNDED(VyukovMPMCCycleQueue_dyn_ic)
-
-#define CDSUNIT_TEST_VyukovMPMCCycleQueue \
- CPPUNIT_TEST(VyukovMPMCCycleQueue_dyn) \
- CPPUNIT_TEST(VyukovMPMCCycleQueue_dyn_ic)
-
-
-// FCQueue
-#define CDSUNIT_DECLARE_FCQueue \
- TEST_FCQUEUE(FCQueue_list_delay2, boost::intrusive::list_base_hook<> ) \
- TEST_FCQUEUE(FCQueue_list_delay2_elimination, boost::intrusive::list_base_hook<> ) \
- TEST_FCQUEUE(FCQueue_list_delay2_elimination_stat, boost::intrusive::list_base_hook<> ) \
- TEST_FCQUEUE(FCQueue_list_expbackoff_elimination, boost::intrusive::list_base_hook<> ) \
- TEST_FCQUEUE(FCQueue_list_expbackoff_elimination_stat, boost::intrusive::list_base_hook<> )
-
-#define CDSUNIT_TEST_FCQueue \
- CPPUNIT_TEST(FCQueue_list_delay2) \
- CPPUNIT_TEST(FCQueue_list_delay2_elimination) \
- CPPUNIT_TEST(FCQueue_list_delay2_elimination_stat) \
- CPPUNIT_TEST(FCQueue_list_expbackoff_elimination) \
- CPPUNIT_TEST(FCQueue_list_expbackoff_elimination_stat)
-
-// SegmentedQueue
-#define CDSUNIT_DECLARE_SegmentedQueue \
- TEST_SEGMENTED( SegmentedQueue_HP_spin ) \
- TEST_SEGMENTED( SegmentedQueue_HP_spin_padding ) \
- TEST_SEGMENTED( SegmentedQueue_HP_spin_stat ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex_padding ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex_stat ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin_padding ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin_stat ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex_padding ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex_stat )
-
-#define CDSUNIT_TEST_SegmentedQueue \
- CPPUNIT_TEST( SegmentedQueue_HP_spin ) \
- CPPUNIT_TEST( SegmentedQueue_HP_spin_padding ) \
- CPPUNIT_TEST( SegmentedQueue_HP_spin_stat ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex_padding ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex_stat ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin_padding ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin_stat ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex_padding ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex_stat )
-
-
-// BoostSList
-#define CDSUNIT_DECLARE_BoostSList \
- TEST_BOOST( BoostSList_mutex, boost::intrusive::slist_base_hook<> ) \
- TEST_BOOST( BoostSList_spin, boost::intrusive::slist_base_hook<> )
-
-#define CDSUNIT_TEST_BoostSList \
- CPPUNIT_TEST( BoostSList_mutex ) \
- CPPUNIT_TEST( BoostSList_spin )
-
-#endif // #ifndef CDSUNIT_INTRUSIVE_QUEUE_DEFS_H
+++ /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 "queue/intrusive_queue_type.h"
-#include "queue/intrusive_queue_defs.h"
-#include <vector>
-#include <algorithm>
-
-// Multi-threaded random queue test
-namespace queue {
-
-#define TEST_CASE( Q, HOOK ) void Q() { test< Types< Value<HOOK> >::Q >(); }
-#define TEST_BOUNDED( Q ) void Q() { test_bounded< Types< Value<> >::Q >(); }
-#define TEST_FCQUEUE( Q, HOOK ) void Q() { test_fcqueue< Types< Value<HOOK> >::Q >(); }
-#define TEST_SEGMENTED( Q ) void Q() { test_segmented< Types< Value<> >::Q >(); }
-#define TEST_BOOST( Q, HOOK ) void Q() { test_boost< Types< Value<HOOK> >::Q >(); }
-
- namespace {
- static size_t s_nReaderThreadCount = 4;
- static size_t s_nWriterThreadCount = 4;
- static size_t s_nQueueSize = 4000000;
- static unsigned int s_nFCPassCount = 8;
- static unsigned int s_nFCCompactFactor = 64;
-
- struct empty {};
-
- template <typename Base = empty >
- struct Value: public Base
- {
- size_t nNo;
- size_t nWriterNo;
- size_t nConsumer;
- };
- }
-
- class IntrusiveQueue_ReaderWriter: public CppUnitMini::TestCase
- {
- template <class Queue>
- class Producer: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Producer( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nPushFailed;
-
- // Interval in m_arrValue
- typename Queue::value_type * m_pStart;
- typename Queue::value_type * m_pEnd;
-
- public:
- Producer( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {}
- Producer( Producer& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {}
-
- IntrusiveQueue_ReaderWriter& getTest()
- {
- return static_cast<IntrusiveQueue_ReaderWriter&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_nPushFailed = 0;
-
- m_fTime = m_Timer.duration();
-
- size_t i = 0;
- for ( typename Queue::value_type * p = m_pStart; p < m_pEnd; ) {
- p->nNo = i;
- p->nWriterNo = m_nThreadNo;
- CDS_TSAN_ANNOTATE_HAPPENS_BEFORE( &p->nWriterNo );
- if ( m_Queue.push( *p )) {
- ++p;
- ++i;
- }
- else
- ++m_nPushFailed;
- }
-
- m_fTime = m_Timer.duration() - m_fTime;
- getTest().m_nProducerCount.fetch_sub( 1, atomics::memory_order_release );
- }
- };
-
- template <class Queue>
- class Consumer: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Consumer( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nPopEmpty;
- size_t m_nPopped;
- size_t m_nBadWriter;
-
- typedef std::vector<size_t> TPoppedData;
- typedef std::vector<size_t>::iterator data_iterator;
- typedef std::vector<size_t>::const_iterator const_data_iterator;
-
- std::vector<TPoppedData> m_WriterData;
-
- private:
- void initPoppedData()
- {
- const size_t nWriterCount = s_nWriterThreadCount;
- const size_t nWriterPushCount = getTest().m_nThreadPushCount;
- m_WriterData.resize( nWriterCount );
- for ( size_t i = 0; i < nWriterCount; ++i )
- m_WriterData[i].reserve( nWriterPushCount );
- }
-
- public:
- Consumer( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {
- initPoppedData();
- }
- Consumer( Consumer& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {
- initPoppedData();
- }
-
- IntrusiveQueue_ReaderWriter& getTest()
- {
- return static_cast<IntrusiveQueue_ReaderWriter&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_nPopEmpty = 0;
- m_nPopped = 0;
- m_nBadWriter = 0;
- const size_t nTotalWriters = s_nWriterThreadCount;
-
- m_fTime = m_Timer.duration();
-
- while ( true ) {
- typename Queue::value_type * p = m_Queue.pop();
- if ( p ) {
- p->nConsumer = m_nThreadNo;
- ++m_nPopped;
- CDS_TSAN_ANNOTATE_HAPPENS_AFTER( &p->nWriterNo );
- if ( p->nWriterNo < nTotalWriters )
- m_WriterData[ p->nWriterNo ].push_back( p->nNo );
- else
- ++m_nBadWriter;
- }
- else {
- ++m_nPopEmpty;
- if ( getTest().m_nProducerCount.load( atomics::memory_order_acquire ) == 0 && m_Queue.empty() )
- break;
- }
- }
-
- m_fTime = m_Timer.duration() - m_fTime;
- }
- };
-
- template <typename T>
- class value_array
- {
- T * m_pArr;
- public:
- value_array( size_t nSize )
- : m_pArr( new T[nSize] )
- {}
-
- ~value_array()
- {
- delete [] m_pArr;
- }
-
- T * get() const { return m_pArr; }
- };
-
-
- protected:
- size_t m_nThreadPushCount;
- atomics::atomic<size_t> m_nProducerCount;
- static CDS_CONSTEXPR const size_t c_nBadConsumer = 0xbadc0ffe;
-
- protected:
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue, size_t /*nLeftOffset*/, size_t nRightOffset )
- {
- typedef Consumer<Queue> Reader;
- typedef Producer<Queue> Writer;
- typedef typename Reader::const_data_iterator ReaderIterator;
-
- size_t nPostTestPops = 0;
- while ( testQueue.pop() )
- ++nPostTestPops;
-
- double fTimeWriter = 0;
- double fTimeReader = 0;
- size_t nTotalPops = 0;
- size_t nPopFalse = 0;
- size_t nPoppedItems = 0;
- size_t nPushFailed = 0;
-
- std::vector< Reader * > arrReaders;
-
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Reader * pReader = dynamic_cast<Reader *>( *it );
- if ( pReader ) {
- fTimeReader += pReader->m_fTime;
- nTotalPops += pReader->m_nPopped;
- nPopFalse += pReader->m_nPopEmpty;
- arrReaders.push_back( pReader );
- CPPUNIT_CHECK_EX( pReader->m_nBadWriter == 0, "reader " << pReader->m_nThreadNo << " bad writer event count=" << pReader->m_nBadWriter );
-
- size_t nPopped = 0;
- for ( size_t n = 0; n < s_nWriterThreadCount; ++n )
- nPopped += pReader->m_WriterData[n].size();
-
- CPPUNIT_MSG( " Reader " << pReader->m_nThreadNo - s_nWriterThreadCount << " popped count=" << nPopped );
- nPoppedItems += nPopped;
- }
- else {
- Writer * pWriter = dynamic_cast<Writer *>( *it );
- CPPUNIT_ASSERT( pWriter != nullptr );
- fTimeWriter += pWriter->m_fTime;
- nPushFailed += pWriter->m_nPushFailed;
- if ( !boost::is_base_of<cds::bounded_container, Queue>::value ) {
- CPPUNIT_CHECK_EX( pWriter->m_nPushFailed == 0,
- "writer " << pWriter->m_nThreadNo << " push failed count=" << pWriter->m_nPushFailed );
- }
- }
- }
- CPPUNIT_CHECK_EX( nTotalPops == nPoppedItems, "nTotalPops=" << nTotalPops << ", nPoppedItems=" << nPoppedItems );
-
- CPPUNIT_MSG( " Readers: duration=" << fTimeReader / s_nReaderThreadCount << ", success pop=" << nTotalPops << ", failed pops=" << nPopFalse );
- CPPUNIT_MSG( " Writers: duration=" << fTimeWriter / s_nWriterThreadCount << ", failed push=" << nPushFailed );
-
- size_t nQueueSize = m_nThreadPushCount * s_nWriterThreadCount;
- CPPUNIT_CHECK_EX( nTotalPops + nPostTestPops == nQueueSize, "popped=" << nTotalPops + nPostTestPops << " must be " << nQueueSize );
- CPPUNIT_CHECK( testQueue.empty() );
-
- // Test that all items have been popped
- // Test FIFO order
- CPPUNIT_MSG( " Test consistency of popped sequence..." );
- size_t nErrors = 0;
- for ( size_t nWriter = 0; nWriter < s_nWriterThreadCount; ++nWriter ) {
- std::vector<size_t> arrData;
- arrData.reserve( m_nThreadPushCount );
- nErrors = 0;
- for ( size_t nReader = 0; nReader < arrReaders.size(); ++nReader ) {
- ReaderIterator it = arrReaders[nReader]->m_WriterData[nWriter].begin();
- ReaderIterator itEnd = arrReaders[nReader]->m_WriterData[nWriter].end();
- if ( it != itEnd ) {
- ReaderIterator itPrev = it;
- for ( ++it; it != itEnd; ++it ) {
- CPPUNIT_CHECK_EX( *itPrev < *it + nRightOffset,
- "Reader " << nReader << ", Writer " << nWriter << ": prev=" << *itPrev << ", cur=" << *it );
- if ( ++nErrors > 10 )
- return;
- itPrev = it;
- }
- }
-
- for ( it = arrReaders[nReader]->m_WriterData[nWriter].begin(); it != itEnd; ++it )
- arrData.push_back( *it );
- }
- std::sort( arrData.begin(), arrData.end() );
- nErrors = 0;
- for ( size_t i=1; i < arrData.size(); ++i ) {
- if ( arrData[i-1] + 1 != arrData[i] ) {
- CPPUNIT_CHECK_EX( arrData[i-1] + 1 == arrData[i], "Writer " << nWriter << ": [" << (i-1) << "]=" << arrData[i-1] << ", [" << i << "]=" << arrData[i] );
- if ( ++nErrors > 10 )
- return;
- }
- }
-
- CPPUNIT_CHECK_EX( arrData[0] == 0, "Writer " << nWriter << "[0] != 0" );
- CPPUNIT_CHECK_EX( arrData[arrData.size() - 1] == m_nThreadPushCount - 1, "Writer " << nWriter << "[last] != " << m_nThreadPushCount - 1 );
- }
- }
-
- template <class Queue>
- void test_with( Queue& testQueue, value_array<typename Queue::value_type>& arrValue, size_t nLeftOffset, size_t nRightOffset )
- {
- m_nThreadPushCount = s_nQueueSize / s_nWriterThreadCount;
- CPPUNIT_MSG( " reader count=" << s_nReaderThreadCount << " writer count=" << s_nWriterThreadCount
- << " item count=" << m_nThreadPushCount * s_nWriterThreadCount << "..." );
-
- typename Queue::value_type * pValStart = arrValue.get();
- typename Queue::value_type * pValEnd = pValStart + s_nQueueSize;
-
- CppUnitMini::ThreadPool pool( *this );
-
- m_nProducerCount.store( s_nWriterThreadCount, atomics::memory_order_release );
-
- // Writers must be first
- pool.add( new Producer<Queue>( pool, testQueue ), s_nWriterThreadCount );
- {
- for ( typename Queue::value_type * it = pValStart; it != pValEnd; ++it ) {
- it->nNo = 0;
- it->nWriterNo = 0;
- it->nConsumer = c_nBadConsumer;
- }
-
- typename Queue::value_type * pStart = pValStart;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- static_cast<Producer<Queue>* >( *it )->m_pStart = pStart;
- pStart += m_nThreadPushCount;
- static_cast<Producer<Queue>* >( *it )->m_pEnd = pStart;
- }
- }
- pool.add( new Consumer<Queue>( pool, testQueue ), s_nReaderThreadCount );
-
- pool.run();
-
- // Check that all values have been dequeued
- {
- size_t nBadConsumerCount = 0;
- size_t nQueueSize = m_nThreadPushCount * s_nWriterThreadCount;
- typename Queue::value_type * pEnd = pValStart + nQueueSize;
- for ( typename Queue::value_type * it = pValStart; it != pEnd; ++it ) {
- if ( it->nConsumer == c_nBadConsumer )
- ++nBadConsumerCount;
- }
- CPPUNIT_CHECK_EX( nBadConsumerCount == 0, "nBadConsumerCount=" << nBadConsumerCount );
- }
-
- analyze( pool, testQueue, nLeftOffset, nRightOffset );
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <typename Queue>
- void test()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- {
- {
- Queue q;
- test_with( q, arrValue, 0, 0 );
- }
- Queue::gc::force_dispose();
- }
- }
-
- template <typename Queue>
- void test_boost()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- {
- Queue q;
- test_with(q, arrValue, 0, 0);
- }
- }
-
- template <typename Queue>
- void test_bounded()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- Queue q;
- test_with(q, arrValue, 0, 0);
- }
-
- template <typename Queue>
- void test_fcqueue()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- CPPUNIT_MSG( "Combining pass count: " << s_nFCPassCount << ", compact factor: " << s_nFCCompactFactor );
- Queue q( s_nFCCompactFactor, s_nFCPassCount );
- test_with(q, arrValue, 0, 0);
- }
-
- template <typename Queue>
- void test_segmented()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
- CPPUNIT_MSG( "Segment size: " << nSegmentSize );
- {
- Queue q( nSegmentSize );
- test_with( q, arrValue, nSegmentSize * 2, nSegmentSize );
- }
- Queue::gc::force_dispose();
- }
- }
-
- template <typename Queue>
- void test_spqueue()
- {
- value_array<typename Queue::value_type> arrValue( s_nQueueSize );
- for ( size_t nArraySize = 2; nArraySize <= 64; nArraySize *= 2 ) {
- CPPUNIT_MSG( "Array size: " << nArraySize );
- {
- Queue q( nArraySize );
- test_with( q, arrValue, 0, 0 );
- }
- Queue::gc::force_dispose();
- }
- }
-
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nReaderThreadCount = cfg.getULong("ReaderCount", 4 );
- s_nWriterThreadCount = cfg.getULong("WriterCount", 4 );
- s_nQueueSize = cfg.getULong("QueueSize", 10000000 );
- s_nFCPassCount = cfg.getUInt("FCPassCount", 8);
- s_nFCCompactFactor = cfg.getUInt("FCCompactFactor", 64);
- }
-
- protected:
- CDSUNIT_DECLARE_MSQueue
- CDSUNIT_DECLARE_MoirQueue
- CDSUNIT_DECLARE_OptimisticQueue
- CDSUNIT_DECLARE_BasketQueue
- CDSUNIT_DECLARE_FCQueue
- CDSUNIT_DECLARE_SegmentedQueue
- CDSUNIT_DECLARE_TsigasCycleQueue
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue
- CDSUNIT_DECLARE_BoostSList
-
-
- CPPUNIT_TEST_SUITE(IntrusiveQueue_ReaderWriter)
- CDSUNIT_TEST_MSQueue
- CDSUNIT_TEST_MoirQueue
- CDSUNIT_TEST_OptimisticQueue
- CDSUNIT_TEST_BasketQueue
- CDSUNIT_TEST_FCQueue
- CDSUNIT_TEST_SegmentedQueue
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CDSUNIT_TEST_BoostSList
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::IntrusiveQueue_ReaderWriter);
+++ /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 CDSUNIT_INTRUSIVE_QUEUE_TYPES_H
-#define CDSUNIT_INTRUSIVE_QUEUE_TYPES_H
-
-#include <cds/intrusive/msqueue.h>
-#include <cds/intrusive/moir_queue.h>
-#include <cds/intrusive/optimistic_queue.h>
-#include <cds/intrusive/tsigas_cycle_queue.h>
-#include <cds/intrusive/vyukov_mpmc_cycle_queue.h>
-#include <cds/intrusive/basket_queue.h>
-#include <cds/intrusive/fcqueue.h>
-#include <cds/intrusive/segmented_queue.h>
-
-#include <cds/gc/hp.h>
-#include <cds/gc/dhp.h>
-
-#include <boost/intrusive/slist.hpp>
-
-#include "print_segmentedqueue_stat.h"
-
-namespace queue {
-
- namespace details {
- struct empty_stat {};
-
- template <typename T, typename Lock=std::mutex>
- class BoostSList
- {
- typedef boost::intrusive::slist< T, boost::intrusive::cache_last<true> > slist_type;
- typedef Lock lock_type;
- typedef std::lock_guard<lock_type> lock_guard;
-
- slist_type m_List;
- mutable lock_type m_Lock;
- public:
- typedef T value_type;
-
- public:
- bool push( value_type& v )
- {
- lock_guard l( m_Lock );
- m_List.push_back( v );
- return true;
- }
-
- bool enqueue( value_type& v )
- {
- return push( v );
- }
-
- value_type * pop()
- {
- lock_guard l( m_Lock );
- if ( m_List.empty() )
- return nullptr;
- value_type& v = m_List.front();
- m_List.pop_front();
- return &v;
- }
- value_type * deque()
- {
- return pop();
- }
-
- bool empty() const
- {
- lock_guard l( m_Lock );
- return m_List.empty();
- }
-
- size_t size() const
- {
- lock_guard l( m_Lock );
- return m_List.size();
- }
-
- empty_stat statistics() const
- {
- return empty_stat();
- }
- };
- }
-
- template <typename T>
- struct Types {
-
- // MSQueue, MoirQueue
- struct traits_MSQueue_HP : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
- };
- typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP > MSQueue_HP;
- typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP > MoirQueue_HP;
-
- struct traits_MSQueue_HP_seqcst : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
- typedef cds::opt::v::sequential_consistent memory_model;
- };
- typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_seqcst > MSQueue_HP_seqcst;
- typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_seqcst > MoirQueue_HP_seqcst;
-
- struct traits_MSQueue_DHP : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
- };
- typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP > MSQueue_DHP;
- typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP > MoirQueue_DHP;
-
- struct traits_MSQueue_DHP_seqcst : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
- typedef cds::opt::v::sequential_consistent memory_model;
- };
- typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_seqcst > MSQueue_DHP_seqcst;
- typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_seqcst > MoirQueue_DHP_seqcst;
-
- // MSQueue + item counter
- struct traits_MSQueue_HP_ic : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
- typedef cds::atomicity::item_counter item_counter;
- };
- typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_ic > MSQueue_HP_ic;
- typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_ic > MoirQueue_HP_ic;
-
- struct traits_MSQueue_DHP_ic : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
- typedef cds::atomicity::item_counter item_counter;
- };
- typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MSQueue_DHP_ic;
- typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_ic > MoirQueue_DHP_ic;
-
- // MSQueue + stat
- struct traits_MSQueue_HP_stat : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
- typedef cds::intrusive::msqueue::stat<> stat;
- };
- typedef cds::intrusive::MSQueue< cds::gc::HP, T, traits_MSQueue_HP_stat > MSQueue_HP_stat;
- typedef cds::intrusive::MoirQueue< cds::gc::HP, T, traits_MSQueue_HP_stat > MoirQueue_HP_stat;
-
- struct traits_MSQueue_DHP_stat : public cds::intrusive::msqueue::traits
- {
- typedef cds::intrusive::msqueue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
- typedef cds::intrusive::msqueue::stat<> stat;
- };
- typedef cds::intrusive::MSQueue< cds::gc::DHP, T, traits_MSQueue_DHP_stat > MSQueue_DHP_stat;
- typedef cds::intrusive::MoirQueue< cds::gc::DHP, T, traits_MSQueue_DHP_stat > MoirQueue_DHP_stat;
-
-
- // OptimisticQueue
- struct traits_OptimisticQueue_HP : public cds::intrusive::optimistic_queue::traits
- {
- typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > hook;
- };
- typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP > OptimisticQueue_HP;
-
- struct traits_OptimisticQueue_HP_seqcst : public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- , cds::opt::memory_model< cds::opt::v::sequential_consistent >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_seqcst > OptimisticQueue_HP_seqcst;
-
- struct traits_OptimisticQueue_DHP : public cds::intrusive::optimistic_queue::traits
- {
- typedef cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > hook;
- };
- typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP > OptimisticQueue_DHP;
-
- struct traits_OptimisticQueue_DHP_seqcst: public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- , cds::opt::memory_model< cds::opt::v::sequential_consistent >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_seqcst > OptimisticQueue_DHP_seqcst;
-
- // OptimisticQueue + item counter
- struct traits_OptimisticQueue_HP_ic: public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- , cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_ic > OptimisticQueue_HP_ic;
-
- struct traits_OptimisticQueue_DHP_ic: public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- , cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_ic > OptimisticQueue_DHP_ic;
-
- // OptimisticQueue + stat
- struct traits_OptimisticQueue_HP_stat: public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::HP, T, traits_OptimisticQueue_HP_stat > OptimisticQueue_HP_stat;
-
- struct traits_OptimisticQueue_DHP_stat: public
- cds::intrusive::optimistic_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::optimistic_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- , cds::opt::stat< cds::intrusive::optimistic_queue::stat<> >
- >::type
- {};
- typedef cds::intrusive::OptimisticQueue< cds::gc::DHP, T, traits_OptimisticQueue_DHP_stat > OptimisticQueue_DHP_stat;
-
- // TsigasCycleQueue
- class TsigasCycleQueue_dyn
- : public cds::intrusive::TsigasCycleQueue< T,
- typename cds::intrusive::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- >::type
- >
- {
- typedef cds::intrusive::TsigasCycleQueue< T,
- typename cds::intrusive::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- >::type
- > base_class;
- public:
- TsigasCycleQueue_dyn()
- : base_class( 1024 * 64 )
- {}
-
- TsigasCycleQueue_dyn( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- class TsigasCycleQueue_dyn_ic
- : public cds::intrusive::TsigasCycleQueue< T,
- typename cds::intrusive::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- >
- {
- typedef cds::intrusive::TsigasCycleQueue< T,
- typename cds::intrusive::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- > base_class;
- public:
- TsigasCycleQueue_dyn_ic()
- : base_class( 1024 * 64 )
- {}
- TsigasCycleQueue_dyn_ic( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- // VyukovMPMCCycleQueue
- struct traits_VyukovMPMCCycleQueue_dyn : public cds::intrusive::vyukov_queue::traits
- {
- typedef cds::opt::v::dynamic_buffer< int > buffer;
- };
- class VyukovMPMCCycleQueue_dyn
- : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn >
- {
- typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn > base_class;
- public:
- VyukovMPMCCycleQueue_dyn()
- : base_class( 1024 * 64 )
- {}
- VyukovMPMCCycleQueue_dyn( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
- {
- typedef cds::atomicity::item_counter item_counter;
- };
- class VyukovMPMCCycleQueue_dyn_ic
- : public cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic >
- {
- typedef cds::intrusive::VyukovMPMCCycleQueue< T, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
- public:
- VyukovMPMCCycleQueue_dyn_ic()
- : base_class( 1024 * 64 )
- {}
- VyukovMPMCCycleQueue_dyn_ic( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- // BasketQueue
- struct traits_BasketQueue_HP : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP > BasketQueue_HP;
-
- struct traits_BasketQueue_HP_seqcst: public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- , cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue<cds::gc::HP, T, traits_BasketQueue_HP_seqcst > BasketQueue_HP_seqcst;
-
- struct traits_BasketQueue_DHP : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP > BasketQueue_DHP;
-
- struct traits_BasketQueue_DHP_seqcst: public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- , cds::opt::memory_model< cds::opt::v::sequential_consistent >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_seqcst > BasketQueue_DHP_seqcst;
-
- // BasketQueue + item counter
- struct traits_BasketQueue_HP_ic : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_ic > BasketQueue_HP_ic;
-
- struct traits_BasketQueue_DHP_ic : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_ic > BasketQueue_DHP_ic;
-
- // BasketQueue + stat
- struct traits_BasketQueue_HP_stat : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::HP > > >
- , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::HP, T, traits_BasketQueue_HP_stat > BasketQueue_HP_stat;
-
- struct traits_BasketQueue_DHP_stat : public
- cds::intrusive::basket_queue::make_traits <
- cds::intrusive::opt::hook< cds::intrusive::basket_queue::base_hook< cds::opt::gc< cds::gc::DHP > > >
- , cds::opt::stat< cds::intrusive::basket_queue::stat<> >
- > ::type
- {};
- typedef cds::intrusive::BasketQueue< cds::gc::DHP, T, traits_BasketQueue_DHP_stat > BasketQueue_DHP_stat;
-
- // FCQueue
- class traits_FCQueue_delay2:
- public cds::intrusive::fcqueue::make_traits<
- cds::opt::back_off< cds::backoff::delay_of<2> >
- >::type
- {};
- class traits_FCQueue_delay2_elimination:
- public cds::intrusive::fcqueue::make_traits<
- cds::opt::back_off< cds::backoff::delay_of<2> >
- ,cds::opt::enable_elimination< true >
- >::type
- {};
- class traits_FCQueue_delay2_elimination_stat:
- public cds::intrusive::fcqueue::make_traits<
- cds::opt::back_off< cds::backoff::delay_of<2> >
- ,cds::opt::stat< cds::intrusive::fcqueue::stat<> >
- ,cds::opt::enable_elimination< true >
- >::type
- {};
- class traits_FCQueue_expbackoff_elimination:
- public cds::intrusive::fcqueue::make_traits<
- cds::opt::enable_elimination< true >
- ,cds::opt::elimination_backoff< cds::backoff::Default >
- >::type
- {};
- class traits_FCQueue_expbackoff_elimination_stat:
- public cds::intrusive::fcqueue::make_traits<
- cds::opt::enable_elimination< true >
- ,cds::opt::stat< cds::intrusive::fcqueue::stat<> >
- ,cds::opt::elimination_backoff< cds::backoff::Default >
- >::type
- {};
-
- typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2 > FCQueue_list_delay2;
- typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2_elimination > FCQueue_list_delay2_elimination;
- typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_delay2_elimination_stat > FCQueue_list_delay2_elimination_stat;
- typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_expbackoff_elimination > FCQueue_list_expbackoff_elimination;
- typedef cds::intrusive::FCQueue< T, boost::intrusive::list<T>, traits_FCQueue_expbackoff_elimination_stat > FCQueue_list_expbackoff_elimination_stat;
-
- // SegmentedQueue
- class traits_SegmentedQueue_spin_stat:
- public cds::intrusive::segmented_queue::make_traits<
- cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
- >::type
- {};
- class traits_SegmentedQueue_spin_padding :
- public cds::intrusive::segmented_queue::make_traits<
- cds::opt::padding< cds::opt::cache_line_padding >
- >::type
- {};
- class traits_SegmentedQueue_mutex_stat :
- public cds::intrusive::segmented_queue::make_traits<
- cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
- ,cds::opt::lock_type< std::mutex >
- >::type
- {};
- class traits_SegmentedQueue_mutex:
- public cds::intrusive::segmented_queue::make_traits<
- cds::opt::lock_type< std::mutex >
- >::type
- {};
- class traits_SegmentedQueue_mutex_padding:
- public cds::intrusive::segmented_queue::make_traits<
- cds::opt::lock_type< std::mutex >
- ,cds::opt::padding< cds::opt::cache_line_padding >
- >::type
- {};
-
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T > SegmentedQueue_HP_spin;
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_spin_padding > SegmentedQueue_HP_spin_padding;
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_spin_stat > SegmentedQueue_HP_spin_stat;
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex > SegmentedQueue_HP_mutex;
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex_padding > SegmentedQueue_HP_mutex_padding;
- typedef cds::intrusive::SegmentedQueue< cds::gc::HP, T, traits_SegmentedQueue_mutex_stat > SegmentedQueue_HP_mutex_stat;
-
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T > SegmentedQueue_DHP_spin;
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_spin_padding > SegmentedQueue_DHP_spin_padding;
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_spin_stat > SegmentedQueue_DHP_spin_stat;
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex > SegmentedQueue_DHP_mutex;
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex_padding > SegmentedQueue_DHP_mutex_padding;
- typedef cds::intrusive::SegmentedQueue< cds::gc::DHP, T, traits_SegmentedQueue_mutex_stat > SegmentedQueue_DHP_mutex_stat;
-
- // Boost SList
- typedef details::BoostSList< T, std::mutex > BoostSList_mutex;
- typedef details::BoostSList< T, cds::sync::spin > BoostSList_spin;
- };
-}
-
-
-// *********************************************
-// Queue statistics
-namespace std {
- /*
- // cds::intrusive::queue_stat
- template <typename Counter>
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_stat<Counter> const& s)
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n";
- }
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::queue_dummy_stat const& s)
- {
- return o;
- }
- */
-
-
- template <typename Counter>
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::stat<Counter> const& s)
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
- << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n"
- << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n";
- }
- static inline std::ostream& operator <<(std::ostream& o, cds::intrusive::basket_queue::empty_stat const& /*s*/)
- {
- return o;
- }
-
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::msqueue::stat<Counter> const& s )
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::msqueue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::opt::none )
- {
- return o;
- }
-
- // cds::intrusive::optimistic_queue::stat
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::optimistic_queue::stat<Counter> const& s )
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
- << "\t\t fix list call: " << s.m_FixListCount.get() << "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::optimistic_queue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- // cds::intrusive::fcqueue::stat
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::fcqueue::stat<Counter> const& s )
- {
- return o << "\tStatistics:\n"
- << "\t Push: " << s.m_nEnqueue.get() << "\n"
- << "\t Pop: " << s.m_nDequeue.get() << "\n"
- << "\t FailedPop: " << s.m_nFailedDeq.get() << "\n"
- << "\t Collided push/pop pair: " << s.m_nCollided.get() << "\n"
- << "\tFlat combining statistics:\n"
- << "\t Combining factor: " << s.combining_factor() << "\n"
- << "\t Operation count: " << s.m_nOperationCount.get() << "\n"
- << "\t Combine call count: " << s.m_nCombiningCount.get() << "\n"
- << "\t Compact pub-list: " << s.m_nCompactPublicationList.get() << "\n"
- << "\t Deactivate pub-record: " << s.m_nDeactivatePubRecord.get() << "\n"
- << "\t Activate pub-record: " << s.m_nActivatePubRecord.get() << "\n"
- << "\t Create pub-record: " << s.m_nPubRecordCreated.get() << "\n"
- << "\t Delete pub-record: " << s.m_nPubRecordDeteted.get() << "\n"
- << "\t Acquire pub-record: " << s.m_nAcquirePubRecCount.get()<< "\n"
- << "\t Release pub-record: " << s.m_nReleasePubRecCount.get()<< "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::fcqueue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- static inline std::ostream& operator <<( std::ostream& o, queue::details::empty_stat const& /*s*/ )
- {
- return o;
- }
-
-} // namespace std
-
-#endif // #ifndef CDSUNIT_INTRUSIVE_QUEUE_TYPES_H
+++ /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 CDSUNIT_QUEUE_DEFS_H
-#define CDSUNIT_QUEUE_DEFS_H
-
-// MoirQueue
-#define CDSUNIT_DECLARE_MoirQueue( ITEM_TYPE ) \
- TEST_CASE( MoirQueue_HP, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_HP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_HP_seqcst, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_HP_ic, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_HP_stat, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_DHP, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_DHP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_DHP_seqcst, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_DHP_ic, ITEM_TYPE ) \
- TEST_CASE( MoirQueue_DHP_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_MoirQueue \
- CPPUNIT_TEST(MoirQueue_HP) \
- CPPUNIT_TEST(MoirQueue_HP_michaelAlloc) \
- CPPUNIT_TEST(MoirQueue_HP_seqcst) \
- CPPUNIT_TEST(MoirQueue_HP_ic) \
- CPPUNIT_TEST(MoirQueue_HP_stat) \
- CPPUNIT_TEST(MoirQueue_DHP) \
- CPPUNIT_TEST(MoirQueue_DHP_michaelAlloc) \
- CPPUNIT_TEST(MoirQueue_DHP_seqcst) \
- CPPUNIT_TEST(MoirQueue_DHP_ic) \
- CPPUNIT_TEST(MoirQueue_DHP_stat)
-
-// MSQueue
-#define CDSUNIT_DECLARE_MSQueue( ITEM_TYPE ) \
- TEST_CASE( MSQueue_HP, ITEM_TYPE ) \
- TEST_CASE( MSQueue_HP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( MSQueue_HP_seqcst, ITEM_TYPE ) \
- TEST_CASE( MSQueue_HP_ic, ITEM_TYPE ) \
- TEST_CASE( MSQueue_HP_stat, ITEM_TYPE ) \
- TEST_CASE( MSQueue_DHP, ITEM_TYPE ) \
- TEST_CASE( MSQueue_DHP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( MSQueue_DHP_seqcst, ITEM_TYPE ) \
- TEST_CASE( MSQueue_DHP_ic, ITEM_TYPE ) \
- TEST_CASE( MSQueue_DHP_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_MSQueue \
- CPPUNIT_TEST(MSQueue_HP) \
- CPPUNIT_TEST(MSQueue_HP_michaelAlloc) \
- CPPUNIT_TEST(MSQueue_HP_seqcst) \
- CPPUNIT_TEST(MSQueue_HP_ic) \
- CPPUNIT_TEST(MSQueue_HP_stat) \
- CPPUNIT_TEST(MSQueue_DHP) \
- CPPUNIT_TEST(MSQueue_DHP_michaelAlloc) \
- CPPUNIT_TEST(MSQueue_DHP_seqcst) \
- CPPUNIT_TEST(MSQueue_DHP_ic) \
- CPPUNIT_TEST(MSQueue_DHP_stat)
-
-
-// OptimisticQueue
-#define CDSUNIT_DECLARE_OptimisticQueue( ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_HP, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_HP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_HP_seqcst, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_HP_ic, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_HP_stat, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_DHP, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_DHP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_DHP_seqcst, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_DHP_ic, ITEM_TYPE ) \
- TEST_CASE(OptimisticQueue_DHP_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_OptimisticQueue \
- CPPUNIT_TEST(OptimisticQueue_HP) \
- CPPUNIT_TEST(OptimisticQueue_HP_michaelAlloc) \
- CPPUNIT_TEST(OptimisticQueue_HP_seqcst) \
- CPPUNIT_TEST(OptimisticQueue_HP_ic) \
- CPPUNIT_TEST(OptimisticQueue_HP_stat) \
- CPPUNIT_TEST(OptimisticQueue_DHP) \
- CPPUNIT_TEST(OptimisticQueue_DHP_michaelAlloc) \
- CPPUNIT_TEST(OptimisticQueue_DHP_seqcst) \
- CPPUNIT_TEST(OptimisticQueue_DHP_ic) \
- CPPUNIT_TEST(OptimisticQueue_DHP_stat)
-
-
-// BasketQueue
-#define CDSUNIT_DECLARE_BasketQueue( ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HP, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HP_seqcst, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HP_ic, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_HP_stat, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_DHP, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_DHP_michaelAlloc, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_DHP_seqcst, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_DHP_ic, ITEM_TYPE ) \
- TEST_CASE( BasketQueue_DHP_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_BasketQueue \
- CPPUNIT_TEST(BasketQueue_HP) \
- CPPUNIT_TEST(BasketQueue_HP_michaelAlloc) \
- CPPUNIT_TEST(BasketQueue_HP_seqcst) \
- CPPUNIT_TEST(BasketQueue_HP_ic) \
- CPPUNIT_TEST(BasketQueue_HP_stat) \
- CPPUNIT_TEST(BasketQueue_DHP) \
- CPPUNIT_TEST(BasketQueue_DHP_michaelAlloc) \
- CPPUNIT_TEST(BasketQueue_DHP_seqcst) \
- CPPUNIT_TEST(BasketQueue_DHP_ic) \
- CPPUNIT_TEST(BasketQueue_DHP_stat)
-
-
-// FCQueue
-#define CDSUNIT_DECLARE_FCQueue( ITEM_TYPE ) \
- TEST_CASE( FCQueue_deque, ITEM_TYPE ) \
- TEST_CASE( FCQueue_deque_elimination, ITEM_TYPE ) \
- TEST_CASE( FCQueue_deque_elimination_stat, ITEM_TYPE ) \
- TEST_CASE( FCQueue_list, ITEM_TYPE ) \
- TEST_CASE( FCQueue_list_elimination, ITEM_TYPE ) \
- TEST_CASE( FCQueue_list_elimination_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_FCQueue \
- CPPUNIT_TEST( FCQueue_deque) \
- CPPUNIT_TEST( FCQueue_deque_elimination) \
- CPPUNIT_TEST( FCQueue_deque_elimination_stat) \
- CPPUNIT_TEST( FCQueue_list) \
- CPPUNIT_TEST( FCQueue_list_elimination) \
- CPPUNIT_TEST( FCQueue_list_elimination_stat)
-
-
-// FCDeque
-#define CDSUNIT_DECLARE_FCDeque( ITEM_TYPE ) \
- TEST_CASE( FCDequeL_default, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_mutex, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_elimination, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_elimination_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_boost, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_boost_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_boost_elimination, ITEM_TYPE ) \
- TEST_CASE( FCDequeL_boost_elimination_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_default, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_mutex, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_elimination, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_elimination_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_boost, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_boost_stat, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_boost_elimination, ITEM_TYPE ) \
- TEST_CASE( FCDequeR_boost_elimination_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_FCDeque \
- CPPUNIT_TEST( FCDequeL_default ) \
- CPPUNIT_TEST( FCDequeL_mutex ) \
- CPPUNIT_TEST( FCDequeL_stat ) \
- CPPUNIT_TEST( FCDequeL_elimination ) \
- CPPUNIT_TEST( FCDequeL_elimination_stat ) \
- CPPUNIT_TEST( FCDequeL_boost ) \
- CPPUNIT_TEST( FCDequeL_boost_stat ) \
- CPPUNIT_TEST( FCDequeL_boost_elimination ) \
- CPPUNIT_TEST( FCDequeL_boost_elimination_stat ) \
- CPPUNIT_TEST( FCDequeR_default ) \
- CPPUNIT_TEST( FCDequeR_mutex ) \
- CPPUNIT_TEST( FCDequeR_stat ) \
- CPPUNIT_TEST( FCDequeR_elimination ) \
- CPPUNIT_TEST( FCDequeR_elimination_stat ) \
- CPPUNIT_TEST( FCDequeR_boost ) \
- CPPUNIT_TEST( FCDequeR_boost_stat ) \
- CPPUNIT_TEST( FCDequeR_boost_elimination ) \
- CPPUNIT_TEST( FCDequeR_boost_elimination_stat )
-
-
-// RWQueue
-#define CDSUNIT_DECLARE_RWQueue( ITEM_TYPE ) \
- TEST_CASE( RWQueue_Spin, ITEM_TYPE ) \
- TEST_CASE( RWQueue_Spin_ic, ITEM_TYPE ) \
- TEST_CASE( RWQueue_mutex, ITEM_TYPE )
-
-#define CDSUNIT_TEST_RWQueue \
- CPPUNIT_TEST(RWQueue_Spin) \
- CPPUNIT_TEST(RWQueue_Spin_ic) \
- CPPUNIT_TEST(RWQueue_mutex)
-
-// TsigasCycleQueue
-#define CDSUNIT_DECLARE_TsigasCycleQueue( ITEM_TYPE ) \
- TEST_BOUNDED(TsigasCycleQueue_dyn, ITEM_TYPE) \
- TEST_BOUNDED(TsigasCycleQueue_dyn_michaelAlloc, ITEM_TYPE) \
- TEST_BOUNDED(TsigasCycleQueue_dyn_ic, ITEM_TYPE)
-
-#define CDSUNIT_TEST_TsigasCycleQueue \
- CPPUNIT_TEST(TsigasCycleQueue_dyn) \
- CPPUNIT_TEST(TsigasCycleQueue_dyn_michaelAlloc) \
- CPPUNIT_TEST(TsigasCycleQueue_dyn_ic)
-
-
-// VyukovMPMCCycleQueue
-#define CDSUNIT_DECLARE_VyukovMPMCCycleQueue( ITEM_TYPE ) \
- TEST_BOUNDED(VyukovMPMCCycleQueue_dyn, ITEM_TYPE) \
- TEST_BOUNDED(VyukovMPMCCycleQueue_dyn_michaelAlloc, ITEM_TYPE) \
- TEST_BOUNDED(VyukovMPMCCycleQueue_dyn_ic, ITEM_TYPE) \
-
-
-#define CDSUNIT_TEST_VyukovMPMCCycleQueue \
- CPPUNIT_TEST(VyukovMPMCCycleQueue_dyn) \
- CPPUNIT_TEST(VyukovMPMCCycleQueue_dyn_michaelAlloc) \
- CPPUNIT_TEST(VyukovMPMCCycleQueue_dyn_ic) \
-
-// SegmentedQueue
-#define CDSUNIT_DECLARE_SegmentedQueue( ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_spin, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_spin_padding, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_spin_stat, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex_padding, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_HP_mutex_stat, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin_padding, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_spin_stat, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex_padding, ITEM_TYPE ) \
- TEST_SEGMENTED( SegmentedQueue_DHP_mutex_stat, ITEM_TYPE )
-
-#define CDSUNIT_TEST_SegmentedQueue \
- CPPUNIT_TEST( SegmentedQueue_HP_spin ) \
- CPPUNIT_TEST( SegmentedQueue_HP_spin_padding ) \
- CPPUNIT_TEST( SegmentedQueue_HP_spin_stat ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex_padding ) \
- CPPUNIT_TEST( SegmentedQueue_HP_mutex_stat ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin_padding ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_spin_stat ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex_padding ) \
- CPPUNIT_TEST( SegmentedQueue_DHP_mutex_stat )
-
-// std::queue
-#define CDSUNIT_DECLARE_StdQueue( ITEM_TYPE ) \
- TEST_CASE( StdQueue_deque_Spinlock, ITEM_TYPE ) \
- TEST_CASE( StdQueue_list_Spinlock, ITEM_TYPE ) \
- TEST_CASE( StdQueue_deque_BoostMutex, ITEM_TYPE ) \
- TEST_CASE( StdQueue_list_BoostMutex, ITEM_TYPE )
-
-#define CDSUNIT_TEST_StdQueue \
- CPPUNIT_TEST(StdQueue_deque_Spinlock) \
- CPPUNIT_TEST(StdQueue_list_Spinlock) \
- CPPUNIT_TEST(StdQueue_deque_BoostMutex) \
- CPPUNIT_TEST(StdQueue_list_BoostMutex)
-
-
-#endif // #ifndef CDSUNIT_QUEUE_DEFS_H
+++ /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 "queue/queue_type.h"
-#include "queue/queue_defs.h"
-
-// Multi-threaded queue test for pop operation
-namespace queue {
-
-#define TEST_CASE( Q, V ) void Q() { test< Types<V>::Q >(); }
-#define TEST_BOUNDED( Q, V ) void Q() { test_bounded< Types<V>::Q >(); }
-#define TEST_SEGMENTED( Q, V ) void Q() { test_segmented< Types<V>::Q >(); }
-
- namespace ns_Queue_Pop {
- static size_t s_nThreadCount = 8;
- static size_t s_nQueueSize = 20000000 ; // no more than 20 million records
-
- struct SimpleValue {
- size_t nNo;
-
- SimpleValue(): nNo(0) {}
- SimpleValue( size_t n ): nNo(n) {}
- size_t getNo() const { return nNo; }
- };
- }
- using namespace ns_Queue_Pop;
-
- class Queue_Pop: public CppUnitMini::TestCase
- {
- template <class Queue>
- class Thread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Thread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- long * m_arr;
- size_t m_nPopCount;
-
- public:
- Thread( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {
- m_arr = new long[s_nQueueSize];
- }
- Thread( Thread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {
- m_arr = new long[s_nQueueSize];
- }
- ~Thread()
- {
- delete [] m_arr;
- }
-
- Queue_Pop& getTest()
- {
- return reinterpret_cast<Queue_Pop&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- memset(m_arr, 0, sizeof(m_arr[0]) * s_nQueueSize );
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_fTime = m_Timer.duration();
-
- typedef typename Queue::value_type value_type;
- value_type value = value_type();
- size_t nPopCount = 0;
- while ( m_Queue.pop( value ) ) {
- ++m_arr[ value.getNo() ];
- ++nPopCount;
- }
- m_nPopCount = nPopCount;
-
- m_fTime = m_Timer.duration() - m_fTime;
- }
- };
-
- protected:
-
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue )
- {
- size_t * arr = new size_t[ s_nQueueSize ];
- memset(arr, 0, sizeof(arr[0]) * s_nQueueSize );
-
- double fTime = 0;
- size_t nTotalPops = 0;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- for ( size_t i = 0; i < s_nQueueSize; ++i )
- arr[i] += pThread->m_arr[i];
- nTotalPops += pThread->m_nPopCount;
- fTime += pThread->m_fTime;
- }
- CPPUNIT_MSG( " Duration=" << (fTime / s_nThreadCount) );
- CPPUNIT_CHECK_EX( nTotalPops == s_nQueueSize, "Total pop=" << nTotalPops << ", queue size=" << s_nQueueSize);
- CPPUNIT_CHECK( testQueue.empty() )
-
- size_t nError = 0;
- for ( size_t i = 0; i < s_nQueueSize; ++i ) {
- if ( arr[i] != 1 ) {
- CPPUNIT_MSG( " ERROR: Item " << i << " has not been popped" );
- CPPUNIT_ASSERT( ++nError <= 10 );
- }
- }
-
- delete [] arr;
- }
-
- template <class Queue>
- void test()
- {
- Queue testQueue;
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- CPPUNIT_MSG( " Create queue size =" << s_nQueueSize << " ...");
- cds::OS::Timer timer;
- for ( size_t i = 0; i < s_nQueueSize; ++i )
- testQueue.push( i );
- CPPUNIT_MSG( " Duration=" << timer.duration() );
-
- CPPUNIT_MSG( " Pop test, thread count=" << s_nThreadCount << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_bounded()
- {
- Queue testQueue( s_nQueueSize );
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- CPPUNIT_MSG( " Create queue size =" << s_nQueueSize << " ...");
- cds::OS::Timer timer;
- for ( size_t i = 0; i < s_nQueueSize; ++i )
- testQueue.push( i );
- CPPUNIT_MSG( " Duration=" << timer.duration() );
-
- CPPUNIT_MSG( " Pop test, thread count=" << s_nThreadCount << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_segmented()
- {
- for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
- CPPUNIT_MSG( "Segment size: " << nSegmentSize );
-
- Queue testQueue( nSegmentSize );
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- CPPUNIT_MSG( " Create queue size =" << s_nQueueSize << " ...");
- cds::OS::Timer timer;
- for ( size_t i = 0; i < s_nQueueSize; ++i )
- testQueue.push( i );
- CPPUNIT_MSG( " Duration=" << timer.duration() );
-
- CPPUNIT_MSG( " Pop test, thread count=" << s_nThreadCount << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
- }
-
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nThreadCount = cfg.getULong("ThreadCount", 8 );
- s_nQueueSize = cfg.getULong("QueueSize", 20000000 );
- }
-
- protected:
- CDSUNIT_DECLARE_MoirQueue( SimpleValue )
- CDSUNIT_DECLARE_MSQueue( SimpleValue )
- CDSUNIT_DECLARE_OptimisticQueue( SimpleValue )
- CDSUNIT_DECLARE_BasketQueue( SimpleValue )
- CDSUNIT_DECLARE_FCQueue( SimpleValue )
- CDSUNIT_DECLARE_FCDeque( SimpleValue )
- CDSUNIT_DECLARE_SegmentedQueue( SimpleValue )
- CDSUNIT_DECLARE_RWQueue( SimpleValue )
- CDSUNIT_DECLARE_TsigasCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_StdQueue( SimpleValue )
-
- CPPUNIT_TEST_SUITE(Queue_Pop)
- CDSUNIT_TEST_MoirQueue
- CDSUNIT_TEST_MSQueue
- CDSUNIT_TEST_OptimisticQueue
- CDSUNIT_TEST_BasketQueue
- CDSUNIT_TEST_FCQueue
- CDSUNIT_TEST_FCDeque
- CDSUNIT_TEST_SegmentedQueue
- CDSUNIT_TEST_RWQueue
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CDSUNIT_TEST_StdQueue
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::Queue_Pop);
+++ /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 "queue/queue_type.h"
-#include "queue/queue_defs.h"
-
-
-// Multi-threaded queue test for push operation
-namespace queue {
-
-#define TEST_CASE( Q, V ) void Q() { test< Types<V>::Q >(); }
-#define TEST_BOUNDED( Q, V ) void Q() { test_bounded< Types<V>::Q >(); }
-#define TEST_SEGMENTED( Q, V ) void Q() { test_segmented< Types<V>::Q >(); }
-
- namespace ns_Queue_Push {
- static size_t s_nThreadCount = 8;
- static size_t s_nQueueSize = 20000000 ; // no more than 20 million records
-
- struct SimpleValue {
- size_t nNo;
-
- SimpleValue(): nNo(0) {}
- SimpleValue( size_t n ): nNo(n) {}
- size_t getNo() const { return nNo; }
- };
- }
- using namespace ns_Queue_Push;
-
- class Queue_Push: public CppUnitMini::TestCase
- {
- template <class Queue>
- class Thread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Thread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nStartItem;
- size_t m_nEndItem;
- size_t m_nPushError;
-
- public:
- Thread( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {}
- Thread( Thread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {}
-
- Queue_Push& getTest()
- {
- return reinterpret_cast<Queue_Push&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_fTime = m_Timer.duration();
-
- m_nPushError = 0;
- for ( size_t nItem = m_nStartItem; nItem < m_nEndItem; ++nItem ) {
- if ( !m_Queue.push( nItem ))
- ++m_nPushError;
- }
-
- m_fTime = m_Timer.duration() - m_fTime;
- }
- };
-
- protected:
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue )
- {
- size_t nThreadItems = s_nQueueSize / s_nThreadCount;
- double fTime = 0;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- fTime += pThread->m_fTime;
- if ( pThread->m_nPushError != 0 )
- CPPUNIT_MSG(" ERROR: thread push error count=" << pThread->m_nPushError );
- }
- CPPUNIT_MSG( " Duration=" << (fTime / s_nThreadCount) );
- CPPUNIT_CHECK( !testQueue.empty() )
-
- size_t * arr = new size_t[ s_nQueueSize ];
- memset(arr, 0, sizeof(arr[0]) * s_nQueueSize );
-
- cds::OS::Timer timer;
- CPPUNIT_MSG( " Pop (single-threaded)..." );
- size_t nPopped = 0;
- SimpleValue val = SimpleValue();
- while ( testQueue.pop( val )) {
- nPopped++;
- ++arr[ val.getNo() ];
- }
- CPPUNIT_MSG( " Duration=" << timer.duration() );
-
- size_t nTotalItems = nThreadItems * s_nThreadCount;
- size_t nError = 0;
- for ( size_t i = 0; i < nTotalItems; ++i ) {
- if ( arr[i] != 1 ) {
- CPPUNIT_MSG( " ERROR: Item " << i << " has not been pushed" );
- CPPUNIT_ASSERT( ++nError <= 10 );
- }
- }
-
- delete [] arr;
- }
-
- template <class Queue>
- void test()
- {
- Queue testQueue;
-
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- size_t nStart = 0;
- size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- pThread->m_nStartItem = nStart;
- nStart += nThreadItemCount;
- pThread->m_nEndItem = nStart;
- }
-
- CPPUNIT_MSG( " Push test, thread count=" << s_nThreadCount << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_bounded()
- {
- size_t nStart = 0;
- size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
-
- Queue testQueue( s_nQueueSize );
-
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- pThread->m_nStartItem = nStart;
- nStart += nThreadItemCount;
- pThread->m_nEndItem = nStart;
- }
-
- CPPUNIT_MSG( " Push test, thread count=" << s_nThreadCount << " ...");
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_segmented()
- {
- CPPUNIT_MSG( " Push test, thread count=" << s_nThreadCount << " ...");
- for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
- CPPUNIT_MSG( "Segment size: " << nSegmentSize );
-
- Queue testQueue( nSegmentSize );
-
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- size_t nStart = 0;
- size_t nThreadItemCount = s_nQueueSize / s_nThreadCount;
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = reinterpret_cast<Thread<Queue> *>(*it);
- pThread->m_nStartItem = nStart;
- nStart += nThreadItemCount;
- pThread->m_nEndItem = nStart;
- }
-
- pool.run();
-
- analyze( pool, testQueue );
-
- CPPUNIT_MSG( testQueue.statistics() );
- }
- }
-
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nThreadCount = cfg.getULong("ThreadCount", 8 );
- s_nQueueSize = cfg.getULong("QueueSize", 20000000 );
- }
-
- protected:
- CDSUNIT_DECLARE_MoirQueue( SimpleValue )
- CDSUNIT_DECLARE_MSQueue( SimpleValue )
- CDSUNIT_DECLARE_OptimisticQueue( SimpleValue )
- CDSUNIT_DECLARE_BasketQueue( SimpleValue )
- CDSUNIT_DECLARE_FCQueue( SimpleValue )
- CDSUNIT_DECLARE_FCDeque( SimpleValue )
- CDSUNIT_DECLARE_SegmentedQueue( SimpleValue )
- CDSUNIT_DECLARE_RWQueue( SimpleValue )
- CDSUNIT_DECLARE_TsigasCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_StdQueue( SimpleValue )
-
- CPPUNIT_TEST_SUITE(Queue_Push)
- CDSUNIT_TEST_MoirQueue
- CDSUNIT_TEST_MSQueue
- CDSUNIT_TEST_OptimisticQueue
- CDSUNIT_TEST_BasketQueue
- CDSUNIT_TEST_FCQueue
- CDSUNIT_TEST_FCDeque
- CDSUNIT_TEST_SegmentedQueue
- CDSUNIT_TEST_RWQueue
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CDSUNIT_TEST_StdQueue
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::Queue_Push);
+++ /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 "queue/queue_type.h"
-#include "queue/queue_defs.h"
-
-
-#include <vector>
-#include <boost/type_traits/is_base_of.hpp>
-
-// Multi-threaded queue test for random push/pop operation
-namespace queue {
-
-#define TEST_CASE( Q, V ) void Q() { test< Types<V>::Q >(); }
-#define TEST_BOUNDED( Q, V ) TEST_CASE( Q, V )
-#define TEST_SEGMENTED( Q, V ) void Q() { test_segmented< Types< V >::Q >(); }
-
- namespace ns_Queue_Random {
- static size_t s_nThreadCount = 16;
- static size_t s_nQueueSize = 10000000;
-
- struct SimpleValue {
- size_t nNo;
- size_t nThread;
-
- SimpleValue() {}
- SimpleValue( size_t n ): nNo(n) {}
- size_t getNo() const { return nNo; }
- };
- }
-
- using namespace ns_Queue_Random;
-
- class Queue_Random: public CppUnitMini::TestCase
- {
- typedef CppUnitMini::TestCase base_class;
-
- template <class Queue>
- class Thread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new Thread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
-
- size_t m_nPushCount;
- size_t m_nPopCount;
- size_t m_nEmptyPop;
-
- size_t m_nUndefWriter;
- size_t m_nRepeatValue;
- size_t m_nPushError ; // push error count
-
- std::vector<size_t> m_arrLastRead;
- std::vector<size_t> m_arrPopCountPerThread;
-
- size_t const m_nSpread;
-
- public:
- Thread( CppUnitMini::ThreadPool& pool, Queue& q, size_t nSpread = 0 )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- , m_nSpread( nSpread )
- {}
- Thread( Thread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- , m_nSpread( src.m_nSpread )
- {}
-
- Queue_Random& getTest()
- {
- return reinterpret_cast<Queue_Random&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- m_nPushCount =
- m_nPopCount =
- m_nEmptyPop =
- m_nUndefWriter =
- m_nRepeatValue =
- m_nPushError = 0;
-
- m_arrLastRead.resize( s_nThreadCount, 0 );
- m_arrPopCountPerThread.resize( s_nThreadCount, 0 );
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- size_t const nThreadCount = s_nThreadCount;
- size_t const nTotalPush = getTest().m_nThreadPushCount;
-
- SimpleValue node;
-
- m_fTime = m_Timer.duration();
-
- bool bNextPop = false;
- while ( m_nPushCount < nTotalPush ) {
- if ( !bNextPop && (rand() & 3) != 3 ) {
- // push
- node.nThread = m_nThreadNo;
- node.nNo = ++m_nPushCount;
- if ( !m_Queue.push( node )) {
- ++m_nPushError;
- --m_nPushCount;
- }
-
- }
- else {
- // pop
- pop( nThreadCount );
- bNextPop = false;
- }
- }
-
- size_t nPopLoop = 0;
- while ( !m_Queue.empty() && nPopLoop < 1000000 ) {
- if ( pop( nThreadCount ) )
- nPopLoop = 0;
- else
- ++nPopLoop;
- }
-
-
- m_fTime = m_Timer.duration() - m_fTime;
- }
-
- bool pop( size_t nThreadCount )
- {
- SimpleValue node;
- node.nThread = -1;
- node.nNo = -1;
- if ( m_Queue.pop( node )) {
- ++m_nPopCount;
- if ( node.nThread < nThreadCount ) {
- m_arrPopCountPerThread[ node.nThread ] += 1;
- if ( m_nSpread ) {
- if ( m_arrLastRead[ node.nThread ] > node.nNo ) {
- if ( m_arrLastRead[ node.nThread ] - node.nNo > m_nSpread )
- ++m_nRepeatValue;
- }
- else if ( m_arrLastRead[ node.nThread ] == node.nNo )
- ++m_nRepeatValue;
- m_arrLastRead[ node.nThread ] = node.nNo;
- }
- else {
- if ( m_arrLastRead[ node.nThread ] < node.nNo ) {
- m_arrLastRead[ node.nThread ] = node.nNo;
- }
- else
- ++m_nRepeatValue;
- }
-
- //if ( node.nNo < m_Test.m_nPushCount )
- // m_Test.m_pRead[ node.nWriter ][ node.nNo ] = node.nNo;
- }
- else {
- ++m_nUndefWriter;
- }
- }
- else {
- ++m_nEmptyPop;
- return false;
- }
- return true;
- }
- };
-
- protected:
- size_t m_nThreadPushCount;
-
- protected:
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue )
- {
- CPPUNIT_CHECK( testQueue.empty() );
-
- std::vector< size_t > arrPushCount;
- arrPushCount.resize( s_nThreadCount, 0 );
-
- size_t nPushTotal = 0;
- size_t nPopTotal = 0;
- double fTime = 0;
- size_t nPushError = 0;
-
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Thread<Queue> * pThread = static_cast<Thread<Queue> *>( *it );
- CPPUNIT_CHECK( pThread->m_nUndefWriter == 0 );
- CPPUNIT_CHECK_EX( pThread->m_nRepeatValue == 0, "nRepeatValue=" << pThread->m_nRepeatValue );
- if ( !boost::is_base_of<cds::bounded_container, Queue>::value ) {
- CPPUNIT_CHECK( pThread->m_nPushError == 0 );
- }
- else
- nPushError += pThread->m_nPushError;
-
- arrPushCount[ pThread->m_nThreadNo ] += pThread->m_nPushCount;
-
- nPushTotal += pThread->m_nPushCount;
- nPopTotal += pThread->m_nPopCount;
- fTime += pThread->m_fTime;
- }
-
- CPPUNIT_MSG( " Duration=" << (fTime /= s_nThreadCount) );
- if ( boost::is_base_of<cds::bounded_container, Queue>::value ) {
- CPPUNIT_MSG( " push error (when queue is full)=" << nPushError );
- }
-
- size_t nTotalItems = m_nThreadPushCount * s_nThreadCount;
-
- CPPUNIT_CHECK_EX( nPushTotal == nTotalItems, "nPushTotal=" << nPushTotal << ", nTotalItems=" << nTotalItems );
- CPPUNIT_CHECK_EX( nPopTotal == nTotalItems, "nPopTotal=" << nPopTotal << ", nTotalItems=" << nTotalItems );
-
- for ( size_t i = 0; i < s_nThreadCount; ++i )
- CPPUNIT_CHECK( arrPushCount[i] == m_nThreadPushCount );
- }
-
- template <class Queue>
- void test()
- {
- CPPUNIT_MSG( "Random push/pop test\n thread count=" << s_nThreadCount << ", push count=" << s_nQueueSize << " ..." );
-
- m_nThreadPushCount = s_nQueueSize / s_nThreadCount;
-
- Queue testQueue;
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue ), s_nThreadCount );
-
- pool.run();
-
- analyze( pool, testQueue );
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_segmented()
- {
- CPPUNIT_MSG( "Random push/pop test\n thread count=" << s_nThreadCount << ", push count=" << s_nQueueSize << " ..." );
-
- m_nThreadPushCount = s_nQueueSize / s_nThreadCount;
-
- for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
- CPPUNIT_MSG( "Segment size: " << nSegmentSize );
-
- Queue testQueue( nSegmentSize );
- CppUnitMini::ThreadPool pool( *this );
- pool.add( new Thread<Queue>( pool, testQueue, nSegmentSize * 2 ), s_nThreadCount );
-
- pool.run();
-
- analyze( pool, testQueue );
- CPPUNIT_MSG( testQueue.statistics() );
- }
- }
-
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nThreadCount = cfg.getULong("ThreadCount", 8 );
- s_nQueueSize = cfg.getULong("QueueSize", 20000000 );
- }
-
- protected:
- CDSUNIT_DECLARE_MoirQueue( SimpleValue )
- CDSUNIT_DECLARE_MSQueue( SimpleValue )
- CDSUNIT_DECLARE_OptimisticQueue( SimpleValue )
- CDSUNIT_DECLARE_BasketQueue( SimpleValue )
- CDSUNIT_DECLARE_FCQueue( SimpleValue )
- CDSUNIT_DECLARE_FCDeque( SimpleValue )
- CDSUNIT_DECLARE_SegmentedQueue( SimpleValue )
- CDSUNIT_DECLARE_RWQueue( SimpleValue )
- CDSUNIT_DECLARE_TsigasCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue( SimpleValue )
- CDSUNIT_DECLARE_StdQueue( SimpleValue )
-
- CPPUNIT_TEST_SUITE(Queue_Random)
- CDSUNIT_TEST_MoirQueue
- CDSUNIT_TEST_MSQueue
- CDSUNIT_TEST_OptimisticQueue
- CDSUNIT_TEST_BasketQueue
- CDSUNIT_TEST_FCQueue
- CDSUNIT_TEST_FCDeque
- CDSUNIT_TEST_SegmentedQueue
- CDSUNIT_TEST_RWQueue
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CDSUNIT_TEST_StdQueue
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::Queue_Random);
+++ /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 "queue/queue_type.h"
-#include "queue/queue_defs.h"
-
-#include <vector>
-#include <algorithm>
-
-// Multi-threaded random queue test
-namespace queue {
-
-#define TEST_CASE( Q, V ) void Q() { test< Types<V>::Q >(); }
-#define TEST_BOUNDED( Q, V ) TEST_CASE( Q, V )
-#define TEST_SEGMENTED( Q, V ) void Q() { test_segmented< Types< V >::Q >(); }
-
- namespace {
- static size_t s_nReaderThreadCount = 4;
- static size_t s_nWriterThreadCount = 4;
- static size_t s_nQueueSize = 4000000;
-
- struct Value {
- size_t nNo;
- size_t nWriterNo;
- };
- }
-
- class Queue_ReaderWriter: public CppUnitMini::TestCase
- {
- template <class Queue>
- class WriterThread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new WriterThread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nPushFailed;
-
- public:
- WriterThread( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {}
- WriterThread( WriterThread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {}
-
- Queue_ReaderWriter& getTest()
- {
- return reinterpret_cast<Queue_ReaderWriter&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- size_t nPushCount = getTest().m_nThreadPushCount;
- Value v;
- v.nWriterNo = m_nThreadNo;
- v.nNo = 0;
- m_nPushFailed = 0;
-
- m_fTime = m_Timer.duration();
-
- while ( v.nNo < nPushCount ) {
- if ( m_Queue.push( v ))
- ++v.nNo;
- else
- ++m_nPushFailed;
- }
-
- m_fTime = m_Timer.duration() - m_fTime;
- getTest().m_nWriterDone.fetch_add( 1 );
- }
- };
-
- template <class Queue>
- class ReaderThread: public CppUnitMini::TestThread
- {
- virtual TestThread * clone()
- {
- return new ReaderThread( *this );
- }
- public:
- Queue& m_Queue;
- double m_fTime;
- size_t m_nPopEmpty;
- size_t m_nPopped;
- size_t m_nBadWriter;
-
- typedef std::vector<size_t> TPoppedData;
- typedef std::vector<size_t>::iterator data_iterator;
- typedef std::vector<size_t>::const_iterator const_data_iterator;
-
- std::vector<TPoppedData> m_WriterData;
-
- private:
- void initPoppedData()
- {
- const size_t nWriterCount = s_nWriterThreadCount;
- const size_t nWriterPushCount = getTest().m_nThreadPushCount;
- m_WriterData.resize( nWriterCount );
- for ( size_t i = 0; i < nWriterCount; ++i )
- m_WriterData[i].reserve( nWriterPushCount );
- }
-
- public:
- ReaderThread( CppUnitMini::ThreadPool& pool, Queue& q )
- : CppUnitMini::TestThread( pool )
- , m_Queue( q )
- {
- initPoppedData();
- }
- ReaderThread( ReaderThread& src )
- : CppUnitMini::TestThread( src )
- , m_Queue( src.m_Queue )
- {
- initPoppedData();
- }
-
- Queue_ReaderWriter& getTest()
- {
- return reinterpret_cast<Queue_ReaderWriter&>( m_Pool.m_Test );
- }
-
- virtual void init()
- {
- cds::threading::Manager::attachThread();
- }
- virtual void fini()
- {
- cds::threading::Manager::detachThread();
- }
-
- virtual void test()
- {
- m_nPopEmpty = 0;
- m_nPopped = 0;
- m_nBadWriter = 0;
- const size_t nTotalWriters = s_nWriterThreadCount;
- Value v;
-
- m_fTime = m_Timer.duration();
-
- while ( true ) {
- if ( m_Queue.pop( v ) ) {
- ++m_nPopped;
- if ( /*v.nWriterNo >= 0 &&*/ v.nWriterNo < nTotalWriters )
- m_WriterData[ v.nWriterNo ].push_back( v.nNo );
- else
- ++m_nBadWriter;
- }
- else
- ++m_nPopEmpty;
-
- if ( m_Queue.empty() ) {
- if ( getTest().m_nWriterDone.load() >= nTotalWriters ) {
- if ( m_Queue.empty() )
- break;
- }
- }
- }
-
- m_fTime = m_Timer.duration() - m_fTime;
- }
- };
-
- protected:
- size_t m_nThreadPushCount;
- atomics::atomic<size_t> m_nWriterDone;
-
- protected:
- template <class Queue>
- void analyze( CppUnitMini::ThreadPool& pool, Queue& testQueue, size_t /*nLeftOffset*/ = 0, size_t nRightOffset = 0 )
- {
- typedef ReaderThread<Queue> Reader;
- typedef WriterThread<Queue> Writer;
- typedef typename Reader::const_data_iterator ReaderIterator;
-
- size_t nPostTestPops = 0;
- {
- Value v;
- while ( testQueue.pop( v ))
- ++nPostTestPops;
- }
-
- double fTimeWriter = 0;
- double fTimeReader = 0;
- size_t nTotalPops = 0;
- size_t nPopFalse = 0;
- size_t nPoppedItems = 0;
- size_t nPushFailed = 0;
-
- std::vector< Reader * > arrReaders;
-
- for ( CppUnitMini::ThreadPool::iterator it = pool.begin(); it != pool.end(); ++it ) {
- Reader * pReader = dynamic_cast<Reader *>( *it );
- if ( pReader ) {
- fTimeReader += pReader->m_fTime;
- nTotalPops += pReader->m_nPopped;
- nPopFalse += pReader->m_nPopEmpty;
- arrReaders.push_back( pReader );
- CPPUNIT_CHECK_EX( pReader->m_nBadWriter == 0, "reader " << pReader->m_nThreadNo << " bad writer event count=" << pReader->m_nBadWriter );
-
- size_t nPopped = 0;
- for ( size_t n = 0; n < s_nWriterThreadCount; ++n )
- nPopped += pReader->m_WriterData[n].size();
-
- CPPUNIT_MSG( " Reader " << pReader->m_nThreadNo - s_nWriterThreadCount << " popped count=" << nPopped );
- nPoppedItems += nPopped;
- }
- else {
- Writer * pWriter = dynamic_cast<Writer *>( *it );
- CPPUNIT_ASSERT( pWriter != nullptr );
- fTimeWriter += pWriter->m_fTime;
- nPushFailed += pWriter->m_nPushFailed;
- if ( !boost::is_base_of<cds::bounded_container, Queue>::value ) {
- CPPUNIT_CHECK_EX( pWriter->m_nPushFailed == 0,
- "writer " << pWriter->m_nThreadNo << " push failed count=" << pWriter->m_nPushFailed );
- }
- }
- }
- CPPUNIT_CHECK_EX( nTotalPops == nPoppedItems, "nTotalPops=" << nTotalPops << ", nPoppedItems=" << nPoppedItems );
-
- CPPUNIT_MSG( " Readers: duration=" << fTimeReader / s_nReaderThreadCount << ", success pop=" << nTotalPops << ", failed pops=" << nPopFalse );
- CPPUNIT_MSG( " Writers: duration=" << fTimeWriter / s_nWriterThreadCount << ", failed push=" << nPushFailed );
-
- size_t nQueueSize = m_nThreadPushCount * s_nWriterThreadCount;
- CPPUNIT_CHECK_EX( nTotalPops + nPostTestPops == nQueueSize, "popped=" << nTotalPops + nPostTestPops << " must be " << nQueueSize );
- CPPUNIT_CHECK( testQueue.empty() );
-
- // Test that all items have been popped
- CPPUNIT_MSG( " Test consistency of popped sequence..." );
- for ( size_t nWriter = 0; nWriter < s_nWriterThreadCount; ++nWriter ) {
- std::vector<size_t> arrData;
- arrData.reserve( m_nThreadPushCount );
- size_t nErrors = 0;
- for ( size_t nReader = 0; nReader < arrReaders.size(); ++nReader ) {
- ReaderIterator it = arrReaders[nReader]->m_WriterData[nWriter].begin();
- ReaderIterator itEnd = arrReaders[nReader]->m_WriterData[nWriter].end();
- if ( it != itEnd ) {
- ReaderIterator itPrev = it;
- for ( ++it; it != itEnd; ++it ) {
- CPPUNIT_CHECK_EX( *itPrev < *it + nRightOffset, "Reader " << nReader << ", Writer " << nWriter << ": prev=" << *itPrev << ", cur=" << *it );
- if ( ++nErrors > 10 )
- return;
- itPrev = it;
- }
- }
-
- for ( it = arrReaders[nReader]->m_WriterData[nWriter].begin(); it != itEnd; ++it )
- arrData.push_back( *it );
- }
-
- std::sort( arrData.begin(), arrData.end() );
- nErrors = 0;
- for ( size_t i=1; i < arrData.size(); ++i ) {
- if ( arrData[i-1] + 1 != arrData[i] ) {
- CPPUNIT_CHECK_EX( arrData[i-1] + 1 == arrData[i], "Writer " << nWriter << ": [" << (i-1) << "]=" << arrData[i-1] << ", [" << i << "]=" << arrData[i] );
- if ( ++nErrors > 10 )
- return;
- }
- }
-
- CPPUNIT_CHECK_EX( arrData[0] == 0, "Writer " << nWriter << "[0] != 0" );
- CPPUNIT_CHECK_EX( arrData[arrData.size() - 1] == m_nThreadPushCount - 1, "Writer " << nWriter << "[last] != " << m_nThreadPushCount - 1 );
- }
- }
-
- template <class Queue>
- void test()
- {
- m_nThreadPushCount = s_nQueueSize / s_nWriterThreadCount;
- CPPUNIT_MSG( " reader count=" << s_nReaderThreadCount << " writer count=" << s_nWriterThreadCount
- << " item count=" << m_nThreadPushCount * s_nWriterThreadCount << "..." );
-
- Queue testQueue;
- CppUnitMini::ThreadPool pool( *this );
-
- m_nWriterDone.store( 0 );
-
- // Writers must be first
- pool.add( new WriterThread<Queue>( pool, testQueue ), s_nWriterThreadCount );
- pool.add( new ReaderThread<Queue>( pool, testQueue ), s_nReaderThreadCount );
-
- //CPPUNIT_MSG( " Reader/Writer test, reader count=" << s_nReaderThreadCount << " writer count=" << s_nWriterThreadCount << "..." );
- pool.run();
-
- analyze( pool, testQueue );
- CPPUNIT_MSG( testQueue.statistics() );
- }
-
- template <class Queue>
- void test_segmented()
- {
- m_nThreadPushCount = s_nQueueSize / s_nWriterThreadCount;
- CPPUNIT_MSG( " reader count=" << s_nReaderThreadCount << " writer count=" << s_nWriterThreadCount
- << " item count=" << m_nThreadPushCount * s_nWriterThreadCount << "..." );
-
- for ( size_t nSegmentSize = 4; nSegmentSize <= 256; nSegmentSize *= 4 ) {
- CPPUNIT_MSG( "Segment size: " << nSegmentSize );
-
- Queue q( nSegmentSize );
- CppUnitMini::ThreadPool pool( *this );
-
- m_nWriterDone.store( 0 );
-
- // Writers must be first
- pool.add( new WriterThread<Queue>( pool, q ), s_nWriterThreadCount );
- pool.add( new ReaderThread<Queue>( pool, q ), s_nReaderThreadCount );
-
- pool.run();
-
- analyze( pool, q, nSegmentSize * 2, nSegmentSize );
- CPPUNIT_MSG( q.statistics() );
- }
- }
-
- void setUpParams( const CppUnitMini::TestCfg& cfg ) {
- s_nReaderThreadCount = cfg.getULong("ReaderCount", 4 );
- s_nWriterThreadCount = cfg.getULong("WriterCount", 4 );
- s_nQueueSize = cfg.getULong("QueueSize", 10000000 );
- }
-
- protected:
- CDSUNIT_DECLARE_MoirQueue( Value )
- CDSUNIT_DECLARE_MSQueue( Value )
- CDSUNIT_DECLARE_OptimisticQueue( Value )
- CDSUNIT_DECLARE_BasketQueue( Value )
- CDSUNIT_DECLARE_FCQueue( Value )
- CDSUNIT_DECLARE_FCDeque( Value )
- CDSUNIT_DECLARE_SegmentedQueue( Value )
- CDSUNIT_DECLARE_RWQueue( Value )
- CDSUNIT_DECLARE_TsigasCycleQueue( Value )
- CDSUNIT_DECLARE_VyukovMPMCCycleQueue( Value )
- CDSUNIT_DECLARE_StdQueue( Value )
-
- CPPUNIT_TEST_SUITE(Queue_ReaderWriter)
- CDSUNIT_TEST_MoirQueue
- CDSUNIT_TEST_MSQueue
- CDSUNIT_TEST_OptimisticQueue
- CDSUNIT_TEST_BasketQueue
- CDSUNIT_TEST_FCQueue
- CDSUNIT_TEST_FCDeque
- CDSUNIT_TEST_SegmentedQueue
- CDSUNIT_TEST_RWQueue
- CDSUNIT_TEST_TsigasCycleQueue
- CDSUNIT_TEST_VyukovMPMCCycleQueue
- CDSUNIT_TEST_StdQueue
- CPPUNIT_TEST_SUITE_END();
- };
-
-} // namespace queue
-
-CPPUNIT_TEST_SUITE_REGISTRATION(queue::Queue_ReaderWriter);
+++ /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 CDSUNIT_QUEUE_TYPES_H
-#define CDSUNIT_QUEUE_TYPES_H
-
-#include <cds/container/msqueue.h>
-#include <cds/container/moir_queue.h>
-#include <cds/container/rwqueue.h>
-#include <cds/container/optimistic_queue.h>
-#include <cds/container/tsigas_cycle_queue.h>
-#include <cds/container/vyukov_mpmc_cycle_queue.h>
-#include <cds/container/basket_queue.h>
-#include <cds/container/fcqueue.h>
-#include <cds/container/fcdeque.h>
-#include <cds/container/segmented_queue.h>
-
-#include <cds/gc/hp.h>
-#include <cds/gc/dhp.h>
-
-#include "queue/std_queue.h"
-#include "lock/win32_lock.h"
-#include "michael_alloc.h"
-#include "print_segmentedqueue_stat.h"
-
-#include <boost/container/deque.hpp>
-
-namespace queue {
- namespace details {
- template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque=std::deque<T> >
- class FCDequeL: public cds::container::FCDeque<T, Deque, Traits >
- {
- typedef cds::container::FCDeque<T, Deque, Traits > base_class;
- public:
- FCDequeL()
- {}
-
- FCDequeL(
- unsigned int nCompactFactor ///< Flat combining: publication list compacting factor
- ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
- )
- : base_class( nCompactFactor, nCombinePassCount )
- {}
-
- bool push( T const& v )
- {
- return base_class::push_front( v );
- }
- bool enqueue( T const& v )
- {
- return push( v );
- }
-
- bool pop( T& v )
- {
- return base_class::pop_back( v );
- }
- bool deque( T& v )
- {
- return pop(v);
- }
- };
-
- template <typename T, typename Traits=cds::container::fcdeque::traits, class Deque = std::deque<T> >
- class FCDequeR: public cds::container::FCDeque<T, Deque, Traits >
- {
- typedef cds::container::FCDeque<T, Deque, Traits > base_class;
- public:
- FCDequeR()
- {}
-
- FCDequeR(
- unsigned int nCompactFactor ///< Flat combining: publication list compacting factor
- ,unsigned int nCombinePassCount ///< Flat combining: number of combining passes for combiner thread
- )
- : base_class( nCompactFactor, nCombinePassCount )
- {}
-
- bool push( T const& v )
- {
- return base_class::push_back( v );
- }
- bool enqueue( T const& v )
- {
- return push( v );
- }
-
- bool pop( T& v )
- {
- return base_class::pop_front( v );
- }
- bool deque( T& v )
- {
- return pop(v);
- }
- };
-
- } // namespace details
-
- template <typename Value>
- struct Types {
-
- // MSQueue
- typedef cds::container::MSQueue<cds::gc::HP, Value > MSQueue_HP;
- typedef cds::container::MSQueue<cds::gc::DHP, Value > MSQueue_DHP;
- typedef cds::container::MoirQueue<cds::gc::HP, Value > MoirQueue_HP;
- typedef cds::container::MoirQueue<cds::gc::DHP, Value > MoirQueue_DHP;
-
- struct traits_MSQueue_michaelAlloc : public cds::container::msqueue::traits
- {
- typedef memory::MichaelAllocator<int> allocator;
- };
- typedef cds::container::MSQueue<cds::gc::HP, Value, traits_MSQueue_michaelAlloc > MSQueue_HP_michaelAlloc;
- typedef cds::container::MSQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MSQueue_DHP_michaelAlloc;
- typedef cds::container::MoirQueue<cds::gc::HP, Value, traits_MSQueue_michaelAlloc > MoirQueue_HP_michaelAlloc;
- typedef cds::container::MoirQueue<cds::gc::DHP, Value, traits_MSQueue_michaelAlloc > MoirQueue_DHP_michaelAlloc;
-
- struct traits_MSQueue_seqcst : public
- cds::container::msqueue::make_traits <
- cds::opt::memory_model < cds::opt::v::sequential_consistent >
- > ::type
- {};
- typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_seqcst > MSQueue_HP_seqcst;
- typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MSQueue_DHP_seqcst;
- typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_seqcst > MoirQueue_HP_seqcst;
- typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_seqcst > MoirQueue_DHP_seqcst;
-
- // MSQueue + item counter
- struct traits_MSQueue_ic : public
- cds::container::msqueue::make_traits <
- cds::opt::item_counter < cds::atomicity::item_counter >
- >::type
- {};
- typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_ic > MSQueue_HP_ic;
- typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MSQueue_DHP_ic;
- typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_ic > MoirQueue_HP_ic;
- typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_ic > MoirQueue_DHP_ic;
-
- // MSQueue + stat
- struct traits_MSQueue_stat: public
- cds::container::msqueue::make_traits <
- cds::opt::stat< cds::container::msqueue::stat<> >
- >::type
- {};
- typedef cds::container::MSQueue< cds::gc::HP, Value, traits_MSQueue_stat > MSQueue_HP_stat;
- typedef cds::container::MSQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MSQueue_DHP_stat;
- typedef cds::container::MoirQueue< cds::gc::HP, Value, traits_MSQueue_stat > MoirQueue_HP_stat;
- typedef cds::container::MoirQueue< cds::gc::DHP, Value, traits_MSQueue_stat > MoirQueue_DHP_stat;
-
-
- // OptimisticQueue
- typedef cds::container::OptimisticQueue< cds::gc::HP, Value > OptimisticQueue_HP;
- typedef cds::container::OptimisticQueue< cds::gc::DHP, Value > OptimisticQueue_DHP;
-
- struct traits_OptimisticQueue_michaelAlloc : public cds::container::optimistic_queue::traits
- {
- typedef memory::MichaelAllocator<int> allocator;
- };
- typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_HP_michaelAlloc;
- typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_michaelAlloc > OptimisticQueue_DHP_michaelAlloc;
-
- struct traits_OptimisticQueue_seqcst : public cds::container::optimistic_queue::traits
- {
- typedef cds::opt::v::sequential_consistent memory_model;
- };
- typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_seqcst > OptimisticQueue_HP_seqcst;
- typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_seqcst > OptimisticQueue_DHP_seqcst;
-
- struct traits_OptimisticQueue_ic : public cds::container::optimistic_queue::traits
- {
- typedef cds::atomicity::item_counter item_counter;
- };
- typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_ic > OptimisticQueue_HP_ic;
- typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_ic > OptimisticQueue_DHP_ic;
-
- struct traits_OptimisticQueue_stat : public
- cds::container::optimistic_queue::make_traits <
- cds::opt::stat < cds::intrusive::optimistic_queue::stat<> >
- > ::type
- {};
- typedef cds::container::OptimisticQueue< cds::gc::HP, Value, traits_OptimisticQueue_stat > OptimisticQueue_HP_stat;
- typedef cds::container::OptimisticQueue< cds::gc::DHP, Value, traits_OptimisticQueue_stat > OptimisticQueue_DHP_stat;
-
-
- // TsigasCycleQueue
-
- class TsigasCycleQueue_dyn
- : public cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- >::type
- >
- {
- typedef cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- >::type
- > base_class;
- public:
- TsigasCycleQueue_dyn()
- : base_class( 1024 * 64 )
- {}
-
- TsigasCycleQueue_dyn( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- class TsigasCycleQueue_dyn_michaelAlloc
- : public cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- ,cds::opt::allocator< memory::MichaelAllocator<int> >
- >::type
- >
- {
- typedef cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- , cds::opt::allocator< memory::MichaelAllocator<int> >
- >::type
- > base_class;
- public:
- TsigasCycleQueue_dyn_michaelAlloc()
- : base_class( 1024 * 64 )
- {}
-
- TsigasCycleQueue_dyn_michaelAlloc( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- class TsigasCycleQueue_dyn_ic
- : public cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- >
- {
- typedef cds::container::TsigasCycleQueue< Value,
- typename cds::container::tsigas_queue::make_traits<
- cds::opt::buffer< cds::opt::v::dynamic_buffer< int > >
- ,cds::opt::item_counter< cds::atomicity::item_counter >
- >::type
- > base_class;
- public:
- TsigasCycleQueue_dyn_ic()
- : base_class( 1024 * 64 )
- {}
- TsigasCycleQueue_dyn_ic( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- // VyukovMPMCCycleQueue
- struct traits_VyukovMPMCCycleQueue_dyn : public cds::container::vyukov_queue::traits
- {
- typedef cds::opt::v::dynamic_buffer< int > buffer;
- };
- class VyukovMPMCCycleQueue_dyn
- : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn >
- {
- typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn > base_class;
- public:
- VyukovMPMCCycleQueue_dyn()
- : base_class( 1024 * 64 )
- {}
- VyukovMPMCCycleQueue_dyn( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- struct traits_VyukovMPMCCycleQueue_dyn_michaelAlloc : public cds::container::vyukov_queue::traits
- {
- typedef cds::opt::v::dynamic_buffer< int, memory::MichaelAllocator<int> > buffer;
- };
- class VyukovMPMCCycleQueue_dyn_michaelAlloc
- : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc >
- {
- typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_michaelAlloc > base_class;
- public:
- VyukovMPMCCycleQueue_dyn_michaelAlloc()
- : base_class( 1024 * 64 )
- {}
- VyukovMPMCCycleQueue_dyn_michaelAlloc( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- struct traits_VyukovMPMCCycleQueue_dyn_ic : public traits_VyukovMPMCCycleQueue_dyn
- {
- typedef cds::atomicity::item_counter item_counter;
- };
- class VyukovMPMCCycleQueue_dyn_ic
- : public cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic >
- {
- typedef cds::container::VyukovMPMCCycleQueue< Value, traits_VyukovMPMCCycleQueue_dyn_ic > base_class;
- public:
- VyukovMPMCCycleQueue_dyn_ic()
- : base_class( 1024 * 64 )
- {}
- VyukovMPMCCycleQueue_dyn_ic( size_t nCapacity )
- : base_class( nCapacity )
- {}
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
-
- // BasketQueue
-
- typedef cds::container::BasketQueue< cds::gc::HP , Value > BasketQueue_HP;
- typedef cds::container::BasketQueue< cds::gc::DHP, Value > BasketQueue_DHP;
-
- struct traits_BasketQueue_michaelAlloc : public cds::container::basket_queue::traits
- {
- typedef memory::MichaelAllocator<int> allocator;
- };
- typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_HP_michaelAlloc;
- typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_michaelAlloc > BasketQueue_DHP_michaelAlloc;
-
- struct traits_BasketQueue_seqcst : public cds::container::basket_queue::traits
- {
- typedef cds::opt::v::sequential_consistent mamory_model;
- };
- typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_seqcst > BasketQueue_HP_seqcst;
- typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_seqcst > BasketQueue_DHP_seqcst;
-
- struct traits_BasketQueue_ic : public cds::container::basket_queue::traits
- {
- typedef cds::atomicity::item_counter item_counter;
- };
- typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_ic >BasketQueue_HP_ic;
- typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_ic >BasketQueue_DHP_ic;
-
- struct traits_BasketQueue_stat : public cds::container::basket_queue::traits
- {
- typedef cds::container::basket_queue::stat<> stat;
- };
- typedef cds::container::BasketQueue< cds::gc::HP, Value, traits_BasketQueue_stat > BasketQueue_HP_stat;
- typedef cds::container::BasketQueue< cds::gc::DHP, Value, traits_BasketQueue_stat > BasketQueue_DHP_stat;
-
-
- // RWQueue
- typedef cds::container::RWQueue< Value > RWQueue_Spin;
-
- struct traits_RWQueue_Spin_ic : public cds::container::rwqueue::traits
- {
- typedef cds::atomicity::item_counter item_counter;
- };
- typedef cds::container::RWQueue< Value, traits_RWQueue_Spin_ic > RWQueue_Spin_ic;
-
- struct traits_RWQueue_mutex : public
- cds::container::rwqueue::make_traits<
- cds::opt::lock_type< std::mutex >
- >::type
- {};
- typedef cds::container::RWQueue< Value, traits_RWQueue_mutex > RWQueue_mutex;
-
- // FCQueue
- class traits_FCQueue_elimination:
- public cds::container::fcqueue::make_traits<
- cds::opt::enable_elimination< true >
- >::type
- {};
- class traits_FCQueue_elimination_stat:
- public cds::container::fcqueue::make_traits<
- cds::opt::enable_elimination< true >
- ,cds::opt::stat< cds::container::fcqueue::stat<> >
- >::type
- {};
-
- typedef cds::container::FCQueue< Value > FCQueue_deque;
- typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination > FCQueue_deque_elimination;
- typedef cds::container::FCQueue< Value, std::queue<Value>, traits_FCQueue_elimination_stat > FCQueue_deque_elimination_stat;
-
- typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> > > FCQueue_list;
- typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination > FCQueue_list_elimination;
- typedef cds::container::FCQueue< Value, std::queue<Value, std::list<Value> >, traits_FCQueue_elimination_stat > FCQueue_list_elimination_stat;
-
-
- // FCDeque
- struct traits_FCDeque_stat:
- public cds::container::fcdeque::make_traits<
- cds::opt::stat< cds::container::fcdeque::stat<> >
- >::type
- {};
- struct traits_FCDeque_elimination:
- public cds::container::fcdeque::make_traits<
- cds::opt::enable_elimination< true >
- >::type
- {};
- struct traits_FCDeque_elimination_stat:
- public cds::container::fcdeque::make_traits<
- cds::opt::stat< cds::container::fcdeque::stat<> >,
- cds::opt::enable_elimination< true >
- >::type
- {};
- struct traits_FCDeque_mutex:
- public cds::container::fcdeque::make_traits<
- cds::opt::lock_type< std::mutex >
- >::type
- {};
-
- typedef details::FCDequeL< Value > FCDequeL_default;
- typedef details::FCDequeL< Value, traits_FCDeque_mutex > FCDequeL_mutex;
- typedef details::FCDequeL< Value, traits_FCDeque_stat > FCDequeL_stat;
- typedef details::FCDequeL< Value, traits_FCDeque_elimination > FCDequeL_elimination;
- typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat > FCDequeL_elimination_stat;
-
- typedef details::FCDequeL< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeL_boost;
- typedef details::FCDequeL< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeL_boost_stat;
- typedef details::FCDequeL< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeL_boost_elimination;
- typedef details::FCDequeL< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeL_boost_elimination_stat;
-
- typedef details::FCDequeR< Value > FCDequeR_default;
- typedef details::FCDequeR< Value, traits_FCDeque_mutex > FCDequeR_mutex;
- typedef details::FCDequeR< Value, traits_FCDeque_stat > FCDequeR_stat;
- typedef details::FCDequeR< Value, traits_FCDeque_elimination > FCDequeR_elimination;
- typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat > FCDequeR_elimination_stat;
-
- typedef details::FCDequeR< Value, cds::container::fcdeque::traits, boost::container::deque<Value> > FCDequeR_boost;
- typedef details::FCDequeR< Value, traits_FCDeque_stat, boost::container::deque<Value> > FCDequeR_boost_stat;
- typedef details::FCDequeR< Value, traits_FCDeque_elimination, boost::container::deque<Value> > FCDequeR_boost_elimination;
- typedef details::FCDequeR< Value, traits_FCDeque_elimination_stat, boost::container::deque<Value> > FCDequeR_boost_elimination_stat;
-
- typedef StdQueue_deque<Value> StdQueue_deque_Spinlock;
- typedef StdQueue_list<Value> StdQueue_list_Spinlock;
- typedef StdQueue_deque<Value, std::mutex> StdQueue_deque_BoostMutex;
- typedef StdQueue_list<Value, std::mutex> StdQueue_list_BoostMutex;
-#ifdef UNIT_LOCK_WIN_CS
- typedef StdQueue_deque<Value, lock::win::CS> StdQueue_deque_WinCS;
- typedef StdQueue_list<Value, lock::win::CS> StdQueue_list_WinCS;
- typedef StdQueue_deque<Value, lock::win::Mutex> StdQueue_deque_WinMutex;
- typedef StdQueue_list<Value, lock::win::Mutex> StdQueue_list_WinMutex;
-#endif
-
- // SegmentedQueue
- class traits_SegmentedQueue_spin_stat:
- public cds::container::segmented_queue::make_traits<
- cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
- >::type
- {};
- class traits_SegmentedQueue_spin_padding:
- public cds::container::segmented_queue::make_traits<
- cds::opt::padding< cds::opt::cache_line_padding >
- >::type
- {};
- class traits_SegmentedQueue_mutex_stat:
- public cds::container::segmented_queue::make_traits<
- cds::opt::stat< cds::intrusive::segmented_queue::stat<> >
- ,cds::opt::lock_type< std::mutex >
- >::type
- {};
- class traits_SegmentedQueue_mutex:
- public cds::container::segmented_queue::make_traits<
- cds::opt::lock_type< std::mutex >
- >::type
- {};
- class traits_SegmentedQueue_mutex_padding:
- public cds::container::segmented_queue::make_traits<
- cds::opt::lock_type< std::mutex >
- , cds::opt::padding< cds::opt::cache_line_padding >
- >::type
- {};
-
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value > SegmentedQueue_HP_spin;
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_padding > SegmentedQueue_HP_spin_padding;
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_spin_stat > SegmentedQueue_HP_spin_stat;
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex > SegmentedQueue_HP_mutex;
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_padding > SegmentedQueue_HP_mutex_padding;
- typedef cds::container::SegmentedQueue< cds::gc::HP, Value, traits_SegmentedQueue_mutex_stat > SegmentedQueue_HP_mutex_stat;
-
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value > SegmentedQueue_DHP_spin;
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_padding > SegmentedQueue_DHP_spin_padding;
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_spin_stat > SegmentedQueue_DHP_spin_stat;
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex > SegmentedQueue_DHP_mutex;
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_padding > SegmentedQueue_DHP_mutex_padding;
- typedef cds::container::SegmentedQueue< cds::gc::DHP, Value, traits_SegmentedQueue_mutex_stat > SegmentedQueue_DHP_mutex_stat;
- };
-}
-
-
-// *********************************************
-// Queue statistics
-namespace std {
-
- template <typename Counter>
- static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::stat<Counter> const& s)
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
- << "\t\tAdd basket attempts: " << s.m_TryAddBasket.get() << "\n"
- << "\t\t Add basket success: " << s.m_AddBasketCount.get() << "\n";
- }
- static inline std::ostream& operator <<(std::ostream& o, cds::container::basket_queue::empty_stat const& /*s*/)
- {
- return o;
- }
-
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::container::msqueue::stat<Counter> const& s )
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\tAdvance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::container::msqueue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::opt::none )
- {
- return o;
- }
-
- // cds::intrusive::optimistic_queue::stat
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::optimistic_queue::stat<Counter> const& s )
- {
- return o
- << "\tStatistics:\n"
- << "\t\t Enqueue count: " << s.m_EnqueueCount.get() << "\n"
- << "\t\t Enqueue race: " << s.m_EnqueueRace.get() << "\n"
- << "\t\t Dequeue count: " << s.m_DequeueCount.get() << "\n"
- << "\t\t Dequeue empty: " << s.m_EmptyDequeue.get() << "\n"
- << "\t\t Dequeue race: " << s.m_DequeueRace.get() << "\n"
- << "\t\t Advance tail error: " << s.m_AdvanceTailError.get() << "\n"
- << "\t\t Bad tail: " << s.m_BadTail.get() << "\n"
- << "\t\t fix list call: " << s.m_FixListCount.get() << "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::intrusive::optimistic_queue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- // cds::container::fcqueue::stat
- template <typename Counter>
- static inline std::ostream& operator <<( std::ostream& o, cds::container::fcqueue::stat<Counter> const& s )
- {
- return o << "\tStatistics:\n"
- << "\t Push: " << s.m_nEnqueue.get() << "\n"
- << "\t PushMove: " << s.m_nEnqMove.get() << "\n"
- << "\t Pop: " << s.m_nDequeue.get() << "\n"
- << "\t FailedPop: " << s.m_nFailedDeq.get() << "\n"
- << "\t Collided push/pop pair: " << s.m_nCollided.get() << "\n"
- << "\tFlat combining statistics:\n"
- << "\t Combining factor: " << s.combining_factor() << "\n"
- << "\t Operation count: " << s.m_nOperationCount.get() << "\n"
- << "\t Combine call count: " << s.m_nCombiningCount.get() << "\n"
- << "\t Compact pub-list: " << s.m_nCompactPublicationList.get() << "\n"
- << "\t Deactivate pub-record: " << s.m_nDeactivatePubRecord.get() << "\n"
- << "\t Activate pub-record: " << s.m_nActivatePubRecord.get() << "\n"
- << "\t Create pub-record: " << s.m_nPubRecordCreated.get() << "\n"
- << "\t Delete pub-record: " << s.m_nPubRecordDeteted.get() << "\n"
- << "\t Acquire pub-record: " << s.m_nAcquirePubRecCount.get()<< "\n"
- << "\t Release pub-record: " << s.m_nReleasePubRecCount.get()<< "\n";
- }
-
- static inline std::ostream& operator <<( std::ostream& o, cds::container::fcqueue::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- static inline std::ostream& operator <<( std::ostream& o, std::nullptr_t /*s*/ )
- {
- return o;
- }
-
- static inline ostream& operator <<( ostream& o, cds::container::fcdeque::empty_stat const& /*s*/ )
- {
- return o;
- }
-
- static inline ostream& operator <<( ostream& o, cds::container::fcdeque::stat<> const& s )
- {
- return o << "\tStatistics:\n"
- << "\t Push front: " << s.m_nPushFront.get() << "\n"
- << "\t Push front move: " << s.m_nPushFrontMove.get() << "\n"
- << "\t Push back: " << s.m_nPushBack.get() << "\n"
- << "\t Push back move: " << s.m_nPushBackMove.get() << "\n"
- << "\t Pop front: " << s.m_nPopFront.get() << "\n"
- << "\t Failed pop front: " << s.m_nFailedPopFront.get() << "\n"
- << "\t Pop back: " << s.m_nPopBack.get() << "\n"
- << "\t Failed pop back: " << s.m_nFailedPopBack.get() << "\n"
- << "\t Collided push/pop pair: " << s.m_nCollided.get() << "\n"
- << "\tFlat combining statistics:\n"
- << "\t Combining factor: " << s.combining_factor() << "\n"
- << "\t Operation count: " << s.m_nOperationCount.get() << "\n"
- << "\t Combine call count: " << s.m_nCombiningCount.get() << "\n"
- << "\t Compact pub-list: " << s.m_nCompactPublicationList.get() << "\n"
- << "\t Deactivate pub-record: " << s.m_nDeactivatePubRecord.get() << "\n"
- << "\t Activate pub-record: " << s.m_nActivatePubRecord.get() << "\n"
- << "\t Create pub-record: " << s.m_nPubRecordCreated.get() << "\n"
- << "\t Delete pub-record: " << s.m_nPubRecordDeteted.get() << "\n"
- << "\t Acquire pub-record: " << s.m_nAcquirePubRecCount.get()<< "\n"
- << "\t Release pub-record: " << s.m_nReleasePubRecCount.get()<< "\n";
- }
-
-}
-
-#endif // #ifndef CDSUNIT_QUEUE_TYPES_H
+++ /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 CDSUNIT_QUEUE_STD_QUEUE_H
-#define CDSUNIT_QUEUE_STD_QUEUE_H
-
-#include <mutex> //unique_lock
-#include <queue>
-#include <cds/sync/spinlock.h>
-
-namespace queue {
-
- template <typename T, class Container, class Lock = cds::sync::spin >
- class StdQueue: public std::queue<T, Container >
- {
- typedef std::queue<T, Container > base_class;
- Lock m_Locker;
-
- public:
- bool enqueue( const T& data )
- {
- std::unique_lock<Lock> a(m_Locker);
-
- base_class::push( data );
- return true;
- }
- bool push( const T& data ) { return enqueue( data ) ; }
- bool dequeue( T& data )
- {
- std::unique_lock<Lock> a(m_Locker);
- if ( base_class::empty() )
- return false;
-
- data = base_class::front();
- base_class::pop();
- return true;
- }
- bool pop( T& data ) { return dequeue( data ) ; }
-
- cds::opt::none statistics() const
- {
- return cds::opt::none();
- }
- };
-
- template <typename T, class Lock = cds::sync::spin >
- class StdQueue_deque: public StdQueue<T, std::deque<T>, Lock >
- {};
-
- template <typename T, class Lock = cds::sync::spin >
- class StdQueue_list: public StdQueue<T, std::list<T>, Lock >
- {};
-}
-
-#endif // #ifndef CDSUNIT_QUEUE_STD_QUEUE_H