merge from dev-win
This commit is contained in:
commit
f844665c9f
@ -173,15 +173,21 @@ install(FILES $<TARGET_OBJECTS:mimalloc-obj>
|
|||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# API surface testing
|
# API surface testing
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
add_executable(mimalloc-test test/test-api.c)
|
add_executable(mimalloc-test-api test/test-api.c)
|
||||||
target_compile_definitions(mimalloc-test PRIVATE ${mi_defines})
|
target_compile_definitions(mimalloc-test-api PRIVATE ${mi_defines})
|
||||||
target_compile_options(mimalloc-test PRIVATE ${mi_cflags})
|
target_compile_options(mimalloc-test-api PRIVATE ${mi_cflags})
|
||||||
target_include_directories(mimalloc-test PRIVATE include)
|
target_include_directories(mimalloc-test-api PRIVATE include)
|
||||||
target_link_libraries(mimalloc-test PRIVATE mimalloc-static)
|
target_link_libraries(mimalloc-test-api PRIVATE mimalloc-static)
|
||||||
|
|
||||||
|
add_executable(mimalloc-test-stress test/test-stress.c)
|
||||||
|
target_compile_definitions(mimalloc-test-stress PRIVATE ${mi_defines})
|
||||||
|
target_compile_options(mimalloc-test-stress PRIVATE ${mi_cflags})
|
||||||
|
target_include_directories(mimalloc-test-stress PRIVATE include)
|
||||||
|
target_link_libraries(mimalloc-test-stress PRIVATE mimalloc-static)
|
||||||
|
|
||||||
enable_testing()
|
enable_testing()
|
||||||
add_test(test_api, mimalloc-test)
|
add_test(test_api, mimalloc-test-api)
|
||||||
|
add_test(test_stress, mimalloc-test-stress)
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Set override properties
|
# Set override properties
|
||||||
@ -192,6 +198,5 @@ if (MI_OVERRIDE MATCHES "ON")
|
|||||||
# It is only possible to override malloc on Windows when building as a DLL. (src/alloc-override.c)
|
# It is only possible to override malloc on Windows when building as a DLL. (src/alloc-override.c)
|
||||||
target_compile_definitions(mimalloc-static PRIVATE MI_MALLOC_OVERRIDE)
|
target_compile_definitions(mimalloc-static PRIVATE MI_MALLOC_OVERRIDE)
|
||||||
target_compile_definitions(mimalloc-obj PRIVATE MI_MALLOC_OVERRIDE)
|
target_compile_definitions(mimalloc-obj PRIVATE MI_MALLOC_OVERRIDE)
|
||||||
target_compile_definitions(mimalloc-test PRIVATE MI_MALLOC_OVERRIDE)
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -23,19 +23,50 @@ jobs:
|
|||||||
solution: build/libmimalloc.sln
|
solution: build/libmimalloc.sln
|
||||||
- upload: $(Build.SourcesDirectory)/build
|
- upload: $(Build.SourcesDirectory)/build
|
||||||
artifact: windows
|
artifact: windows
|
||||||
|
|
||||||
- job:
|
- job:
|
||||||
displayName: Linux
|
displayName: Linux
|
||||||
pool:
|
pool:
|
||||||
vmImage:
|
vmImage:
|
||||||
ubuntu-16.04
|
ubuntu-16.04
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
Debug:
|
||||||
|
CC: gcc
|
||||||
|
CXX: g++
|
||||||
|
BuildType: debug
|
||||||
|
cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_CHECK_FULL=ON
|
||||||
|
Release:
|
||||||
|
CC: gcc
|
||||||
|
CXX: g++
|
||||||
|
BuildType: release
|
||||||
|
cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release
|
||||||
|
Debug Clang:
|
||||||
|
CC: clang
|
||||||
|
CXX: clang++
|
||||||
|
BuildType: debug-clang
|
||||||
|
cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Debug -DMI_CHECK_FULL=ON
|
||||||
|
Release Clang:
|
||||||
|
CC: clang
|
||||||
|
CXX: clang++
|
||||||
|
BuildType: release-clang
|
||||||
|
cmakeExtraArgs: -DCMAKE_BUILD_TYPE=Release
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- task: CMake@1
|
- task: CMake@1
|
||||||
inputs:
|
inputs:
|
||||||
workingDirectory: 'build'
|
workingDirectory: $(BuildType)
|
||||||
cmakeArgs: ..
|
cmakeArgs: .. $(cmakeExtraArgs)
|
||||||
- script: make -j$(nproc) -C build
|
|
||||||
- upload: $(Build.SourcesDirectory)/build
|
- script: make -j$(nproc) -C $(BuildType)
|
||||||
artifact: ubuntu
|
displayName: Make
|
||||||
|
|
||||||
|
- script: make test -C $(BuildType)
|
||||||
|
displayName: Ctest
|
||||||
|
|
||||||
|
- upload: $(Build.SourcesDirectory)/$(BuildType)
|
||||||
|
artifact: ubuntu-$(BuildType)
|
||||||
|
|
||||||
- job:
|
- job:
|
||||||
displayName: macOS
|
displayName: macOS
|
||||||
pool:
|
pool:
|
||||||
|
155
ide/vs2017/mimalloc-test-stress.vcxproj
Normal file
155
ide/vs2017/mimalloc-test-stress.vcxproj
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>Win32</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Debug|x64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|x64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>x64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<VCProjectVersion>15.0</VCProjectVersion>
|
||||||
|
<ProjectGuid>{FEF7958F-750E-4C21-A04D-22707CC66878}</ProjectGuid>
|
||||||
|
<RootNamespace>mimalloc-test-stress</RootNamespace>
|
||||||
|
<WindowsTargetPlatformVersion>10.0.17134.0</WindowsTargetPlatformVersion>
|
||||||
|
<ProjectName>mimalloc-test-stress</ProjectName>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
|
<ImportGroup Label="ExtensionSettings">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="Shared">
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
|
<PropertyGroup Label="UserMacros" />
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\test\test-stress.c">
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="mimalloc.vcxproj">
|
||||||
|
<Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
<ImportGroup Label="ExtensionTargets">
|
||||||
|
</ImportGroup>
|
||||||
|
</Project>
|
22
ide/vs2017/mimalloc-test-stress.vcxproj.filters
Normal file
22
ide/vs2017/mimalloc-test-stress.vcxproj.filters
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<ItemGroup>
|
||||||
|
<Filter Include="Source Files">
|
||||||
|
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||||
|
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Header Files">
|
||||||
|
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||||
|
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
|
||||||
|
</Filter>
|
||||||
|
<Filter Include="Resource Files">
|
||||||
|
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||||
|
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||||
|
</Filter>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ClCompile Include="..\..\test\test-stress.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
Binary file not shown.
4
src/os.c
4
src/os.c
@ -93,7 +93,7 @@ void _mi_os_init(void) {
|
|||||||
if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity;
|
if (si.dwAllocationGranularity > 0) os_alloc_granularity = si.dwAllocationGranularity;
|
||||||
// get the VirtualAlloc2 function
|
// get the VirtualAlloc2 function
|
||||||
HINSTANCE hDll;
|
HINSTANCE hDll;
|
||||||
hDll = LoadLibrary("kernelbase.dll");
|
hDll = LoadLibrary(TEXT("kernelbase.dll"));
|
||||||
if (hDll != NULL) {
|
if (hDll != NULL) {
|
||||||
// use VirtualAlloc2FromApp as it is available to Windows store apps
|
// use VirtualAlloc2FromApp as it is available to Windows store apps
|
||||||
pVirtualAlloc2 = (VirtualAlloc2Ptr)GetProcAddress(hDll, "VirtualAlloc2FromApp");
|
pVirtualAlloc2 = (VirtualAlloc2Ptr)GetProcAddress(hDll, "VirtualAlloc2FromApp");
|
||||||
@ -110,7 +110,7 @@ void _mi_os_init(void) {
|
|||||||
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
|
ok = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
TOKEN_PRIVILEGES tp;
|
TOKEN_PRIVILEGES tp;
|
||||||
ok = LookupPrivilegeValue(NULL, "SeLockMemoryPrivilege", &tp.Privileges[0].Luid);
|
ok = LookupPrivilegeValue(NULL, TEXT("SeLockMemoryPrivilege"), &tp.Privileges[0].Luid);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
tp.PrivilegeCount = 1;
|
tp.PrivilegeCount = 1;
|
||||||
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
@ -92,6 +92,10 @@ static void mi_segment_enqueue(mi_segment_queue_t* queue, mi_segment_t* segment)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* -----------------------------------------------------------
|
||||||
|
Invariant checking
|
||||||
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
#if (MI_DEBUG > 1)
|
#if (MI_DEBUG > 1)
|
||||||
static size_t mi_segment_pagesize(mi_segment_t* segment) {
|
static size_t mi_segment_pagesize(mi_segment_t* segment) {
|
||||||
return ((size_t)1 << segment->page_shift);
|
return ((size_t)1 << segment->page_shift);
|
||||||
|
166
test/test-stress.c
Normal file
166
test/test-stress.c
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
/* ----------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2018,2019 Microsoft Research, Daan Leijen
|
||||||
|
This is free software; you can redistribute it and/or modify it under the
|
||||||
|
terms of the MIT license. A copy of the license can be found in the file
|
||||||
|
"LICENSE" at the root of this distribution.
|
||||||
|
-----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* This is a stress test for the allocator, using multiple threads and
|
||||||
|
transferring objects between threads. This is not a typical workload
|
||||||
|
but uses a random size distribution. Do not use this test as a benchmark!
|
||||||
|
Note: pthreads uses mimalloc to allocate stacks and thus not all
|
||||||
|
memory is freed at the end. (usually the 320 byte chunks).
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "mimalloc.h"
|
||||||
|
#include "mimalloc-internal.h"
|
||||||
|
#include "mimalloc-atomic.h"
|
||||||
|
|
||||||
|
#define N (10) // scaling factor
|
||||||
|
#define THREADS (32)
|
||||||
|
#define TRANSFERS (1000)
|
||||||
|
|
||||||
|
static volatile void* transfer[TRANSFERS];
|
||||||
|
|
||||||
|
#if (MI_INTPTR_SIZE==8)
|
||||||
|
const uintptr_t cookie = 0xbf58476d1ce4e5b9UL;
|
||||||
|
#else
|
||||||
|
const uintptr_t cookie = 0x1ce4e5b9UL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
static void* alloc_items(size_t items) {
|
||||||
|
if ((rand()%100) == 0) items *= 100; // 1% huge objects;
|
||||||
|
if (items==40) items++; // pthreads uses that size for stack increases
|
||||||
|
uintptr_t* p = mi_mallocn_tp(uintptr_t,items);
|
||||||
|
for (uintptr_t i = 0; i < items; i++) p[i] = (items - i) ^ cookie;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_items(void* p) {
|
||||||
|
if (p != NULL) {
|
||||||
|
uintptr_t* q = (uintptr_t*)p;
|
||||||
|
uintptr_t items = (q[0] ^ cookie);
|
||||||
|
for (uintptr_t i = 0; i < items; i++) {
|
||||||
|
if ((q[i]^cookie) != items - i) {
|
||||||
|
fprintf(stderr,"memory corruption at block %p at %zu\n", p, i);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mi_free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void stress(intptr_t tid) {
|
||||||
|
const size_t max_item = 128; // in words
|
||||||
|
const size_t max_item_retained = 10*max_item;
|
||||||
|
size_t allocs = 80*N*(tid%8 + 1); // some threads do more
|
||||||
|
size_t retain = allocs/2;
|
||||||
|
void** data = NULL;
|
||||||
|
size_t data_size = 0;
|
||||||
|
size_t data_top = 0;
|
||||||
|
void** retained = mi_mallocn_tp(void*,retain);
|
||||||
|
size_t retain_top = 0;
|
||||||
|
|
||||||
|
while (allocs>0 || retain>0) {
|
||||||
|
if (retain == 0 || ((rand()%4 == 0) && allocs > 0)) {
|
||||||
|
// 75% alloc
|
||||||
|
allocs--;
|
||||||
|
if (data_top >= data_size) {
|
||||||
|
data_size += 100000;
|
||||||
|
data = mi_reallocn_tp(data, void*, data_size);
|
||||||
|
}
|
||||||
|
data[data_top++] = alloc_items((rand() % max_item) + 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// 25% retain
|
||||||
|
retained[retain_top++] = alloc_items( 10*((rand() % max_item_retained) + 1) );
|
||||||
|
retain--;
|
||||||
|
}
|
||||||
|
if ((rand()%3)!=0 && data_top > 0) {
|
||||||
|
// 66% free previous alloc
|
||||||
|
size_t idx = rand() % data_top;
|
||||||
|
free_items(data[idx]);
|
||||||
|
data[idx]=NULL;
|
||||||
|
}
|
||||||
|
if ((tid%2)==0 && (rand()%4)==0 && data_top > 0) {
|
||||||
|
// 25% transfer-swap of half the threads
|
||||||
|
size_t data_idx = rand() % data_top;
|
||||||
|
size_t transfer_idx = rand() % TRANSFERS;
|
||||||
|
void* p = data[data_idx];
|
||||||
|
void* q = mi_atomic_exchange_ptr(&transfer[transfer_idx],p);
|
||||||
|
data[data_idx] = q;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// free everything that is left
|
||||||
|
for (size_t i = 0; i < retain_top; i++) {
|
||||||
|
free_items(retained[i]);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < data_top; i++) {
|
||||||
|
free_items(data[i]);
|
||||||
|
}
|
||||||
|
mi_free(retained);
|
||||||
|
mi_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_os_threads();
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
srand(42);
|
||||||
|
memset((void*)transfer,0,TRANSFERS*sizeof(void*));
|
||||||
|
run_os_threads();
|
||||||
|
for (int i = 0; i < TRANSFERS; i++) {
|
||||||
|
free_items((void*)transfer[i]);
|
||||||
|
}
|
||||||
|
mi_collect(false);
|
||||||
|
mi_stats_print(NULL);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
static DWORD WINAPI thread_entry(LPVOID param) {
|
||||||
|
stress((intptr_t)param);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_os_threads() {
|
||||||
|
DWORD tids[THREADS];
|
||||||
|
HANDLE thandles[THREADS];
|
||||||
|
for(intptr_t i = 0; i < THREADS; i++) {
|
||||||
|
thandles[i] = CreateThread(0,4096,&thread_entry,(void*)(i),0,&tids[i]);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < THREADS; i++) {
|
||||||
|
WaitForSingleObject(thandles[i], INFINITE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
static void* thread_entry( void* param ) {
|
||||||
|
stress((uintptr_t)param);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void run_os_threads() {
|
||||||
|
pthread_t threads[THREADS];
|
||||||
|
memset(threads,0,sizeof(pthread_t)*THREADS);
|
||||||
|
//pthread_setconcurrency(THREADS);
|
||||||
|
for(uintptr_t i = 0; i < THREADS; i++) {
|
||||||
|
pthread_create(&threads[i], NULL, &thread_entry, (void*)i);
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < THREADS; i++) {
|
||||||
|
pthread_join(threads[i], NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in New Issue
Block a user