mirror of
https://github.com/microsoft/mimalloc.git
synced 2025-07-03 02:04:37 +03:00
merge from dev
This commit is contained in:
commit
806bf8ea7e
28 changed files with 1055 additions and 471 deletions
|
@ -14,6 +14,7 @@ option(MI_TRACK_VALGRIND "Compile with Valgrind support (adds a small overhea
|
||||||
option(MI_TRACK_ASAN "Compile with address sanitizer support (adds a small overhead)" OFF)
|
option(MI_TRACK_ASAN "Compile with address sanitizer support (adds a small overhead)" OFF)
|
||||||
option(MI_TRACK_ETW "Compile with Windows event tracing (ETW) support (adds a small overhead)" OFF)
|
option(MI_TRACK_ETW "Compile with Windows event tracing (ETW) support (adds a small overhead)" OFF)
|
||||||
option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF)
|
option(MI_USE_CXX "Use the C++ compiler to compile the library (instead of the C compiler)" OFF)
|
||||||
|
option(MI_OPT_ARCH "Only for optimized builds: turn on architecture specific optimizations (for arm64: '-march=armv8.1-a' (2016))" ON)
|
||||||
option(MI_SEE_ASM "Generate assembly files" OFF)
|
option(MI_SEE_ASM "Generate assembly files" OFF)
|
||||||
option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
|
option(MI_OSX_INTERPOSE "Use interpose to override standard malloc on macOS" ON)
|
||||||
option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" ON)
|
option(MI_OSX_ZONE "Use malloc zone to override standard malloc on macOS" ON)
|
||||||
|
@ -73,16 +74,16 @@ else()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Convenience: set default build type depending on the build directory
|
# Convenience: set default build type and compiler depending on the build directory
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
message(STATUS "")
|
message(STATUS "")
|
||||||
if (NOT CMAKE_BUILD_TYPE)
|
if (NOT CMAKE_BUILD_TYPE)
|
||||||
if ("${CMAKE_BINARY_DIR}" MATCHES ".*(D|d)ebug$" OR MI_DEBUG_FULL)
|
if ("${CMAKE_BINARY_DIR}" MATCHES ".*((D|d)ebug|asan|tsan|ubsan|valgrind)$" OR MI_DEBUG_FULL)
|
||||||
message(STATUS "No build type selected, default to: Debug")
|
message(STATUS "No build type selected, default to 'Debug'")
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
else()
|
else()
|
||||||
message(STATUS "No build type selected, default to: Release")
|
message(STATUS "No build type selected, default to 'Release'")
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
set(CMAKE_BUILD_TYPE "Release")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
@ -92,7 +93,6 @@ if("${CMAKE_BINARY_DIR}" MATCHES ".*(S|s)ecure$")
|
||||||
set(MI_SECURE "ON")
|
set(MI_SECURE "ON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
# Process options
|
# Process options
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
|
@ -112,6 +112,14 @@ if(CMAKE_C_COMPILER_ID MATCHES "MSVC|Intel")
|
||||||
set(MI_USE_CXX "ON")
|
set(MI_USE_CXX "ON")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CMAKE_BUILD_TYPE MATCHES "Release|RelWithDebInfo")
|
||||||
|
if (NOT MI_OPT_ARCH)
|
||||||
|
message(STATUS "Architecture specific optimizations are disabled (MI_OPT_ARCH=OFF)")
|
||||||
|
endif()
|
||||||
|
else()
|
||||||
|
set(MI_OPT_ARCH OFF)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MI_OVERRIDE)
|
if(MI_OVERRIDE)
|
||||||
message(STATUS "Override standard malloc (MI_OVERRIDE=ON)")
|
message(STATUS "Override standard malloc (MI_OVERRIDE=ON)")
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
|
@ -139,12 +147,6 @@ if(MI_OVERRIDE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
if (MI_WIN_REDIRECT)
|
|
||||||
if (MSVC_C_ARCHITECTURE_ID MATCHES "ARM")
|
|
||||||
message(STATUS "Cannot use redirection on Windows ARM (MI_WIN_REDIRECT=OFF)")
|
|
||||||
set(MI_WIN_REDIRECT OFF)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if (NOT MI_WIN_REDIRECT)
|
if (NOT MI_WIN_REDIRECT)
|
||||||
# use a negative define for backward compatibility
|
# use a negative define for backward compatibility
|
||||||
list(APPEND mi_defines MI_WIN_NOREDIRECT=1)
|
list(APPEND mi_defines MI_WIN_NOREDIRECT=1)
|
||||||
|
@ -319,16 +321,32 @@ if(MI_WIN_USE_FLS)
|
||||||
list(APPEND mi_defines MI_WIN_USE_FLS=1)
|
list(APPEND mi_defines MI_WIN_USE_FLS=1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# Determine architecture
|
||||||
|
set(MI_OPT_ARCH_FLAGS "")
|
||||||
|
set(MI_ARCH "unknown")
|
||||||
|
if(APPLE)
|
||||||
|
list(FIND CMAKE_OSX_ARCHITECTURES "x86_64" x64_index)
|
||||||
|
list(FIND CMAKE_OSX_ARCHITECTURES "arm64" arm64_index)
|
||||||
|
if(x64_index GREATER_EQUAL 0)
|
||||||
|
set(MI_ARCH "x64")
|
||||||
|
elseif(arm64_index GREATER_EQUAL 0)
|
||||||
|
set(MI_ARCH "arm64")
|
||||||
|
endif()
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64" OR CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
|
||||||
|
set(MI_ARCH "x64")
|
||||||
|
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64" OR CMAKE_GENERATOR_PLATFORM STREQUAL "ARM64")
|
||||||
|
set(MI_ARCH "arm64")
|
||||||
|
endif()
|
||||||
|
|
||||||
# Check /proc/cpuinfo for an SV39 MMU and limit the virtual address bits.
|
# Check /proc/cpuinfo for an SV39 MMU and limit the virtual address bits.
|
||||||
# (this will skip the aligned hinting in that case. Issue #939, #949)
|
# (this will skip the aligned hinting in that case. Issue #939, #949)
|
||||||
if (EXISTS /proc/cpuinfo)
|
if (EXISTS /proc/cpuinfo)
|
||||||
file(STRINGS /proc/cpuinfo mi_sv39_mmu REGEX "^mmu[ \t]+:[ \t]+sv39$")
|
file(STRINGS /proc/cpuinfo mi_sv39_mmu REGEX "^mmu[ \t]+:[ \t]+sv39$")
|
||||||
if (mi_sv39_mmu)
|
if (mi_sv39_mmu)
|
||||||
MESSAGE( STATUS "Set virtual address bits to 39 (SV39 MMU detected)" )
|
MESSAGE( STATUS "Set virtual address bits to 39 (SV39 MMU detected)" )
|
||||||
list(APPEND mi_defines MI_DEFAULT_VIRTUAL_ADDRESS_BITS=39)
|
list(APPEND mi_defines MI_DEFAULT_VIRTUAL_ADDRESS_BITS=39)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# On Haiku use `-DCMAKE_INSTALL_PREFIX` instead, issue #788
|
# On Haiku use `-DCMAKE_INSTALL_PREFIX` instead, issue #788
|
||||||
# if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
# if(CMAKE_SYSTEM_NAME MATCHES "Haiku")
|
||||||
|
@ -367,16 +385,31 @@ if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang|GNU|Intel" AND NOT CMAKE_SYSTEM
|
||||||
if(MI_OVERRIDE)
|
if(MI_OVERRIDE)
|
||||||
list(APPEND mi_cflags -fno-builtin-malloc)
|
list(APPEND mi_cflags -fno-builtin-malloc)
|
||||||
endif()
|
endif()
|
||||||
|
if(MI_OPT_ARCH)
|
||||||
|
if(MI_ARCH STREQUAL "arm64")
|
||||||
|
set(MI_OPT_ARCH_FLAGS "-march=armv8.1-a") # fast atomics
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914)
|
if (MSVC AND MSVC_VERSION GREATER_EQUAL 1914)
|
||||||
list(APPEND mi_cflags /Zc:__cplusplus)
|
list(APPEND mi_cflags /Zc:__cplusplus)
|
||||||
|
if(MI_OPT_ARCH)
|
||||||
|
if(MI_ARCH STREQUAL "arm64")
|
||||||
|
set(MI_OPT_ARCH_FLAGS "/arch:armv8.1") # fast atomics
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
add_definitions(-D_WIN32_WINNT=0x600)
|
add_definitions(-D_WIN32_WINNT=0x600)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(MI_OPT_ARCH_FLAGS)
|
||||||
|
list(APPEND mi_cflags ${MI_OPT_ARCH_FLAGS})
|
||||||
|
message(STATUS "Architecture specific optimization is enabled (with ${MI_OPT_ARCH_FLAGS}) (MI_OPT_ARCH=ON)")
|
||||||
|
endif()
|
||||||
|
|
||||||
# extra needed libraries
|
# extra needed libraries
|
||||||
|
|
||||||
# we prefer -l<lib> test over `find_library` as sometimes core libraries
|
# we prefer -l<lib> test over `find_library` as sometimes core libraries
|
||||||
|
@ -495,7 +528,9 @@ if(MI_BUILD_SHARED)
|
||||||
)
|
)
|
||||||
if(WIN32 AND MI_WIN_REDIRECT)
|
if(WIN32 AND MI_WIN_REDIRECT)
|
||||||
# On windows, link and copy the mimalloc redirection dll too.
|
# On windows, link and copy the mimalloc redirection dll too.
|
||||||
if(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
if(MI_ARCH STREQUAL "arm64")
|
||||||
|
set(MIMALLOC_REDIRECT_SUFFIX "-arm64")
|
||||||
|
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
|
||||||
set(MIMALLOC_REDIRECT_SUFFIX "32")
|
set(MIMALLOC_REDIRECT_SUFFIX "32")
|
||||||
else()
|
else()
|
||||||
set(MIMALLOC_REDIRECT_SUFFIX "")
|
set(MIMALLOC_REDIRECT_SUFFIX "")
|
||||||
|
@ -617,6 +652,11 @@ endif()
|
||||||
if (MI_OVERRIDE)
|
if (MI_OVERRIDE)
|
||||||
if (MI_BUILD_SHARED)
|
if (MI_BUILD_SHARED)
|
||||||
target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE)
|
target_compile_definitions(mimalloc PRIVATE MI_MALLOC_OVERRIDE)
|
||||||
|
if (WIN32)
|
||||||
|
# on windows we should generate mimalloc-override.dll.
|
||||||
|
string(REPLACE "mimalloc" "mimalloc-override" mi_override_output_name ${mi_basename})
|
||||||
|
set_target_properties(mimalloc PROPERTIES OUTPUT_NAME ${mi_override_output_name})
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
# It is only possible to override malloc on Windows when building as a DLL.
|
# It is only possible to override malloc on Windows when building as a DLL.
|
||||||
|
|
|
@ -284,7 +284,7 @@ jobs:
|
||||||
displayName: CTest
|
displayName: CTest
|
||||||
|
|
||||||
- job:
|
- job:
|
||||||
displayName: macOS 15 (Sequia)
|
displayName: macOS 15 (Sequoia)
|
||||||
pool:
|
pool:
|
||||||
vmImage:
|
vmImage:
|
||||||
macOS-15
|
macOS-15
|
||||||
|
|
BIN
bin/mimalloc-redirect-arm64.dll
Normal file
BIN
bin/mimalloc-redirect-arm64.dll
Normal file
Binary file not shown.
BIN
bin/mimalloc-redirect-arm64.lib
Normal file
BIN
bin/mimalloc-redirect-arm64.lib
Normal file
Binary file not shown.
BIN
bin/minject-arm64.exe
Normal file
BIN
bin/minject-arm64.exe
Normal file
Binary file not shown.
|
@ -11,11 +11,12 @@ There are four requirements to make the overriding work robustly:
|
||||||
|
|
||||||
2. Link your program explicitly with `mimalloc-override.dll` library.
|
2. Link your program explicitly with `mimalloc-override.dll` library.
|
||||||
To ensure the `mimalloc-override.dll` is loaded at run-time it is easiest to insert some
|
To ensure the `mimalloc-override.dll` is loaded at run-time it is easiest to insert some
|
||||||
call to the mimalloc API in the `main` function, like `mi_version()`
|
call to the mimalloc API in the `main` function, like `mi_version()`
|
||||||
(or use the `/INCLUDE:mi_version` switch on the linker). See the `mimalloc-override-test` project
|
(or use the `/INCLUDE:mi_version` switch on the linker, or
|
||||||
for an example on how to use this.
|
use `#pragma comment(linker, "/include:mi_version")` in some source file).
|
||||||
|
See the `mimalloc-override-test` project for an example on how to use this.
|
||||||
|
|
||||||
3. The `mimalloc-redirect.dll` (or `mimalloc-redirect32.dll`) must be put
|
3. The `mimalloc-redirect.dll` (x64) (or `mimalloc-redirect32.dll` (x86), or `mimalloc-redirect-arm64.dll` (arm64)) must be put
|
||||||
in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency of that DLL).
|
in the same folder as the main `mimalloc-override.dll` at runtime (as it is a dependency of that DLL).
|
||||||
The redirection DLL ensures that all calls to the C runtime malloc API get redirected to
|
The redirection DLL ensures that all calls to the C runtime malloc API get redirected to
|
||||||
mimalloc functions (which reside in `mimalloc-override.dll`).
|
mimalloc functions (which reside in `mimalloc-override.dll`).
|
||||||
|
@ -40,7 +41,9 @@ if they are linked with the dynamic C runtime (`ucrtbase.dll`) -- just put the `
|
||||||
into the import table (and put `mimalloc-redirect.dll` in the same folder)
|
into the import table (and put `mimalloc-redirect.dll` in the same folder)
|
||||||
Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388).
|
Such patching can be done for example with [CFF Explorer](https://ntcore.com/?page_id=388).
|
||||||
|
|
||||||
The `minject` program can also do this from the command line, use `minject --help` for options:
|
The `minject` program can also do this from the command line
|
||||||
|
(or `minject32` for 32-bit PE files, or `minject-arm64` on arm64 Windows).
|
||||||
|
Use `minject --help` for options:
|
||||||
|
|
||||||
```
|
```
|
||||||
> minject --help
|
> minject --help
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -42,12 +50,23 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -62,9 +81,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -78,10 +103,18 @@
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -128,6 +161,30 @@
|
||||||
</Command>
|
</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
<CompileAs>Default</CompileAs>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
<AdditionalDependencies>kernel32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent />
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -176,6 +233,31 @@
|
||||||
</Command>
|
</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\test\main-override.cpp" />
|
<ClCompile Include="..\..\test\main-override.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -41,11 +49,21 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -60,9 +78,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -82,12 +106,24 @@
|
||||||
<TargetExt>.dll</TargetExt>
|
<TargetExt>.dll</TargetExt>
|
||||||
<TargetName>mimalloc-override</TargetName>
|
<TargetName>mimalloc-override</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
<TargetExt>.dll</TargetExt>
|
||||||
|
<TargetName>mimalloc-override</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
<TargetExt>.dll</TargetExt>
|
<TargetExt>.dll</TargetExt>
|
||||||
<TargetName>mimalloc-override</TargetName>
|
<TargetName>mimalloc-override</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
<TargetExt>.dll</TargetExt>
|
||||||
|
<TargetName>mimalloc-override</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -144,6 +180,34 @@
|
||||||
<Message>copy mimalloc-redirect.dll to the output directory</Message>
|
<Message>copy mimalloc-redirect.dll to the output directory</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>MI_DEBUG=4;MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);</PreprocessorDefinitions>
|
||||||
|
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect-arm64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
|
<ModuleDefinitionFile>
|
||||||
|
</ModuleDefinitionFile>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect-arm64.dll" "$(OutputPath)"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Message>copy mimalloc-redirect-arm64.dll to the output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -208,6 +272,39 @@
|
||||||
<Message>copy mimalloc-redirect.dll to the output directory</Message>
|
<Message>copy mimalloc-redirect.dll to the output directory</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>MI_SHARED_LIB;MI_SHARED_LIB_EXPORT;MI_MALLOC_OVERRIDE;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||||
|
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<EnableEnhancedInstructionSet>CPUExtensionRequirementsARMv81</EnableEnhancedInstructionSet>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<AdditionalDependencies>$(ProjectDir)\..\..\bin\mimalloc-redirect-arm64.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<ModuleDefinitionFile>
|
||||||
|
</ModuleDefinitionFile>
|
||||||
|
<LinkTimeCodeGeneration>Default</LinkTimeCodeGeneration>
|
||||||
|
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>COPY /Y "$(ProjectDir)..\..\bin\mimalloc-redirect-arm64.dll" "$(OutputPath)"</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Message>copy mimalloc-redirect-arm64.dll to the output directory</Message>
|
||||||
|
</PostBuildEvent>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" />
|
<ClInclude Include="$(ProjectDir)..\..\include\mimalloc.h" />
|
||||||
<ClInclude Include="..\..\include\mimalloc-etw-gen.h" />
|
<ClInclude Include="..\..\include\mimalloc-etw-gen.h" />
|
||||||
|
@ -226,13 +323,17 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\alloc-override.c">
|
<ClCompile Include="..\..\src\alloc-override.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\alloc-posix.c" />
|
<ClCompile Include="..\..\src\alloc-posix.c" />
|
||||||
<ClCompile Include="..\..\src\alloc.c" />
|
<ClCompile Include="..\..\src\alloc.c" />
|
||||||
|
@ -240,7 +341,9 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\arena.c" />
|
<ClCompile Include="..\..\src\arena.c" />
|
||||||
<ClCompile Include="..\..\src\bitmap.c" />
|
<ClCompile Include="..\..\src\bitmap.c" />
|
||||||
|
@ -252,7 +355,9 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\options.c" />
|
<ClCompile Include="..\..\src\options.c" />
|
||||||
<ClCompile Include="..\..\src\os.c" />
|
<ClCompile Include="..\..\src\os.c" />
|
||||||
|
@ -260,7 +365,9 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\page.c" />
|
<ClCompile Include="..\..\src\page.c" />
|
||||||
<ClCompile Include="..\..\src\random.c" />
|
<ClCompile Include="..\..\src\random.c" />
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -42,12 +50,23 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -62,9 +81,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -78,10 +103,18 @@
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -106,6 +139,18 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<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'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -140,15 +185,35 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<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>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\test\test-api-fill.c">
|
<ClCompile Include="..\..\test\test-api-fill.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\test\test-api.c">
|
<ClCompile Include="..\..\test\test-api.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -42,12 +50,23 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -62,9 +81,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -78,10 +103,18 @@
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -106,6 +139,18 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<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'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -140,17 +185,37 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<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>
|
||||||
|
<EnableEnhancedInstructionSet>CPUExtensionRequirementsARMv81</EnableEnhancedInstructionSet>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\test\test-stress.c">
|
<ClCompile Include="..\..\test\test-stress.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="mimalloc-override.vcxproj">
|
<ProjectReference Include="mimalloc.vcxproj">
|
||||||
<Project>{abb5eae7-b3e6-432e-b636-333449892ea7}</Project>
|
<Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project>
|
||||||
</ProjectReference>
|
</ProjectReference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -42,12 +50,23 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -62,9 +81,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -78,10 +103,18 @@
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -108,6 +141,19 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
@ -144,6 +190,24 @@
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level3</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>..\..\include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>_MBCS;%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
<LanguageStandard>stdcpp17</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<SubSystem>Console</SubSystem>
|
||||||
|
</Link>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="mimalloc.vcxproj">
|
<ProjectReference Include="mimalloc.vcxproj">
|
||||||
<Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project>
|
<Project>{abb5eae7-b3e6-432e-b636-333449892ea6}</Project>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 16
|
# Visual Studio Version 17
|
||||||
VisualStudioVersion = 16.0.29709.97
|
VisualStudioVersion = 17.12.35527.113 d17.12
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc", "mimalloc.vcxproj", "{ABB5EAE7-B3E6-432E-B636-333449892EA6}"
|
||||||
EndProject
|
EndProject
|
||||||
|
@ -17,56 +17,82 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mimalloc-test-api", "mimall
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|ARM64 = Debug|ARM64
|
||||||
Debug|x64 = Debug|x64
|
Debug|x64 = Debug|x64
|
||||||
Debug|x86 = Debug|x86
|
Debug|x86 = Debug|x86
|
||||||
|
Release|ARM64 = Release|ARM64
|
||||||
Release|x64 = Release|x64
|
Release|x64 = Release|x64
|
||||||
Release|x86 = Release|x86
|
Release|x86 = Release|x86
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x64.Build.0 = Debug|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.ActiveCfg = Release|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x64.Build.0 = Release|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA6}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
|
{FEF7858F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x64.Build.0 = Debug|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.ActiveCfg = Release|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x64.Build.0 = Release|x64
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32
|
{ABB5EAE7-B3E6-432E-B636-333449892EA7}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x64.Build.0 = Debug|x64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.ActiveCfg = Release|x64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x64.Build.0 = Release|x64
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32
|
{FEF7868F-750E-4C21-A04D-22707CC66879}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
||||||
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
|
{FEF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.Build.0 = Release|Win32
|
||||||
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x64.Build.0 = Debug|x64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.ActiveCfg = Debug|Win32
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Debug|x86.Build.0 = Debug|Win32
|
||||||
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.ActiveCfg = Release|x64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x64.Build.0 = Release|x64
|
||||||
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
{FFF7958F-750E-4C21-A04D-22707CC66878}.Release|x86.ActiveCfg = Release|Win32
|
||||||
|
|
|
@ -1,10 +1,18 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
<ItemGroup Label="ProjectConfigurations">
|
<ItemGroup Label="ProjectConfigurations">
|
||||||
|
<ProjectConfiguration Include="Debug|ARM64">
|
||||||
|
<Configuration>Debug</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Debug|Win32">
|
<ProjectConfiguration Include="Debug|Win32">
|
||||||
<Configuration>Debug</Configuration>
|
<Configuration>Debug</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
|
<ProjectConfiguration Include="Release|ARM64">
|
||||||
|
<Configuration>Release</Configuration>
|
||||||
|
<Platform>ARM64</Platform>
|
||||||
|
</ProjectConfiguration>
|
||||||
<ProjectConfiguration Include="Release|Win32">
|
<ProjectConfiguration Include="Release|Win32">
|
||||||
<Configuration>Release</Configuration>
|
<Configuration>Release</Configuration>
|
||||||
<Platform>Win32</Platform>
|
<Platform>Win32</Platform>
|
||||||
|
@ -42,12 +50,23 @@
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="Configuration">
|
||||||
|
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||||
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
|
<PlatformToolset>v143</PlatformToolset>
|
||||||
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
@ -62,9 +81,15 @@
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<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" />
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'" Label="PropertySheets">
|
||||||
|
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||||
|
</ImportGroup>
|
||||||
<PropertyGroup Label="UserMacros" />
|
<PropertyGroup Label="UserMacros" />
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
@ -84,12 +109,24 @@
|
||||||
<TargetExt>.lib</TargetExt>
|
<TargetExt>.lib</TargetExt>
|
||||||
<TargetName>mimalloc-static</TargetName>
|
<TargetName>mimalloc-static</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
<TargetExt>.lib</TargetExt>
|
||||||
|
<TargetName>mimalloc-static</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
<TargetExt>.lib</TargetExt>
|
<TargetExt>.lib</TargetExt>
|
||||||
<TargetName>mimalloc-static</TargetName>
|
<TargetName>mimalloc-static</TargetName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<OutDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(Configuration)\</OutDir>
|
||||||
|
<IntDir>$(SolutionDir)..\..\out\msvc-$(Platform)\$(ProjectName)\$(Configuration)\</IntDir>
|
||||||
|
<TargetExt>.lib</TargetExt>
|
||||||
|
<TargetName>mimalloc-static</TargetName>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
@ -136,6 +173,33 @@
|
||||||
</AdditionalDependencies>
|
</AdditionalDependencies>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>Disabled</Optimization>
|
||||||
|
<SDLCheck>true</SDLCheck>
|
||||||
|
<ConformanceMode>Default</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>MI_DEBUG=3;MI_GUARDED=0;%(PreprocessorDefinitions);</PreprocessorDefinitions>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<SupportJustMyCode>false</SupportJustMyCode>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
</ClCompile>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<Link>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
</Link>
|
||||||
|
<Lib>
|
||||||
|
<AdditionalLibraryDirectories>
|
||||||
|
</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>
|
||||||
|
</AdditionalDependencies>
|
||||||
|
</Lib>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<WarningLevel>Level4</WarningLevel>
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
@ -198,34 +262,79 @@
|
||||||
</AdditionalDependencies>
|
</AdditionalDependencies>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
|
||||||
|
<ClCompile>
|
||||||
|
<WarningLevel>Level4</WarningLevel>
|
||||||
|
<Optimization>MaxSpeed</Optimization>
|
||||||
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
|
<ConformanceMode>Default</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||||
|
<PreprocessorDefinitions>%(PreprocessorDefinitions);NDEBUG</PreprocessorDefinitions>
|
||||||
|
<AssemblerOutput>AssemblyAndSourceCode</AssemblerOutput>
|
||||||
|
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||||
|
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||||
|
<BufferSecurityCheck>false</BufferSecurityCheck>
|
||||||
|
<InlineFunctionExpansion>Default</InlineFunctionExpansion>
|
||||||
|
<CompileAs>CompileAsCpp</CompileAs>
|
||||||
|
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||||
|
<LanguageStandard>stdcpp20</LanguageStandard>
|
||||||
|
<EnableEnhancedInstructionSet>CPUExtensionRequirementsARMv81</EnableEnhancedInstructionSet>
|
||||||
|
<ExceptionHandling>Sync</ExceptionHandling>
|
||||||
|
</ClCompile>
|
||||||
|
<Link>
|
||||||
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
|
<EntryPointSymbol>
|
||||||
|
</EntryPointSymbol>
|
||||||
|
</Link>
|
||||||
|
<PostBuildEvent>
|
||||||
|
<Command>
|
||||||
|
</Command>
|
||||||
|
</PostBuildEvent>
|
||||||
|
<Lib>
|
||||||
|
<AdditionalLibraryDirectories>
|
||||||
|
</AdditionalLibraryDirectories>
|
||||||
|
<AdditionalDependencies>
|
||||||
|
</AdditionalDependencies>
|
||||||
|
</Lib>
|
||||||
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="..\..\src\alloc-aligned.c">
|
<ClCompile Include="..\..\src\alloc-aligned.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">false</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\alloc-override.c">
|
<ClCompile Include="..\..\src\alloc-override.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\alloc-posix.c" />
|
<ClCompile Include="..\..\src\alloc-posix.c" />
|
||||||
<ClCompile Include="..\..\src\alloc.c" />
|
<ClCompile Include="..\..\src\alloc.c" />
|
||||||
<ClCompile Include="..\..\src\arena-abandon.c">
|
<ClCompile Include="..\..\src\arena-abandon.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\arena.c" />
|
<ClCompile Include="..\..\src\arena.c" />
|
||||||
<ClCompile Include="..\..\src\bitmap.c">
|
<ClCompile Include="..\..\src\bitmap.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">false</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">false</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\free.c">
|
<ClCompile Include="..\..\src\free.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\heap.c" />
|
<ClCompile Include="..\..\src\heap.c" />
|
||||||
<ClCompile Include="..\..\src\init.c" />
|
<ClCompile Include="..\..\src\init.c" />
|
||||||
|
@ -235,14 +344,18 @@
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\options.c" />
|
<ClCompile Include="..\..\src\options.c" />
|
||||||
<ClCompile Include="..\..\src\page-queue.c">
|
<ClCompile Include="..\..\src\page-queue.c">
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">true</ExcludedFromBuild>
|
||||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||||
|
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">true</ExcludedFromBuild>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="..\..\src\page.c" />
|
<ClCompile Include="..\..\src\page.c" />
|
||||||
<ClCompile Include="..\..\src\random.c" />
|
<ClCompile Include="..\..\src\random.c" />
|
||||||
|
|
|
@ -53,90 +53,100 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#define mi_decl_externc
|
#define mi_decl_externc
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// "libc.c"
|
||||||
|
#include <stdarg.h>
|
||||||
|
void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);
|
||||||
|
void _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...);
|
||||||
|
char _mi_toupper(char c);
|
||||||
|
int _mi_strnicmp(const char* s, const char* t, size_t n);
|
||||||
|
void _mi_strlcpy(char* dest, const char* src, size_t dest_size);
|
||||||
|
void _mi_strlcat(char* dest, const char* src, size_t dest_size);
|
||||||
|
size_t _mi_strlen(const char* s);
|
||||||
|
size_t _mi_strnlen(const char* s, size_t max_len);
|
||||||
|
bool _mi_getenv(const char* name, char* result, size_t result_size);
|
||||||
|
|
||||||
// "options.c"
|
// "options.c"
|
||||||
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
|
void _mi_fputs(mi_output_fun* out, void* arg, const char* prefix, const char* message);
|
||||||
void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);
|
void _mi_fprintf(mi_output_fun* out, void* arg, const char* fmt, ...);
|
||||||
void _mi_warning_message(const char* fmt, ...);
|
void _mi_warning_message(const char* fmt, ...);
|
||||||
void _mi_verbose_message(const char* fmt, ...);
|
void _mi_verbose_message(const char* fmt, ...);
|
||||||
void _mi_trace_message(const char* fmt, ...);
|
void _mi_trace_message(const char* fmt, ...);
|
||||||
void _mi_options_init(void);
|
void _mi_options_init(void);
|
||||||
long _mi_option_get_fast(mi_option_t option);
|
long _mi_option_get_fast(mi_option_t option);
|
||||||
void _mi_error_message(int err, const char* fmt, ...);
|
void _mi_error_message(int err, const char* fmt, ...);
|
||||||
|
|
||||||
// random.c
|
// random.c
|
||||||
void _mi_random_init(mi_random_ctx_t* ctx);
|
void _mi_random_init(mi_random_ctx_t* ctx);
|
||||||
void _mi_random_init_weak(mi_random_ctx_t* ctx);
|
void _mi_random_init_weak(mi_random_ctx_t* ctx);
|
||||||
void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);
|
void _mi_random_reinit_if_weak(mi_random_ctx_t * ctx);
|
||||||
void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);
|
void _mi_random_split(mi_random_ctx_t* ctx, mi_random_ctx_t* new_ctx);
|
||||||
uintptr_t _mi_random_next(mi_random_ctx_t* ctx);
|
uintptr_t _mi_random_next(mi_random_ctx_t* ctx);
|
||||||
uintptr_t _mi_heap_random_next(mi_heap_t* heap);
|
uintptr_t _mi_heap_random_next(mi_heap_t* heap);
|
||||||
uintptr_t _mi_os_random_weak(uintptr_t extra_seed);
|
uintptr_t _mi_os_random_weak(uintptr_t extra_seed);
|
||||||
static inline uintptr_t _mi_random_shuffle(uintptr_t x);
|
static inline uintptr_t _mi_random_shuffle(uintptr_t x);
|
||||||
|
|
||||||
// init.c
|
// init.c
|
||||||
extern mi_decl_cache_align mi_stats_t _mi_stats_main;
|
extern mi_decl_cache_align mi_stats_t _mi_stats_main;
|
||||||
extern mi_decl_cache_align const mi_page_t _mi_page_empty;
|
extern mi_decl_cache_align const mi_page_t _mi_page_empty;
|
||||||
void _mi_process_load(void);
|
void _mi_process_load(void);
|
||||||
void mi_cdecl _mi_process_done(void);
|
void mi_cdecl _mi_process_done(void);
|
||||||
bool _mi_is_redirected(void);
|
bool _mi_is_redirected(void);
|
||||||
bool _mi_allocator_init(const char** message);
|
bool _mi_allocator_init(const char** message);
|
||||||
void _mi_allocator_done(void);
|
void _mi_allocator_done(void);
|
||||||
bool _mi_is_main_thread(void);
|
bool _mi_is_main_thread(void);
|
||||||
size_t _mi_current_thread_count(void);
|
size_t _mi_current_thread_count(void);
|
||||||
bool _mi_preloading(void); // true while the C runtime is not initialized yet
|
bool _mi_preloading(void); // true while the C runtime is not initialized yet
|
||||||
void _mi_thread_done(mi_heap_t* heap);
|
void _mi_thread_done(mi_heap_t* heap);
|
||||||
void _mi_thread_data_collect(void);
|
void _mi_thread_data_collect(void);
|
||||||
void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap);
|
void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap);
|
||||||
mi_threadid_t _mi_thread_id(void) mi_attr_noexcept;
|
mi_threadid_t _mi_thread_id(void) mi_attr_noexcept;
|
||||||
mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap
|
mi_heap_t* _mi_heap_main_get(void); // statically allocated main backing heap
|
||||||
mi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id);
|
mi_subproc_t* _mi_subproc_from_id(mi_subproc_id_t subproc_id);
|
||||||
void _mi_heap_guarded_init(mi_heap_t* heap);
|
void _mi_heap_guarded_init(mi_heap_t* heap);
|
||||||
|
|
||||||
// os.c
|
// os.c
|
||||||
void _mi_os_init(void); // called from process init
|
void _mi_os_init(void); // called from process init
|
||||||
void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* stats);
|
void* _mi_os_alloc(size_t size, mi_memid_t* memid);
|
||||||
void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats);
|
void _mi_os_free(void* p, size_t size, mi_memid_t memid);
|
||||||
void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* stats);
|
void _mi_os_free_ex(void* p, size_t size, bool still_committed, mi_memid_t memid);
|
||||||
|
|
||||||
size_t _mi_os_page_size(void);
|
size_t _mi_os_page_size(void);
|
||||||
size_t _mi_os_good_alloc_size(size_t size);
|
size_t _mi_os_good_alloc_size(size_t size);
|
||||||
bool _mi_os_has_overcommit(void);
|
bool _mi_os_has_overcommit(void);
|
||||||
bool _mi_os_has_virtual_reserve(void);
|
bool _mi_os_has_virtual_reserve(void);
|
||||||
|
|
||||||
bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats);
|
bool _mi_os_reset(void* addr, size_t size);
|
||||||
bool _mi_os_reset(void* addr, size_t size, mi_stats_t* tld_stats);
|
bool _mi_os_commit(void* p, size_t size, bool* is_zero);
|
||||||
bool _mi_os_commit(void* p, size_t size, bool* is_zero, mi_stats_t* stats);
|
bool _mi_os_decommit(void* addr, size_t size);
|
||||||
bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
|
bool _mi_os_protect(void* addr, size_t size);
|
||||||
bool _mi_os_protect(void* addr, size_t size);
|
bool _mi_os_unprotect(void* addr, size_t size);
|
||||||
bool _mi_os_unprotect(void* addr, size_t size);
|
bool _mi_os_purge(void* p, size_t size);
|
||||||
bool _mi_os_purge(void* p, size_t size, mi_stats_t* stats);
|
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset);
|
||||||
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats);
|
|
||||||
|
|
||||||
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats);
|
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid);
|
||||||
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* tld_stats);
|
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_memid_t* memid);
|
||||||
|
|
||||||
void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size);
|
void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size);
|
||||||
bool _mi_os_use_large_page(size_t size, size_t alignment);
|
bool _mi_os_use_large_page(size_t size, size_t alignment);
|
||||||
size_t _mi_os_large_page_size(void);
|
size_t _mi_os_large_page_size(void);
|
||||||
|
|
||||||
void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid);
|
void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_secs, size_t* pages_reserved, size_t* psize, mi_memid_t* memid);
|
||||||
|
|
||||||
// arena.c
|
// arena.c
|
||||||
mi_arena_id_t _mi_arena_id_none(void);
|
mi_arena_id_t _mi_arena_id_none(void);
|
||||||
void _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid, mi_stats_t* stats);
|
void _mi_arena_free(void* p, size_t size, size_t still_committed_size, mi_memid_t memid);
|
||||||
void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld);
|
void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid);
|
||||||
void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld);
|
void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid);
|
||||||
bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id);
|
bool _mi_arena_memid_is_suitable(mi_memid_t memid, mi_arena_id_t request_arena_id);
|
||||||
bool _mi_arena_contains(const void* p);
|
bool _mi_arena_contains(const void* p);
|
||||||
void _mi_arenas_collect(bool force_purge, mi_stats_t* stats);
|
void _mi_arenas_collect(bool force_purge);
|
||||||
void _mi_arena_unsafe_destroy_all(mi_stats_t* stats);
|
void _mi_arena_unsafe_destroy_all(void);
|
||||||
|
|
||||||
bool _mi_arena_segment_clear_abandoned(mi_segment_t* segment);
|
bool _mi_arena_segment_clear_abandoned(mi_segment_t* segment);
|
||||||
void _mi_arena_segment_mark_abandoned(mi_segment_t* segment);
|
void _mi_arena_segment_mark_abandoned(mi_segment_t* segment);
|
||||||
|
|
||||||
void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid);
|
void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid);
|
||||||
void _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size);
|
void _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size);
|
||||||
|
|
||||||
typedef struct mi_arena_field_cursor_s { // abstract struct
|
typedef struct mi_arena_field_cursor_s { // abstract struct
|
||||||
size_t os_list_count; // max entries to visit in the OS abandoned list
|
size_t os_list_count; // max entries to visit in the OS abandoned list
|
||||||
|
@ -152,20 +162,20 @@ mi_segment_t* _mi_arena_segment_clear_abandoned_next(mi_arena_field_cursor_t* pr
|
||||||
void _mi_arena_field_cursor_done(mi_arena_field_cursor_t* current);
|
void _mi_arena_field_cursor_done(mi_arena_field_cursor_t* current);
|
||||||
|
|
||||||
// "segment-map.c"
|
// "segment-map.c"
|
||||||
void _mi_segment_map_allocated_at(const mi_segment_t* segment);
|
void _mi_segment_map_allocated_at(const mi_segment_t* segment);
|
||||||
void _mi_segment_map_freed_at(const mi_segment_t* segment);
|
void _mi_segment_map_freed_at(const mi_segment_t* segment);
|
||||||
|
|
||||||
// "segment.c"
|
// "segment.c"
|
||||||
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld);
|
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld);
|
||||||
void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld);
|
void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld);
|
||||||
void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld);
|
void _mi_segment_page_abandon(mi_page_t* page, mi_segments_tld_t* tld);
|
||||||
bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld);
|
bool _mi_segment_try_reclaim_abandoned( mi_heap_t* heap, bool try_all, mi_segments_tld_t* tld);
|
||||||
void _mi_segment_collect(mi_segment_t* segment, bool force, mi_segments_tld_t* tld);
|
void _mi_segment_collect(mi_segment_t* segment, bool force);
|
||||||
|
|
||||||
#if MI_HUGE_PAGE_ABANDON
|
#if MI_HUGE_PAGE_ABANDON
|
||||||
void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
|
void _mi_segment_huge_page_free(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
|
||||||
#else
|
#else
|
||||||
void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
|
void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_block_t* block);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page
|
uint8_t* _mi_segment_page_start(const mi_segment_t* segment, const mi_page_t* page, size_t* page_size); // page start for any page
|
||||||
|
@ -175,42 +185,42 @@ bool _mi_segment_attempt_reclaim(mi_heap_t* heap, mi_segment_t* segment);
|
||||||
bool _mi_segment_visit_blocks(mi_segment_t* segment, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);
|
bool _mi_segment_visit_blocks(mi_segment_t* segment, int heap_tag, bool visit_blocks, mi_block_visit_fun* visitor, void* arg);
|
||||||
|
|
||||||
// "page.c"
|
// "page.c"
|
||||||
void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc;
|
void* _mi_malloc_generic(mi_heap_t* heap, size_t size, bool zero, size_t huge_alignment) mi_attr_noexcept mi_attr_malloc;
|
||||||
|
|
||||||
void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks
|
void _mi_page_retire(mi_page_t* page) mi_attr_noexcept; // free the page if there are no other pages with many free blocks
|
||||||
void _mi_page_unfull(mi_page_t* page);
|
void _mi_page_unfull(mi_page_t* page);
|
||||||
void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page
|
void _mi_page_free(mi_page_t* page, mi_page_queue_t* pq, bool force); // free the page
|
||||||
void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread...
|
void _mi_page_abandon(mi_page_t* page, mi_page_queue_t* pq); // abandon the page, to be picked up by another thread...
|
||||||
void _mi_page_force_abandon(mi_page_t* page);
|
void _mi_page_force_abandon(mi_page_t* page);
|
||||||
|
|
||||||
void _mi_heap_delayed_free_all(mi_heap_t* heap);
|
void _mi_heap_delayed_free_all(mi_heap_t* heap);
|
||||||
bool _mi_heap_delayed_free_partial(mi_heap_t* heap);
|
bool _mi_heap_delayed_free_partial(mi_heap_t* heap);
|
||||||
void _mi_heap_collect_retired(mi_heap_t* heap, bool force);
|
void _mi_heap_collect_retired(mi_heap_t* heap, bool force);
|
||||||
|
|
||||||
void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
|
void _mi_page_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
|
||||||
bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
|
bool _mi_page_try_use_delayed_free(mi_page_t* page, mi_delayed_t delay, bool override_never);
|
||||||
size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append);
|
size_t _mi_page_queue_append(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_queue_t* append);
|
||||||
void _mi_deferred_free(mi_heap_t* heap, bool force);
|
void _mi_deferred_free(mi_heap_t* heap, bool force);
|
||||||
|
|
||||||
void _mi_page_free_collect(mi_page_t* page,bool force);
|
void _mi_page_free_collect(mi_page_t* page,bool force);
|
||||||
void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments
|
void _mi_page_reclaim(mi_heap_t* heap, mi_page_t* page); // callback from segments
|
||||||
|
|
||||||
size_t _mi_bin_size(uint8_t bin); // for stats
|
size_t _mi_bin_size(uint8_t bin); // for stats
|
||||||
uint8_t _mi_bin(size_t size); // for stats
|
uint8_t _mi_bin(size_t size); // for stats
|
||||||
|
|
||||||
// "heap.c"
|
// "heap.c"
|
||||||
void _mi_heap_init(mi_heap_t* heap, mi_tld_t* tld, mi_arena_id_t arena_id, bool noreclaim, uint8_t tag);
|
void _mi_heap_init(mi_heap_t* heap, mi_tld_t* tld, mi_arena_id_t arena_id, bool noreclaim, uint8_t tag);
|
||||||
void _mi_heap_destroy_pages(mi_heap_t* heap);
|
void _mi_heap_destroy_pages(mi_heap_t* heap);
|
||||||
void _mi_heap_collect_abandon(mi_heap_t* heap);
|
void _mi_heap_collect_abandon(mi_heap_t* heap);
|
||||||
void _mi_heap_set_default_direct(mi_heap_t* heap);
|
void _mi_heap_set_default_direct(mi_heap_t* heap);
|
||||||
bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid);
|
bool _mi_heap_memid_is_suitable(mi_heap_t* heap, mi_memid_t memid);
|
||||||
void _mi_heap_unsafe_destroy_all(void);
|
void _mi_heap_unsafe_destroy_all(void);
|
||||||
mi_heap_t* _mi_heap_by_tag(mi_heap_t* heap, uint8_t tag);
|
mi_heap_t* _mi_heap_by_tag(mi_heap_t* heap, uint8_t tag);
|
||||||
void _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);
|
void _mi_heap_area_init(mi_heap_area_t* area, mi_page_t* page);
|
||||||
bool _mi_heap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg);
|
bool _mi_heap_area_visit_blocks(const mi_heap_area_t* area, mi_page_t* page, mi_block_visit_fun* visitor, void* arg);
|
||||||
|
|
||||||
// "stats.c"
|
// "stats.c"
|
||||||
void _mi_stats_done(mi_stats_t* stats);
|
void _mi_stats_done(mi_stats_t* stats);
|
||||||
mi_msecs_t _mi_clock_now(void);
|
mi_msecs_t _mi_clock_now(void);
|
||||||
mi_msecs_t _mi_clock_end(mi_msecs_t start);
|
mi_msecs_t _mi_clock_end(mi_msecs_t start);
|
||||||
mi_msecs_t _mi_clock_start(void);
|
mi_msecs_t _mi_clock_start(void);
|
||||||
|
@ -227,18 +237,6 @@ bool _mi_free_delayed_block(mi_block_t* block);
|
||||||
void _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept; // for runtime integration
|
void _mi_free_generic(mi_segment_t* segment, mi_page_t* page, bool is_local, void* p) mi_attr_noexcept; // for runtime integration
|
||||||
void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size);
|
void _mi_padding_shrink(const mi_page_t* page, const mi_block_t* block, const size_t min_size);
|
||||||
|
|
||||||
// "libc.c"
|
|
||||||
#include <stdarg.h>
|
|
||||||
void _mi_vsnprintf(char* buf, size_t bufsize, const char* fmt, va_list args);
|
|
||||||
void _mi_snprintf(char* buf, size_t buflen, const char* fmt, ...);
|
|
||||||
char _mi_toupper(char c);
|
|
||||||
int _mi_strnicmp(const char* s, const char* t, size_t n);
|
|
||||||
void _mi_strlcpy(char* dest, const char* src, size_t dest_size);
|
|
||||||
void _mi_strlcat(char* dest, const char* src, size_t dest_size);
|
|
||||||
size_t _mi_strlen(const char* s);
|
|
||||||
size_t _mi_strnlen(const char* s, size_t max_len);
|
|
||||||
bool _mi_getenv(const char* name, char* result, size_t result_size);
|
|
||||||
|
|
||||||
#if MI_DEBUG>1
|
#if MI_DEBUG>1
|
||||||
bool _mi_page_is_valid(mi_page_t* page);
|
bool _mi_page_is_valid(mi_page_t* page);
|
||||||
#endif
|
#endif
|
||||||
|
@ -890,13 +888,13 @@ static inline uintptr_t _mi_random_shuffle(uintptr_t x) {
|
||||||
// Optimize numa node access for the common case (= one node)
|
// Optimize numa node access for the common case (= one node)
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
int _mi_os_numa_node_get(mi_os_tld_t* tld);
|
int _mi_os_numa_node_get(void);
|
||||||
size_t _mi_os_numa_node_count_get(void);
|
size_t _mi_os_numa_node_count_get(void);
|
||||||
|
|
||||||
extern _Atomic(size_t) _mi_numa_node_count;
|
extern _Atomic(size_t) _mi_numa_node_count;
|
||||||
static inline int _mi_os_numa_node(mi_os_tld_t* tld) {
|
static inline int _mi_os_numa_node(void) {
|
||||||
if mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1) { return 0; }
|
if mi_likely(mi_atomic_load_relaxed(&_mi_numa_node_count) == 1) { return 0; }
|
||||||
else return _mi_os_numa_node_get(tld);
|
else return _mi_os_numa_node_get();
|
||||||
}
|
}
|
||||||
static inline size_t _mi_os_numa_node_count(void) {
|
static inline size_t _mi_os_numa_node_count(void) {
|
||||||
const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count);
|
const size_t count = mi_atomic_load_relaxed(&_mi_numa_node_count);
|
||||||
|
@ -958,16 +956,18 @@ static inline size_t mi_ctz(uintptr_t x) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline size_t mi_ctz32(uint32_t x) {
|
|
||||||
|
static inline size_t mi_ctz_generic32(uint32_t x) {
|
||||||
// de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
|
// de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
|
||||||
static const unsigned char debruijn[32] = {
|
static const uint8_t debruijn[32] = {
|
||||||
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
|
||||||
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
|
||||||
};
|
};
|
||||||
if (x==0) return 32;
|
if (x==0) return 32;
|
||||||
return debruijn[((x & -(int32_t)x) * 0x077CB531UL) >> 27];
|
return debruijn[(uint32_t)((x & -(int32_t)x) * (uint32_t)(0x077CB531U)) >> 27];
|
||||||
}
|
}
|
||||||
static inline size_t mi_clz32(uint32_t x) {
|
|
||||||
|
static inline size_t mi_clz_generic32(uint32_t x) {
|
||||||
// de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
|
// de Bruijn multiplication, see <http://supertech.csail.mit.edu/papers/debruijn.pdf>
|
||||||
static const uint8_t debruijn[32] = {
|
static const uint8_t debruijn[32] = {
|
||||||
31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
|
31, 22, 30, 21, 18, 10, 29, 2, 20, 17, 15, 13, 9, 6, 28, 1,
|
||||||
|
@ -979,28 +979,37 @@ static inline size_t mi_clz32(uint32_t x) {
|
||||||
x |= x >> 4;
|
x |= x >> 4;
|
||||||
x |= x >> 8;
|
x |= x >> 8;
|
||||||
x |= x >> 16;
|
x |= x >> 16;
|
||||||
return debruijn[(uint32_t)(x * 0x07C4ACDDUL) >> 27];
|
return debruijn[(uint32_t)(x * (uint32_t)(0x07C4ACDDU)) >> 27];
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t mi_clz(uintptr_t x) {
|
static inline size_t mi_ctz(size_t x) {
|
||||||
if (x==0) return MI_INTPTR_BITS;
|
if (x==0) return MI_SIZE_BITS;
|
||||||
#if (MI_INTPTR_BITS <= 32)
|
#if (MI_SIZE_BITS <= 32)
|
||||||
return mi_clz32((uint32_t)x);
|
return mi_ctz_generic32((uint32_t)x);
|
||||||
#else
|
#else
|
||||||
size_t count = mi_clz32((uint32_t)(x >> 32));
|
const uint32_t lo = (uint32_t)x;
|
||||||
if (count < 32) return count;
|
if (lo != 0) {
|
||||||
return (32 + mi_clz32((uint32_t)x));
|
return mi_ctz_generic32(lo);
|
||||||
#endif
|
}
|
||||||
|
else {
|
||||||
|
return (32 + mi_ctz_generic32((uint32_t)(x>>32)));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
static inline size_t mi_ctz(uintptr_t x) {
|
|
||||||
if (x==0) return MI_INTPTR_BITS;
|
static inline size_t mi_clz(size_t x) {
|
||||||
#if (MI_INTPTR_BITS <= 32)
|
if (x==0) return MI_SIZE_BITS;
|
||||||
return mi_ctz32((uint32_t)x);
|
#if (MI_SIZE_BITS <= 32)
|
||||||
#else
|
return mi_clz_generic32((uint32_t)x);
|
||||||
size_t count = mi_ctz32((uint32_t)x);
|
#else
|
||||||
if (count < 32) return count;
|
const uint32_t hi = (uint32_t)(x>>32);
|
||||||
return (32 + mi_ctz32((uint32_t)(x>>32)));
|
if (hi != 0) {
|
||||||
#endif
|
return mi_clz_generic32(hi);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return 32 + mi_clz_generic32((uint32_t)x);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -717,13 +717,6 @@ typedef struct mi_span_queue_s {
|
||||||
|
|
||||||
#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)
|
#define MI_SEGMENT_BIN_MAX (35) // 35 == mi_segment_bin(MI_SLICES_PER_SEGMENT)
|
||||||
|
|
||||||
// OS thread local data
|
|
||||||
typedef struct mi_os_tld_s {
|
|
||||||
size_t region_idx; // start point for next allocation
|
|
||||||
mi_stats_t* stats; // points to tld stats
|
|
||||||
} mi_os_tld_t;
|
|
||||||
|
|
||||||
|
|
||||||
// Segments thread local data
|
// Segments thread local data
|
||||||
typedef struct mi_segments_tld_s {
|
typedef struct mi_segments_tld_s {
|
||||||
mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments
|
mi_span_queue_t spans[MI_SEGMENT_BIN_MAX+1]; // free slice spans inside segments
|
||||||
|
@ -734,7 +727,6 @@ typedef struct mi_segments_tld_s {
|
||||||
size_t reclaim_count;// number of reclaimed (abandoned) segments
|
size_t reclaim_count;// number of reclaimed (abandoned) segments
|
||||||
mi_subproc_t* subproc; // sub-process this thread belongs to.
|
mi_subproc_t* subproc; // sub-process this thread belongs to.
|
||||||
mi_stats_t* stats; // points to tld stats
|
mi_stats_t* stats; // points to tld stats
|
||||||
mi_os_tld_t* os; // points to os tld
|
|
||||||
} mi_segments_tld_t;
|
} mi_segments_tld_t;
|
||||||
|
|
||||||
// Thread local data
|
// Thread local data
|
||||||
|
@ -744,7 +736,6 @@ struct mi_tld_s {
|
||||||
mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted)
|
mi_heap_t* heap_backing; // backing heap of this thread (cannot be deleted)
|
||||||
mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates)
|
mi_heap_t* heaps; // list of heaps in this thread (so we can abandon all when the thread terminates)
|
||||||
mi_segments_tld_t segments; // segment tld
|
mi_segments_tld_t segments; // segment tld
|
||||||
mi_os_tld_t os; // os tld
|
|
||||||
mi_stats_t stats; // statistics
|
mi_stats_t stats; // statistics
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,10 @@ static mi_decl_restrict void* mi_heap_malloc_guarded_aligned(mi_heap_t* heap, si
|
||||||
|
|
||||||
static void* mi_heap_malloc_zero_no_guarded(mi_heap_t* heap, size_t size, bool zero) {
|
static void* mi_heap_malloc_zero_no_guarded(mi_heap_t* heap, size_t size, bool zero) {
|
||||||
const size_t rate = heap->guarded_sample_rate;
|
const size_t rate = heap->guarded_sample_rate;
|
||||||
heap->guarded_sample_rate = 0;
|
// only write if `rate!=0` so we don't write to the constant `_mi_heap_empty`
|
||||||
|
if (rate != 0) { heap->guarded_sample_rate = 0; }
|
||||||
void* p = _mi_heap_malloc_zero(heap, size, zero);
|
void* p = _mi_heap_malloc_zero(heap, size, zero);
|
||||||
heap->guarded_sample_rate = rate;
|
if (rate != 0) { heap->guarded_sample_rate = rate; }
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
|
92
src/arena.c
92
src/arena.c
|
@ -190,7 +190,7 @@ void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid) {
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
|
|
||||||
// or fall back to the OS
|
// or fall back to the OS
|
||||||
p = _mi_os_alloc(size, memid, &_mi_stats_main);
|
p = _mi_os_alloc(size, memid);
|
||||||
if (p == NULL) return NULL;
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
// zero the OS memory if needed
|
// zero the OS memory if needed
|
||||||
|
@ -203,7 +203,7 @@ void* _mi_arena_meta_zalloc(size_t size, mi_memid_t* memid) {
|
||||||
|
|
||||||
void _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size) {
|
void _mi_arena_meta_free(void* p, mi_memid_t memid, size_t size) {
|
||||||
if (mi_memkind_is_os(memid.memkind)) {
|
if (mi_memkind_is_os(memid.memkind)) {
|
||||||
_mi_os_free(p, size, memid, &_mi_stats_main);
|
_mi_os_free(p, size, memid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mi_assert(memid.memkind == MI_MEM_STATIC);
|
mi_assert(memid.memkind == MI_MEM_STATIC);
|
||||||
|
@ -220,10 +220,10 @@ void* mi_arena_block_start(mi_arena_t* arena, mi_bitmap_index_t bindex) {
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
// claim the `blocks_inuse` bits
|
// claim the `blocks_inuse` bits
|
||||||
static bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx, mi_stats_t* stats)
|
static bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index_t* bitmap_idx)
|
||||||
{
|
{
|
||||||
size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx); // start from last search; ok to be relaxed as the exact start does not matter
|
size_t idx = 0; // mi_atomic_load_relaxed(&arena->search_idx); // start from last search; ok to be relaxed as the exact start does not matter
|
||||||
if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx, stats)) {
|
if (_mi_bitmap_try_find_from_claim_across(arena->blocks_inuse, arena->field_count, idx, blocks, bitmap_idx)) {
|
||||||
mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx)); // start search from found location next time around
|
mi_atomic_store_relaxed(&arena->search_idx, mi_bitmap_index_field(*bitmap_idx)); // start search from found location next time around
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
@ -236,13 +236,13 @@ static bool mi_arena_try_claim(mi_arena_t* arena, size_t blocks, mi_bitmap_index
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t arena_index, size_t needed_bcount,
|
static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t arena_index, size_t needed_bcount,
|
||||||
bool commit, mi_memid_t* memid, mi_os_tld_t* tld)
|
bool commit, mi_memid_t* memid)
|
||||||
{
|
{
|
||||||
MI_UNUSED(arena_index);
|
MI_UNUSED(arena_index);
|
||||||
mi_assert_internal(mi_arena_id_index(arena->id) == arena_index);
|
mi_assert_internal(mi_arena_id_index(arena->id) == arena_index);
|
||||||
|
|
||||||
mi_bitmap_index_t bitmap_index;
|
mi_bitmap_index_t bitmap_index;
|
||||||
if (!mi_arena_try_claim(arena, needed_bcount, &bitmap_index, tld->stats)) return NULL;
|
if (!mi_arena_try_claim(arena, needed_bcount, &bitmap_index)) return NULL;
|
||||||
|
|
||||||
// claimed it!
|
// claimed it!
|
||||||
void* p = mi_arena_block_start(arena, bitmap_index);
|
void* p = mi_arena_block_start(arena, bitmap_index);
|
||||||
|
@ -272,7 +272,7 @@ static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t ar
|
||||||
_mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted);
|
_mi_bitmap_claim_across(arena->blocks_committed, arena->field_count, needed_bcount, bitmap_index, &any_uncommitted);
|
||||||
if (any_uncommitted) {
|
if (any_uncommitted) {
|
||||||
bool commit_zero = false;
|
bool commit_zero = false;
|
||||||
if (!_mi_os_commit(p, mi_arena_block_size(needed_bcount), &commit_zero, tld->stats)) {
|
if (!_mi_os_commit(p, mi_arena_block_size(needed_bcount), &commit_zero)) {
|
||||||
memid->initially_committed = false;
|
memid->initially_committed = false;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -290,7 +290,7 @@ static mi_decl_noinline void* mi_arena_try_alloc_at(mi_arena_t* arena, size_t ar
|
||||||
|
|
||||||
// allocate in a speficic arena
|
// allocate in a speficic arena
|
||||||
static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_node, int numa_node, size_t size, size_t alignment,
|
static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_node, int numa_node, size_t size, size_t alignment,
|
||||||
bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld )
|
bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid )
|
||||||
{
|
{
|
||||||
MI_UNUSED_RELEASE(alignment);
|
MI_UNUSED_RELEASE(alignment);
|
||||||
mi_assert(alignment <= MI_SEGMENT_ALIGN);
|
mi_assert(alignment <= MI_SEGMENT_ALIGN);
|
||||||
|
@ -311,7 +311,7 @@ static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_no
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to allocate
|
// try to allocate
|
||||||
void* p = mi_arena_try_alloc_at(arena, arena_index, bcount, commit, memid, tld);
|
void* p = mi_arena_try_alloc_at(arena, arena_index, bcount, commit, memid);
|
||||||
mi_assert_internal(p == NULL || _mi_is_aligned(p, alignment));
|
mi_assert_internal(p == NULL || _mi_is_aligned(p, alignment));
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -320,7 +320,7 @@ static void* mi_arena_try_alloc_at_id(mi_arena_id_t arena_id, bool match_numa_no
|
||||||
// allocate from an arena with fallback to the OS
|
// allocate from an arena with fallback to the OS
|
||||||
static mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, size_t alignment,
|
static mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, size_t alignment,
|
||||||
bool commit, bool allow_large,
|
bool commit, bool allow_large,
|
||||||
mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld )
|
mi_arena_id_t req_arena_id, mi_memid_t* memid )
|
||||||
{
|
{
|
||||||
MI_UNUSED(alignment);
|
MI_UNUSED(alignment);
|
||||||
mi_assert_internal(alignment <= MI_SEGMENT_ALIGN);
|
mi_assert_internal(alignment <= MI_SEGMENT_ALIGN);
|
||||||
|
@ -330,21 +330,21 @@ static mi_decl_noinline void* mi_arena_try_alloc(int numa_node, size_t size, siz
|
||||||
if (req_arena_id != _mi_arena_id_none()) {
|
if (req_arena_id != _mi_arena_id_none()) {
|
||||||
// try a specific arena if requested
|
// try a specific arena if requested
|
||||||
if (mi_arena_id_index(req_arena_id) < max_arena) {
|
if (mi_arena_id_index(req_arena_id) < max_arena) {
|
||||||
void* p = mi_arena_try_alloc_at_id(req_arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
|
void* p = mi_arena_try_alloc_at_id(req_arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// try numa affine allocation
|
// try numa affine allocation
|
||||||
for (size_t i = 0; i < max_arena; i++) {
|
for (size_t i = 0; i < max_arena; i++) {
|
||||||
void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
|
void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
// try from another numa node instead..
|
// try from another numa node instead..
|
||||||
if (numa_node >= 0) { // if numa_node was < 0 (no specific affinity requested), all arena's have been tried already
|
if (numa_node >= 0) { // if numa_node was < 0 (no specific affinity requested), all arena's have been tried already
|
||||||
for (size_t i = 0; i < max_arena; i++) {
|
for (size_t i = 0; i < max_arena; i++) {
|
||||||
void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), false /* only proceed if not numa local */, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
|
void* p = mi_arena_try_alloc_at_id(mi_arena_id_create(i), false /* only proceed if not numa local */, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -389,18 +389,18 @@ static bool mi_arena_reserve(size_t req_size, bool allow_large, mi_arena_id_t re
|
||||||
|
|
||||||
|
|
||||||
void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large,
|
void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset, bool commit, bool allow_large,
|
||||||
mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld)
|
mi_arena_id_t req_arena_id, mi_memid_t* memid)
|
||||||
{
|
{
|
||||||
mi_assert_internal(memid != NULL && tld != NULL);
|
mi_assert_internal(memid != NULL);
|
||||||
mi_assert_internal(size > 0);
|
mi_assert_internal(size > 0);
|
||||||
*memid = _mi_memid_none();
|
*memid = _mi_memid_none();
|
||||||
|
|
||||||
const int numa_node = _mi_os_numa_node(tld); // current numa node
|
const int numa_node = _mi_os_numa_node(); // current numa node
|
||||||
|
|
||||||
// try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data)
|
// try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data)
|
||||||
if (!mi_option_is_enabled(mi_option_disallow_arena_alloc) || req_arena_id != _mi_arena_id_none()) { // is arena allocation allowed?
|
if (!mi_option_is_enabled(mi_option_disallow_arena_alloc) || req_arena_id != _mi_arena_id_none()) { // is arena allocation allowed?
|
||||||
if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) {
|
if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) {
|
||||||
void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
|
void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid);
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
|
|
||||||
// otherwise, try to first eagerly reserve a new arena
|
// otherwise, try to first eagerly reserve a new arena
|
||||||
|
@ -409,7 +409,7 @@ void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset
|
||||||
if (mi_arena_reserve(size, allow_large, req_arena_id, &arena_id)) {
|
if (mi_arena_reserve(size, allow_large, req_arena_id, &arena_id)) {
|
||||||
// and try allocate in there
|
// and try allocate in there
|
||||||
mi_assert_internal(req_arena_id == _mi_arena_id_none());
|
mi_assert_internal(req_arena_id == _mi_arena_id_none());
|
||||||
p = mi_arena_try_alloc_at_id(arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
|
p = mi_arena_try_alloc_at_id(arena_id, true, numa_node, size, alignment, commit, allow_large, req_arena_id, memid);
|
||||||
if (p != NULL) return p;
|
if (p != NULL) return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -424,16 +424,16 @@ void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset
|
||||||
|
|
||||||
// finally, fall back to the OS
|
// finally, fall back to the OS
|
||||||
if (align_offset > 0) {
|
if (align_offset > 0) {
|
||||||
return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid, tld->stats);
|
return _mi_os_alloc_aligned_at_offset(size, alignment, align_offset, commit, allow_large, memid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld->stats);
|
return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld)
|
void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid)
|
||||||
{
|
{
|
||||||
return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, 0, commit, allow_large, req_arena_id, memid, tld);
|
return _mi_arena_alloc_aligned(size, MI_ARENA_BLOCK_SIZE, 0, commit, allow_large, req_arena_id, memid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -459,7 +459,7 @@ static long mi_arena_purge_delay(void) {
|
||||||
|
|
||||||
// reset or decommit in an arena and update the committed/decommit bitmaps
|
// reset or decommit in an arena and update the committed/decommit bitmaps
|
||||||
// assumes we own the area (i.e. blocks_in_use is claimed by us)
|
// assumes we own the area (i.e. blocks_in_use is claimed by us)
|
||||||
static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) {
|
static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks) {
|
||||||
mi_assert_internal(arena->blocks_committed != NULL);
|
mi_assert_internal(arena->blocks_committed != NULL);
|
||||||
mi_assert_internal(arena->blocks_purge != NULL);
|
mi_assert_internal(arena->blocks_purge != NULL);
|
||||||
mi_assert_internal(!arena->memid.is_pinned);
|
mi_assert_internal(!arena->memid.is_pinned);
|
||||||
|
@ -468,7 +468,7 @@ static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks,
|
||||||
bool needs_recommit;
|
bool needs_recommit;
|
||||||
if (_mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx)) {
|
if (_mi_bitmap_is_claimed_across(arena->blocks_committed, arena->field_count, blocks, bitmap_idx)) {
|
||||||
// all blocks are committed, we can purge freely
|
// all blocks are committed, we can purge freely
|
||||||
needs_recommit = _mi_os_purge(p, size, stats);
|
needs_recommit = _mi_os_purge(p, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// some blocks are not committed -- this can happen when a partially committed block is freed
|
// some blocks are not committed -- this can happen when a partially committed block is freed
|
||||||
|
@ -476,7 +476,7 @@ static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks,
|
||||||
// we need to ensure we do not try to reset (as that may be invalid for uncommitted memory),
|
// we need to ensure we do not try to reset (as that may be invalid for uncommitted memory),
|
||||||
// and also undo the decommit stats (as it was already adjusted)
|
// and also undo the decommit stats (as it was already adjusted)
|
||||||
mi_assert_internal(mi_option_is_enabled(mi_option_purge_decommits));
|
mi_assert_internal(mi_option_is_enabled(mi_option_purge_decommits));
|
||||||
needs_recommit = _mi_os_purge_ex(p, size, false /* allow reset? */, stats);
|
needs_recommit = _mi_os_purge_ex(p, size, false /* allow reset? */);
|
||||||
if (needs_recommit) { _mi_stat_increase(&_mi_stats_main.committed, size); }
|
if (needs_recommit) { _mi_stat_increase(&_mi_stats_main.committed, size); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -490,14 +490,14 @@ static void mi_arena_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks,
|
||||||
|
|
||||||
// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls.
|
// Schedule a purge. This is usually delayed to avoid repeated decommit/commit calls.
|
||||||
// Note: assumes we (still) own the area as we may purge immediately
|
// Note: assumes we (still) own the area as we may purge immediately
|
||||||
static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks, mi_stats_t* stats) {
|
static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t blocks) {
|
||||||
mi_assert_internal(arena->blocks_purge != NULL);
|
mi_assert_internal(arena->blocks_purge != NULL);
|
||||||
const long delay = mi_arena_purge_delay();
|
const long delay = mi_arena_purge_delay();
|
||||||
if (delay < 0) return; // is purging allowed at all?
|
if (delay < 0) return; // is purging allowed at all?
|
||||||
|
|
||||||
if (_mi_preloading() || delay == 0) {
|
if (_mi_preloading() || delay == 0) {
|
||||||
// decommit directly
|
// decommit directly
|
||||||
mi_arena_purge(arena, bitmap_idx, blocks, stats);
|
mi_arena_purge(arena, bitmap_idx, blocks);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// schedule decommit
|
// schedule decommit
|
||||||
|
@ -515,7 +515,7 @@ static void mi_arena_schedule_purge(mi_arena_t* arena, size_t bitmap_idx, size_t
|
||||||
// purge a range of blocks
|
// purge a range of blocks
|
||||||
// return true if the full range was purged.
|
// return true if the full range was purged.
|
||||||
// assumes we own the area (i.e. blocks_in_use is claimed by us)
|
// assumes we own the area (i.e. blocks_in_use is claimed by us)
|
||||||
static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx, size_t bitlen, size_t purge, mi_stats_t* stats) {
|
static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx, size_t bitlen, size_t purge) {
|
||||||
const size_t endidx = startidx + bitlen;
|
const size_t endidx = startidx + bitlen;
|
||||||
size_t bitidx = startidx;
|
size_t bitidx = startidx;
|
||||||
bool all_purged = false;
|
bool all_purged = false;
|
||||||
|
@ -528,7 +528,7 @@ static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx,
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
// found range to be purged
|
// found range to be purged
|
||||||
const mi_bitmap_index_t range_idx = mi_bitmap_index_create(idx, bitidx);
|
const mi_bitmap_index_t range_idx = mi_bitmap_index_create(idx, bitidx);
|
||||||
mi_arena_purge(arena, range_idx, count, stats);
|
mi_arena_purge(arena, range_idx, count);
|
||||||
if (count == bitlen) {
|
if (count == bitlen) {
|
||||||
all_purged = true;
|
all_purged = true;
|
||||||
}
|
}
|
||||||
|
@ -539,7 +539,7 @@ static bool mi_arena_purge_range(mi_arena_t* arena, size_t idx, size_t startidx,
|
||||||
}
|
}
|
||||||
|
|
||||||
// returns true if anything was purged
|
// returns true if anything was purged
|
||||||
static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi_stats_t* stats)
|
static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force)
|
||||||
{
|
{
|
||||||
if (arena->memid.is_pinned || arena->blocks_purge == NULL) return false;
|
if (arena->memid.is_pinned || arena->blocks_purge == NULL) return false;
|
||||||
mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire);
|
mi_msecs_t expire = mi_atomic_loadi64_relaxed(&arena->purge_expire);
|
||||||
|
@ -575,7 +575,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi
|
||||||
if (bitlen > 0) {
|
if (bitlen > 0) {
|
||||||
// read purge again now that we have the in_use bits
|
// read purge again now that we have the in_use bits
|
||||||
purge = mi_atomic_load_acquire(&arena->blocks_purge[i]);
|
purge = mi_atomic_load_acquire(&arena->blocks_purge[i]);
|
||||||
if (!mi_arena_purge_range(arena, i, bitidx, bitlen, purge, stats)) {
|
if (!mi_arena_purge_range(arena, i, bitidx, bitlen, purge)) {
|
||||||
full_purge = false;
|
full_purge = false;
|
||||||
}
|
}
|
||||||
any_purged = true;
|
any_purged = true;
|
||||||
|
@ -595,7 +595,7 @@ static bool mi_arena_try_purge(mi_arena_t* arena, mi_msecs_t now, bool force, mi
|
||||||
return any_purged;
|
return any_purged;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats ) {
|
static void mi_arenas_try_purge( bool force, bool visit_all ) {
|
||||||
if (_mi_preloading() || mi_arena_purge_delay() <= 0) return; // nothing will be scheduled
|
if (_mi_preloading() || mi_arena_purge_delay() <= 0) return; // nothing will be scheduled
|
||||||
|
|
||||||
const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count);
|
const size_t max_arena = mi_atomic_load_acquire(&mi_arena_count);
|
||||||
|
@ -610,7 +610,7 @@ static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats )
|
||||||
for (size_t i = 0; i < max_arena; i++) {
|
for (size_t i = 0; i < max_arena; i++) {
|
||||||
mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]);
|
mi_arena_t* arena = mi_atomic_load_ptr_acquire(mi_arena_t, &mi_arenas[i]);
|
||||||
if (arena != NULL) {
|
if (arena != NULL) {
|
||||||
if (mi_arena_try_purge(arena, now, force, stats)) {
|
if (mi_arena_try_purge(arena, now, force)) {
|
||||||
if (max_purge_count <= 1) break;
|
if (max_purge_count <= 1) break;
|
||||||
max_purge_count--;
|
max_purge_count--;
|
||||||
}
|
}
|
||||||
|
@ -624,8 +624,8 @@ static void mi_arenas_try_purge( bool force, bool visit_all, mi_stats_t* stats )
|
||||||
Arena free
|
Arena free
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memid, mi_stats_t* stats) {
|
void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memid) {
|
||||||
mi_assert_internal(size > 0 && stats != NULL);
|
mi_assert_internal(size > 0);
|
||||||
mi_assert_internal(committed_size <= size);
|
mi_assert_internal(committed_size <= size);
|
||||||
if (p==NULL) return;
|
if (p==NULL) return;
|
||||||
if (size==0) return;
|
if (size==0) return;
|
||||||
|
@ -640,7 +640,7 @@ void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memi
|
||||||
// if partially committed, adjust the committed stats (as `_mi_os_free` will increase decommit by the full size)
|
// if partially committed, adjust the committed stats (as `_mi_os_free` will increase decommit by the full size)
|
||||||
_mi_stat_decrease(&_mi_stats_main.committed, committed_size);
|
_mi_stat_decrease(&_mi_stats_main.committed, committed_size);
|
||||||
}
|
}
|
||||||
_mi_os_free(p, size, memid, stats);
|
_mi_os_free(p, size, memid);
|
||||||
}
|
}
|
||||||
else if (memid.memkind == MI_MEM_ARENA) {
|
else if (memid.memkind == MI_MEM_ARENA) {
|
||||||
// allocated in an arena
|
// allocated in an arena
|
||||||
|
@ -685,7 +685,7 @@ void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memi
|
||||||
// works (as we should never reset decommitted parts).
|
// works (as we should never reset decommitted parts).
|
||||||
}
|
}
|
||||||
// (delay) purge the entire range
|
// (delay) purge the entire range
|
||||||
mi_arena_schedule_purge(arena, bitmap_idx, blocks, stats);
|
mi_arena_schedule_purge(arena, bitmap_idx, blocks);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and make it available to others again
|
// and make it available to others again
|
||||||
|
@ -701,7 +701,7 @@ void _mi_arena_free(void* p, size_t size, size_t committed_size, mi_memid_t memi
|
||||||
}
|
}
|
||||||
|
|
||||||
// purge expired decommits
|
// purge expired decommits
|
||||||
mi_arenas_try_purge(false, false, stats);
|
mi_arenas_try_purge(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`
|
// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`
|
||||||
|
@ -715,7 +715,7 @@ static void mi_arenas_unsafe_destroy(void) {
|
||||||
mi_lock_done(&arena->abandoned_visit_lock);
|
mi_lock_done(&arena->abandoned_visit_lock);
|
||||||
if (arena->start != NULL && mi_memkind_is_os(arena->memid.memkind)) {
|
if (arena->start != NULL && mi_memkind_is_os(arena->memid.memkind)) {
|
||||||
mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], NULL);
|
mi_atomic_store_ptr_release(mi_arena_t, &mi_arenas[i], NULL);
|
||||||
_mi_os_free(arena->start, mi_arena_size(arena), arena->memid, &_mi_stats_main);
|
_mi_os_free(arena->start, mi_arena_size(arena), arena->memid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
new_max_arena = i;
|
new_max_arena = i;
|
||||||
|
@ -730,15 +730,15 @@ static void mi_arenas_unsafe_destroy(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired
|
// Purge the arenas; if `force_purge` is true, amenable parts are purged even if not yet expired
|
||||||
void _mi_arenas_collect(bool force_purge, mi_stats_t* stats) {
|
void _mi_arenas_collect(bool force_purge) {
|
||||||
mi_arenas_try_purge(force_purge, force_purge /* visit all? */, stats);
|
mi_arenas_try_purge(force_purge, force_purge /* visit all? */);
|
||||||
}
|
}
|
||||||
|
|
||||||
// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`
|
// destroy owned arenas; this is unsafe and should only be done using `mi_option_destroy_on_exit`
|
||||||
// for dynamic libraries that are unloaded and need to release all their allocated memory.
|
// for dynamic libraries that are unloaded and need to release all their allocated memory.
|
||||||
void _mi_arena_unsafe_destroy_all(mi_stats_t* stats) {
|
void _mi_arena_unsafe_destroy_all(void) {
|
||||||
mi_arenas_unsafe_destroy();
|
mi_arenas_unsafe_destroy();
|
||||||
_mi_arenas_collect(true /* force purge */, stats); // purge non-owned arenas
|
_mi_arenas_collect(true /* force purge */); // purge non-owned arenas
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is a pointer inside any of our arenas?
|
// Is a pointer inside any of our arenas?
|
||||||
|
@ -842,11 +842,11 @@ int mi_reserve_os_memory_ex(size_t size, bool commit, bool allow_large, bool exc
|
||||||
if (arena_id != NULL) *arena_id = _mi_arena_id_none();
|
if (arena_id != NULL) *arena_id = _mi_arena_id_none();
|
||||||
size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block
|
size = _mi_align_up(size, MI_ARENA_BLOCK_SIZE); // at least one block
|
||||||
mi_memid_t memid;
|
mi_memid_t memid;
|
||||||
void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, allow_large, &memid, &_mi_stats_main);
|
void* start = _mi_os_alloc_aligned(size, MI_SEGMENT_ALIGN, commit, allow_large, &memid);
|
||||||
if (start == NULL) return ENOMEM;
|
if (start == NULL) return ENOMEM;
|
||||||
const bool is_large = memid.is_pinned; // todo: use separate is_large field?
|
const bool is_large = memid.is_pinned; // todo: use separate is_large field?
|
||||||
if (!mi_manage_os_memory_ex2(start, size, is_large, -1 /* numa node */, exclusive, memid, arena_id)) {
|
if (!mi_manage_os_memory_ex2(start, size, is_large, -1 /* numa node */, exclusive, memid, arena_id)) {
|
||||||
_mi_os_free_ex(start, size, commit, memid, &_mi_stats_main);
|
_mi_os_free_ex(start, size, commit, memid);
|
||||||
_mi_verbose_message("failed to reserve %zu KiB memory\n", _mi_divide_up(size, 1024));
|
_mi_verbose_message("failed to reserve %zu KiB memory\n", _mi_divide_up(size, 1024));
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
|
@ -942,7 +942,7 @@ int mi_reserve_huge_os_pages_at_ex(size_t pages, int numa_node, size_t timeout_m
|
||||||
_mi_verbose_message("numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\n", numa_node, pages_reserved, pages);
|
_mi_verbose_message("numa node %i: reserved %zu GiB huge pages (of the %zu GiB requested)\n", numa_node, pages_reserved, pages);
|
||||||
|
|
||||||
if (!mi_manage_os_memory_ex2(p, hsize, true, numa_node, exclusive, memid, arena_id)) {
|
if (!mi_manage_os_memory_ex2(p, hsize, true, numa_node, exclusive, memid, arena_id)) {
|
||||||
_mi_os_free(p, hsize, memid, &_mi_stats_main);
|
_mi_os_free(p, hsize, memid);
|
||||||
return ENOMEM;
|
return ENOMEM;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
|
12
src/bitmap.c
12
src/bitmap.c
|
@ -200,7 +200,7 @@ bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t
|
||||||
// Try to atomically claim a sequence of `count` bits starting from the field
|
// Try to atomically claim a sequence of `count` bits starting from the field
|
||||||
// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success.
|
// at `idx` in `bitmap` and crossing into subsequent fields. Returns `true` on success.
|
||||||
// Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`)
|
// Only needs to consider crossing into the next fields (see `mi_bitmap_try_find_from_claim_across`)
|
||||||
static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx, mi_stats_t* stats)
|
static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bitmap_fields, size_t idx, const size_t count, const size_t retries, mi_bitmap_index_t* bitmap_idx)
|
||||||
{
|
{
|
||||||
mi_assert_internal(bitmap_idx != NULL);
|
mi_assert_internal(bitmap_idx != NULL);
|
||||||
|
|
||||||
|
@ -260,7 +260,7 @@ static bool mi_bitmap_try_find_claim_field_across(mi_bitmap_t bitmap, size_t bit
|
||||||
} while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
|
} while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
|
||||||
|
|
||||||
// claimed!
|
// claimed!
|
||||||
mi_stat_counter_increase(stats->arena_crossover_count,1);
|
mi_stat_counter_increase(_mi_stats_main.arena_crossover_count,1);
|
||||||
*bitmap_idx = mi_bitmap_index_create(idx, initial_idx);
|
*bitmap_idx = mi_bitmap_index_create(idx, initial_idx);
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
@ -280,10 +280,10 @@ rollback:
|
||||||
newmap = (map & ~initial_mask);
|
newmap = (map & ~initial_mask);
|
||||||
} while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
|
} while (!mi_atomic_cas_strong_acq_rel(field, &map, newmap));
|
||||||
}
|
}
|
||||||
mi_stat_counter_increase(stats->arena_rollback_count,1);
|
mi_stat_counter_increase(_mi_stats_main.arena_rollback_count,1);
|
||||||
// retry? (we make a recursive call instead of goto to be able to use const declarations)
|
// retry? (we make a recursive call instead of goto to be able to use const declarations)
|
||||||
if (retries <= 2) {
|
if (retries <= 2) {
|
||||||
return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx, stats);
|
return mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, retries+1, bitmap_idx);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -293,7 +293,7 @@ rollback:
|
||||||
|
|
||||||
// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
|
// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
|
||||||
// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
|
// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
|
||||||
bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx, mi_stats_t* stats) {
|
bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx) {
|
||||||
mi_assert_internal(count > 0);
|
mi_assert_internal(count > 0);
|
||||||
if (count <= 2) {
|
if (count <= 2) {
|
||||||
// we don't bother with crossover fields for small counts
|
// we don't bother with crossover fields for small counts
|
||||||
|
@ -313,7 +313,7 @@ bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitm
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
// if that fails, then try to claim across fields
|
// if that fails, then try to claim across fields
|
||||||
if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx, stats)) {
|
if (mi_bitmap_try_find_claim_field_across(bitmap, bitmap_fields, idx, count, 0, bitmap_idx)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,7 +103,7 @@ bool _mi_bitmap_is_any_claimed(mi_bitmap_t bitmap, size_t bitmap_fields, size_t
|
||||||
|
|
||||||
// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
|
// Find `count` bits of zeros and set them to 1 atomically; returns `true` on success.
|
||||||
// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
|
// Starts at idx, and wraps around to search in all `bitmap_fields` fields.
|
||||||
bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx, mi_stats_t* stats);
|
bool _mi_bitmap_try_find_from_claim_across(mi_bitmap_t bitmap, const size_t bitmap_fields, const size_t start_field_idx, const size_t count, mi_bitmap_index_t* bitmap_idx);
|
||||||
|
|
||||||
// Set `count` bits at `bitmap_idx` to 0 atomically
|
// Set `count` bits at `bitmap_idx` to 0 atomically
|
||||||
// Returns `true` if all `count` bits were 1 previously.
|
// Returns `true` if all `count` bits were 1 previously.
|
||||||
|
|
15
src/heap.c
15
src/heap.c
|
@ -98,7 +98,7 @@ static bool mi_heap_page_collect(mi_heap_t* heap, mi_page_queue_t* pq, mi_page_t
|
||||||
if (collect == MI_FORCE) {
|
if (collect == MI_FORCE) {
|
||||||
// note: call before a potential `_mi_page_free` as the segment may be freed if this was the last used page in that segment.
|
// note: call before a potential `_mi_page_free` as the segment may be freed if this was the last used page in that segment.
|
||||||
mi_segment_t* segment = _mi_page_segment(page);
|
mi_segment_t* segment = _mi_page_segment(page);
|
||||||
_mi_segment_collect(segment, true /* force? */, &heap->tld->segments);
|
_mi_segment_collect(segment, true /* force? */);
|
||||||
}
|
}
|
||||||
if (mi_page_all_free(page)) {
|
if (mi_page_all_free(page)) {
|
||||||
// no more used blocks, free the page.
|
// no more used blocks, free the page.
|
||||||
|
@ -173,7 +173,7 @@ static void mi_heap_collect_ex(mi_heap_t* heap, mi_collect_t collect)
|
||||||
}
|
}
|
||||||
|
|
||||||
// collect arenas (this is program wide so don't force purges on abandonment of threads)
|
// collect arenas (this is program wide so don't force purges on abandonment of threads)
|
||||||
_mi_arenas_collect(collect == MI_FORCE /* force purge? */, &heap->tld->stats);
|
_mi_arenas_collect(collect == MI_FORCE /* force purge? */);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_heap_collect_abandon(mi_heap_t* heap) {
|
void _mi_heap_collect_abandon(mi_heap_t* heap) {
|
||||||
|
@ -458,6 +458,12 @@ static void mi_heap_absorb(mi_heap_t* heap, mi_heap_t* from) {
|
||||||
mi_heap_reset_pages(from);
|
mi_heap_reset_pages(from);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// are two heaps compatible with respect to heap-tag, exclusive arena etc.
|
||||||
|
static bool mi_heaps_are_compatible(mi_heap_t* heap1, mi_heap_t* heap2) {
|
||||||
|
return (heap1->tag == heap2->tag && // store same kind of objects
|
||||||
|
heap1->arena_id == heap2->arena_id); // same arena preference
|
||||||
|
}
|
||||||
|
|
||||||
// Safe delete a heap without freeing any still allocated blocks in that heap.
|
// Safe delete a heap without freeing any still allocated blocks in that heap.
|
||||||
void mi_heap_delete(mi_heap_t* heap)
|
void mi_heap_delete(mi_heap_t* heap)
|
||||||
{
|
{
|
||||||
|
@ -466,9 +472,10 @@ void mi_heap_delete(mi_heap_t* heap)
|
||||||
mi_assert_expensive(mi_heap_is_valid(heap));
|
mi_assert_expensive(mi_heap_is_valid(heap));
|
||||||
if (heap==NULL || !mi_heap_is_initialized(heap)) return;
|
if (heap==NULL || !mi_heap_is_initialized(heap)) return;
|
||||||
|
|
||||||
if (!mi_heap_is_backing(heap)) {
|
mi_heap_t* bheap = heap->tld->heap_backing;
|
||||||
|
if (bheap != heap && mi_heaps_are_compatible(bheap,heap)) {
|
||||||
// transfer still used pages to the backing heap
|
// transfer still used pages to the backing heap
|
||||||
mi_heap_absorb(heap->tld->heap_backing, heap);
|
mi_heap_absorb(bheap, heap);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// the backing heap abandons its pages
|
// the backing heap abandons its pages
|
||||||
|
|
19
src/init.c
19
src/init.c
|
@ -135,14 +135,12 @@ mi_decl_cache_align const mi_heap_t _mi_heap_empty = {
|
||||||
static mi_decl_cache_align mi_subproc_t mi_subproc_default;
|
static mi_decl_cache_align mi_subproc_t mi_subproc_default;
|
||||||
|
|
||||||
#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))
|
#define tld_empty_stats ((mi_stats_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,stats)))
|
||||||
#define tld_empty_os ((mi_os_tld_t*)((uint8_t*)&tld_empty + offsetof(mi_tld_t,os)))
|
|
||||||
|
|
||||||
mi_decl_cache_align static const mi_tld_t tld_empty = {
|
mi_decl_cache_align static const mi_tld_t tld_empty = {
|
||||||
0,
|
0,
|
||||||
false,
|
false,
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, tld_empty_stats, tld_empty_os }, // segments
|
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, tld_empty_stats }, // segments
|
||||||
{ 0, tld_empty_stats }, // os
|
|
||||||
{ MI_STATS_NULL } // stats
|
{ MI_STATS_NULL } // stats
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -158,8 +156,7 @@ extern mi_heap_t _mi_heap_main;
|
||||||
static mi_decl_cache_align mi_tld_t tld_main = {
|
static mi_decl_cache_align mi_tld_t tld_main = {
|
||||||
0, false,
|
0, false,
|
||||||
&_mi_heap_main, & _mi_heap_main,
|
&_mi_heap_main, & _mi_heap_main,
|
||||||
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, &tld_main.stats, &tld_main.os }, // segments
|
{ MI_SEGMENT_SPAN_QUEUES_EMPTY, 0, 0, 0, 0, 0, &mi_subproc_default, &tld_main.stats }, // segments
|
||||||
{ 0, &tld_main.stats }, // os
|
|
||||||
{ MI_STATS_NULL } // stats
|
{ MI_STATS_NULL } // stats
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -341,10 +338,10 @@ static mi_thread_data_t* mi_thread_data_zalloc(void) {
|
||||||
// if that fails, allocate as meta data
|
// if that fails, allocate as meta data
|
||||||
if (td == NULL) {
|
if (td == NULL) {
|
||||||
mi_memid_t memid;
|
mi_memid_t memid;
|
||||||
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main);
|
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
|
||||||
if (td == NULL) {
|
if (td == NULL) {
|
||||||
// if this fails, try once more. (issue #257)
|
// if this fails, try once more. (issue #257)
|
||||||
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid, &_mi_stats_main);
|
td = (mi_thread_data_t*)_mi_os_alloc(sizeof(mi_thread_data_t), &memid);
|
||||||
if (td == NULL) {
|
if (td == NULL) {
|
||||||
// really out of memory
|
// really out of memory
|
||||||
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
|
_mi_error_message(ENOMEM, "unable to allocate thread local heap metadata (%zu bytes)\n", sizeof(mi_thread_data_t));
|
||||||
|
@ -374,7 +371,7 @@ static void mi_thread_data_free( mi_thread_data_t* tdfree ) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// if that fails, just free it directly
|
// if that fails, just free it directly
|
||||||
_mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid, &_mi_stats_main);
|
_mi_os_free(tdfree, sizeof(mi_thread_data_t), tdfree->memid);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_thread_data_collect(void) {
|
void _mi_thread_data_collect(void) {
|
||||||
|
@ -384,7 +381,7 @@ void _mi_thread_data_collect(void) {
|
||||||
if (td != NULL) {
|
if (td != NULL) {
|
||||||
td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
|
td = mi_atomic_exchange_ptr_acq_rel(mi_thread_data_t, &td_cache[i], NULL);
|
||||||
if (td != NULL) {
|
if (td != NULL) {
|
||||||
_mi_os_free(td, sizeof(mi_thread_data_t), td->memid, &_mi_stats_main);
|
_mi_os_free(td, sizeof(mi_thread_data_t), td->memid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -421,8 +418,6 @@ void _mi_tld_init(mi_tld_t* tld, mi_heap_t* bheap) {
|
||||||
tld->heaps = NULL;
|
tld->heaps = NULL;
|
||||||
tld->segments.subproc = &mi_subproc_default;
|
tld->segments.subproc = &mi_subproc_default;
|
||||||
tld->segments.stats = &tld->stats;
|
tld->segments.stats = &tld->stats;
|
||||||
tld->segments.os = &tld->os;
|
|
||||||
tld->os.stats = &tld->stats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free the thread local default heap (called from `mi_thread_done`)
|
// Free the thread local default heap (called from `mi_thread_done`)
|
||||||
|
@ -709,7 +704,7 @@ void mi_cdecl _mi_process_done(void) {
|
||||||
if (mi_option_is_enabled(mi_option_destroy_on_exit)) {
|
if (mi_option_is_enabled(mi_option_destroy_on_exit)) {
|
||||||
mi_collect(true /* force */);
|
mi_collect(true /* force */);
|
||||||
_mi_heap_unsafe_destroy_all(); // forcefully release all memory held by all heaps (of this thread only!)
|
_mi_heap_unsafe_destroy_all(); // forcefully release all memory held by all heaps (of this thread only!)
|
||||||
_mi_arena_unsafe_destroy_all(& _mi_heap_main_get()->tld->stats);
|
_mi_arena_unsafe_destroy_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
|
if (mi_option_is_enabled(mi_option_show_stats) || mi_option_is_enabled(mi_option_verbose)) {
|
||||||
|
|
130
src/os.c
130
src/os.c
|
@ -9,6 +9,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
#include "mimalloc/atomic.h"
|
#include "mimalloc/atomic.h"
|
||||||
#include "mimalloc/prim.h"
|
#include "mimalloc/prim.h"
|
||||||
|
|
||||||
|
#define os_stats (&_mi_stats_main)
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
Initialization.
|
Initialization.
|
||||||
|
@ -85,8 +86,8 @@ void _mi_os_init(void) {
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
Util
|
Util
|
||||||
-------------------------------------------------------------- */
|
-------------------------------------------------------------- */
|
||||||
bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* stats);
|
bool _mi_os_decommit(void* addr, size_t size);
|
||||||
bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats);
|
bool _mi_os_commit(void* addr, size_t size, bool* is_zero);
|
||||||
|
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
|
@ -146,23 +147,20 @@ void* _mi_os_get_aligned_hint(size_t try_alignment, size_t size) {
|
||||||
Free memory
|
Free memory
|
||||||
-------------------------------------------------------------- */
|
-------------------------------------------------------------- */
|
||||||
|
|
||||||
static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats);
|
static void mi_os_free_huge_os_pages(void* p, size_t size);
|
||||||
|
|
||||||
static void mi_os_prim_free(void* addr, size_t size, bool still_committed, mi_stats_t* tld_stats) {
|
static void mi_os_prim_free(void* addr, size_t size, bool still_committed) {
|
||||||
MI_UNUSED(tld_stats);
|
|
||||||
mi_stats_t* stats = &_mi_stats_main;
|
|
||||||
mi_assert_internal((size % _mi_os_page_size()) == 0);
|
mi_assert_internal((size % _mi_os_page_size()) == 0);
|
||||||
if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr)
|
if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr)
|
||||||
int err = _mi_prim_free(addr, size);
|
int err = _mi_prim_free(addr, size);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
_mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr);
|
_mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr);
|
||||||
}
|
}
|
||||||
if (still_committed) { _mi_stat_decrease(&stats->committed, size); }
|
if (still_committed) { _mi_stat_decrease(&os_stats->committed, size); }
|
||||||
_mi_stat_decrease(&stats->reserved, size);
|
_mi_stat_decrease(&os_stats->reserved, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid, mi_stats_t* stats) {
|
void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t memid) {
|
||||||
if (stats == NULL) stats = &_mi_stats_main;
|
|
||||||
if (mi_memkind_is_os(memid.memkind)) {
|
if (mi_memkind_is_os(memid.memkind)) {
|
||||||
size_t csize = _mi_os_good_alloc_size(size);
|
size_t csize = _mi_os_good_alloc_size(size);
|
||||||
void* base = addr;
|
void* base = addr;
|
||||||
|
@ -176,10 +174,10 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
|
||||||
// free it
|
// free it
|
||||||
if (memid.memkind == MI_MEM_OS_HUGE) {
|
if (memid.memkind == MI_MEM_OS_HUGE) {
|
||||||
mi_assert(memid.is_pinned);
|
mi_assert(memid.is_pinned);
|
||||||
mi_os_free_huge_os_pages(base, csize, stats);
|
mi_os_free_huge_os_pages(base, csize);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
mi_os_prim_free(base, csize, still_committed, stats);
|
mi_os_prim_free(base, csize, still_committed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -188,9 +186,8 @@ void _mi_os_free_ex(void* addr, size_t size, bool still_committed, mi_memid_t me
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats) {
|
void _mi_os_free(void* p, size_t size, mi_memid_t memid) {
|
||||||
if (stats == NULL) stats = &_mi_stats_main;
|
_mi_os_free_ex(p, size, true, memid);
|
||||||
_mi_os_free_ex(p, size, true, memid, stats);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -200,7 +197,7 @@ void _mi_os_free(void* p, size_t size, mi_memid_t memid, mi_stats_t* stats) {
|
||||||
|
|
||||||
// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.
|
// Note: the `try_alignment` is just a hint and the returned pointer is not guaranteed to be aligned.
|
||||||
// Also `hint_addr` is a hint and may be ignored.
|
// Also `hint_addr` is a hint and may be ignored.
|
||||||
static void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, mi_stats_t* tld_stats) {
|
static void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {
|
||||||
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
|
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
|
||||||
mi_assert_internal(is_zero != NULL);
|
mi_assert_internal(is_zero != NULL);
|
||||||
mi_assert_internal(is_large != NULL);
|
mi_assert_internal(is_large != NULL);
|
||||||
|
@ -214,13 +211,13 @@ static void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignm
|
||||||
_mi_warning_message("unable to allocate OS memory (error: %d (0x%x), addr: %p, size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\n", err, err, hint_addr, size, try_alignment, commit, allow_large);
|
_mi_warning_message("unable to allocate OS memory (error: %d (0x%x), addr: %p, size: 0x%zx bytes, align: 0x%zx, commit: %d, allow large: %d)\n", err, err, hint_addr, size, try_alignment, commit, allow_large);
|
||||||
}
|
}
|
||||||
|
|
||||||
MI_UNUSED(tld_stats);
|
|
||||||
mi_stats_t* stats = &_mi_stats_main;
|
|
||||||
mi_stat_counter_increase(stats->mmap_calls, 1);
|
mi_stat_counter_increase(os_stats->mmap_calls, 1);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
_mi_stat_increase(&stats->reserved, size);
|
_mi_stat_increase(&os_stats->reserved, size);
|
||||||
if (commit) {
|
if (commit) {
|
||||||
_mi_stat_increase(&stats->committed, size);
|
_mi_stat_increase(&os_stats->committed, size);
|
||||||
// seems needed for asan (or `mimalloc-test-api` fails)
|
// seems needed for asan (or `mimalloc-test-api` fails)
|
||||||
#ifdef MI_TRACK_ASAN
|
#ifdef MI_TRACK_ASAN
|
||||||
if (*is_zero) { mi_track_mem_defined(p,size); }
|
if (*is_zero) { mi_track_mem_defined(p,size); }
|
||||||
|
@ -231,14 +228,14 @@ static void* mi_os_prim_alloc_at(void* hint_addr, size_t size, size_t try_alignm
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, mi_stats_t* tld_stats) {
|
static void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero) {
|
||||||
return mi_os_prim_alloc_at(NULL, size, try_alignment, commit, allow_large, is_large, is_zero, tld_stats);
|
return mi_os_prim_alloc_at(NULL, size, try_alignment, commit, allow_large, is_large, is_zero);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Primitive aligned allocation from the OS.
|
// Primitive aligned allocation from the OS.
|
||||||
// This function guarantees the allocated memory is aligned.
|
// This function guarantees the allocated memory is aligned.
|
||||||
static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** base, mi_stats_t* stats) {
|
static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, bool* is_large, bool* is_zero, void** base) {
|
||||||
mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0));
|
mi_assert_internal(alignment >= _mi_os_page_size() && ((alignment & (alignment - 1)) == 0));
|
||||||
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
|
mi_assert_internal(size > 0 && (size % _mi_os_page_size()) == 0);
|
||||||
mi_assert_internal(is_large != NULL);
|
mi_assert_internal(is_large != NULL);
|
||||||
|
@ -249,7 +246,7 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
size = _mi_align_up(size, _mi_os_page_size());
|
size = _mi_align_up(size, _mi_os_page_size());
|
||||||
|
|
||||||
// try first with a requested alignment hint (this will usually be aligned directly on Win 10+ or BSD)
|
// try first with a requested alignment hint (this will usually be aligned directly on Win 10+ or BSD)
|
||||||
void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero, stats);
|
void* p = mi_os_prim_alloc(size, alignment, commit, allow_large, is_large, is_zero);
|
||||||
if (p == NULL) return NULL;
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
// aligned already?
|
// aligned already?
|
||||||
|
@ -261,13 +258,13 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
#if !MI_TRACK_ASAN
|
#if !MI_TRACK_ASAN
|
||||||
_mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\n", size, p, alignment, commit);
|
_mi_warning_message("unable to allocate aligned OS memory directly, fall back to over-allocation (size: 0x%zx bytes, address: %p, alignment: 0x%zx, commit: %d)\n", size, p, alignment, commit);
|
||||||
#endif
|
#endif
|
||||||
mi_os_prim_free(p, size, commit, stats);
|
mi_os_prim_free(p, size, commit);
|
||||||
if (size >= (SIZE_MAX - alignment)) return NULL; // overflow
|
if (size >= (SIZE_MAX - alignment)) return NULL; // overflow
|
||||||
const size_t over_size = size + alignment;
|
const size_t over_size = size + alignment;
|
||||||
|
|
||||||
if (!mi_os_mem_config.has_partial_free) { // win32 virtualAlloc cannot free parts of an allocated block
|
if (!mi_os_mem_config.has_partial_free) { // win32 virtualAlloc cannot free parts of an allocated block
|
||||||
// over-allocate uncommitted (virtual) memory
|
// over-allocate uncommitted (virtual) memory
|
||||||
p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, is_zero, stats);
|
p = mi_os_prim_alloc(over_size, 1 /*alignment*/, false /* commit? */, false /* allow_large */, is_large, is_zero);
|
||||||
if (p == NULL) return NULL;
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
// set p to the aligned part in the full region
|
// set p to the aligned part in the full region
|
||||||
|
@ -278,12 +275,12 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
|
|
||||||
// explicitly commit only the aligned part
|
// explicitly commit only the aligned part
|
||||||
if (commit) {
|
if (commit) {
|
||||||
_mi_os_commit(p, size, NULL, stats);
|
_mi_os_commit(p, size, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { // mmap can free inside an allocation
|
else { // mmap can free inside an allocation
|
||||||
// overallocate...
|
// overallocate...
|
||||||
p = mi_os_prim_alloc(over_size, 1, commit, false, is_large, is_zero, stats);
|
p = mi_os_prim_alloc(over_size, 1, commit, false, is_large, is_zero);
|
||||||
if (p == NULL) return NULL;
|
if (p == NULL) return NULL;
|
||||||
|
|
||||||
// and selectively unmap parts around the over-allocated area.
|
// and selectively unmap parts around the over-allocated area.
|
||||||
|
@ -292,8 +289,8 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
size_t mid_size = _mi_align_up(size, _mi_os_page_size());
|
size_t mid_size = _mi_align_up(size, _mi_os_page_size());
|
||||||
size_t post_size = over_size - pre_size - mid_size;
|
size_t post_size = over_size - pre_size - mid_size;
|
||||||
mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size);
|
mi_assert_internal(pre_size < over_size&& post_size < over_size&& mid_size >= size);
|
||||||
if (pre_size > 0) { mi_os_prim_free(p, pre_size, commit, stats); }
|
if (pre_size > 0) { mi_os_prim_free(p, pre_size, commit); }
|
||||||
if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); }
|
if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit); }
|
||||||
// we can return the aligned pointer on `mmap` systems
|
// we can return the aligned pointer on `mmap` systems
|
||||||
p = aligned_p;
|
p = aligned_p;
|
||||||
*base = aligned_p; // since we freed the pre part, `*base == p`.
|
*base = aligned_p; // since we freed the pre part, `*base == p`.
|
||||||
|
@ -309,33 +306,31 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
|
||||||
OS API: alloc and alloc_aligned
|
OS API: alloc and alloc_aligned
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
void* _mi_os_alloc(size_t size, mi_memid_t* memid, mi_stats_t* stats) {
|
void* _mi_os_alloc(size_t size, mi_memid_t* memid) {
|
||||||
*memid = _mi_memid_none();
|
*memid = _mi_memid_none();
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
if (stats == NULL) stats = &_mi_stats_main;
|
|
||||||
size = _mi_os_good_alloc_size(size);
|
size = _mi_os_good_alloc_size(size);
|
||||||
bool os_is_large = false;
|
bool os_is_large = false;
|
||||||
bool os_is_zero = false;
|
bool os_is_zero = false;
|
||||||
void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero, stats);
|
void* p = mi_os_prim_alloc(size, 0, true, false, &os_is_large, &os_is_zero);
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
*memid = _mi_memid_create_os(true, os_is_zero, os_is_large);
|
*memid = _mi_memid_create_os(true, os_is_zero, os_is_large);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats)
|
void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allow_large, mi_memid_t* memid)
|
||||||
{
|
{
|
||||||
MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings
|
MI_UNUSED(&_mi_os_get_aligned_hint); // suppress unused warnings
|
||||||
*memid = _mi_memid_none();
|
*memid = _mi_memid_none();
|
||||||
if (size == 0) return NULL;
|
if (size == 0) return NULL;
|
||||||
if (stats == NULL) stats = &_mi_stats_main;
|
|
||||||
size = _mi_os_good_alloc_size(size);
|
size = _mi_os_good_alloc_size(size);
|
||||||
alignment = _mi_align_up(alignment, _mi_os_page_size());
|
alignment = _mi_align_up(alignment, _mi_os_page_size());
|
||||||
|
|
||||||
bool os_is_large = false;
|
bool os_is_large = false;
|
||||||
bool os_is_zero = false;
|
bool os_is_zero = false;
|
||||||
void* os_base = NULL;
|
void* os_base = NULL;
|
||||||
void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base, stats );
|
void* p = mi_os_prim_alloc_aligned(size, alignment, commit, allow_large, &os_is_large, &os_is_zero, &os_base );
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
*memid = _mi_memid_create_os(commit, os_is_zero, os_is_large);
|
*memid = _mi_memid_create_os(commit, os_is_zero, os_is_large);
|
||||||
memid->mem.os.base = os_base;
|
memid->mem.os.base = os_base;
|
||||||
|
@ -352,29 +347,28 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, bool commit, bool allo
|
||||||
to use the actual start of the memory region.
|
to use the actual start of the memory region.
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid, mi_stats_t* stats) {
|
void* _mi_os_alloc_aligned_at_offset(size_t size, size_t alignment, size_t offset, bool commit, bool allow_large, mi_memid_t* memid) {
|
||||||
mi_assert(offset <= MI_SEGMENT_SIZE);
|
mi_assert(offset <= MI_SEGMENT_SIZE);
|
||||||
mi_assert(offset <= size);
|
mi_assert(offset <= size);
|
||||||
mi_assert((alignment % _mi_os_page_size()) == 0);
|
mi_assert((alignment % _mi_os_page_size()) == 0);
|
||||||
*memid = _mi_memid_none();
|
*memid = _mi_memid_none();
|
||||||
if (stats == NULL) stats = &_mi_stats_main;
|
|
||||||
if (offset > MI_SEGMENT_SIZE) return NULL;
|
if (offset > MI_SEGMENT_SIZE) return NULL;
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
// regular aligned allocation
|
// regular aligned allocation
|
||||||
return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, stats);
|
return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// overallocate to align at an offset
|
// overallocate to align at an offset
|
||||||
const size_t extra = _mi_align_up(offset, alignment) - offset;
|
const size_t extra = _mi_align_up(offset, alignment) - offset;
|
||||||
const size_t oversize = size + extra;
|
const size_t oversize = size + extra;
|
||||||
void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid, stats);
|
void* const start = _mi_os_alloc_aligned(oversize, alignment, commit, allow_large, memid);
|
||||||
if (start == NULL) return NULL;
|
if (start == NULL) return NULL;
|
||||||
|
|
||||||
void* const p = (uint8_t*)start + extra;
|
void* const p = (uint8_t*)start + extra;
|
||||||
mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment));
|
mi_assert(_mi_is_aligned((uint8_t*)p + offset, alignment));
|
||||||
// decommit the overallocation at the start
|
// decommit the overallocation at the start
|
||||||
if (commit && extra > _mi_os_page_size()) {
|
if (commit && extra > _mi_os_page_size()) {
|
||||||
_mi_os_decommit(start, extra, stats);
|
_mi_os_decommit(start, extra);
|
||||||
}
|
}
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
@ -408,12 +402,10 @@ static void* mi_os_page_align_area_conservative(void* addr, size_t size, size_t*
|
||||||
return mi_os_page_align_areax(true, addr, size, newsize);
|
return mi_os_page_align_areax(true, addr, size, newsize);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats) {
|
bool _mi_os_commit(void* addr, size_t size, bool* is_zero) {
|
||||||
MI_UNUSED(tld_stats);
|
|
||||||
mi_stats_t* stats = &_mi_stats_main;
|
|
||||||
if (is_zero != NULL) { *is_zero = false; }
|
if (is_zero != NULL) { *is_zero = false; }
|
||||||
_mi_stat_increase(&stats->committed, size); // use size for precise commit vs. decommit
|
_mi_stat_increase(&os_stats->committed, size); // use size for precise commit vs. decommit
|
||||||
_mi_stat_counter_increase(&stats->commit_calls, 1);
|
_mi_stat_counter_increase(&os_stats->commit_calls, 1);
|
||||||
|
|
||||||
// page align range
|
// page align range
|
||||||
size_t csize;
|
size_t csize;
|
||||||
|
@ -439,11 +431,8 @@ bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, mi_stats_t* tld_stats) {
|
static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit) { mi_assert_internal(needs_recommit!=NULL);
|
||||||
MI_UNUSED(tld_stats);
|
_mi_stat_decrease(&os_stats->committed, size);
|
||||||
mi_stats_t* stats = &_mi_stats_main;
|
|
||||||
mi_assert_internal(needs_recommit!=NULL);
|
|
||||||
_mi_stat_decrease(&stats->committed, size);
|
|
||||||
|
|
||||||
// page align
|
// page align
|
||||||
size_t csize;
|
size_t csize;
|
||||||
|
@ -460,9 +449,9 @@ static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, mi_
|
||||||
return (err == 0);
|
return (err == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) {
|
bool _mi_os_decommit(void* addr, size_t size) {
|
||||||
bool needs_recommit;
|
bool needs_recommit;
|
||||||
return mi_os_decommit_ex(addr, size, &needs_recommit, tld_stats);
|
return mi_os_decommit_ex(addr, size, &needs_recommit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -470,13 +459,13 @@ bool _mi_os_decommit(void* addr, size_t size, mi_stats_t* tld_stats) {
|
||||||
// but may be used later again. This will release physical memory
|
// but may be used later again. This will release physical memory
|
||||||
// pages and reduce swapping while keeping the memory committed.
|
// pages and reduce swapping while keeping the memory committed.
|
||||||
// We page align to a conservative area inside the range to reset.
|
// We page align to a conservative area inside the range to reset.
|
||||||
bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) {
|
bool _mi_os_reset(void* addr, size_t size) {
|
||||||
// page align conservatively within the range
|
// page align conservatively within the range
|
||||||
size_t csize;
|
size_t csize;
|
||||||
void* start = mi_os_page_align_area_conservative(addr, size, &csize);
|
void* start = mi_os_page_align_area_conservative(addr, size, &csize);
|
||||||
if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr)
|
if (csize == 0) return true; // || _mi_os_is_huge_reserved(addr)
|
||||||
_mi_stat_increase(&stats->reset, csize);
|
_mi_stat_increase(&os_stats->reset, csize);
|
||||||
_mi_stat_counter_increase(&stats->reset_calls, 1);
|
_mi_stat_counter_increase(&os_stats->reset_calls, 1);
|
||||||
|
|
||||||
#if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN
|
#if (MI_DEBUG>1) && !MI_SECURE && !MI_TRACK_ENABLED // && !MI_TSAN
|
||||||
memset(start, 0, csize); // pretend it is eagerly reset
|
memset(start, 0, csize); // pretend it is eagerly reset
|
||||||
|
@ -492,22 +481,22 @@ bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) {
|
||||||
|
|
||||||
// either resets or decommits memory, returns true if the memory needs
|
// either resets or decommits memory, returns true if the memory needs
|
||||||
// to be recommitted if it is to be re-used later on.
|
// to be recommitted if it is to be re-used later on.
|
||||||
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats)
|
bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset)
|
||||||
{
|
{
|
||||||
if (mi_option_get(mi_option_purge_delay) < 0) return false; // is purging allowed?
|
if (mi_option_get(mi_option_purge_delay) < 0) return false; // is purging allowed?
|
||||||
_mi_stat_counter_increase(&stats->purge_calls, 1);
|
_mi_stat_counter_increase(&os_stats->purge_calls, 1);
|
||||||
_mi_stat_increase(&stats->purged, size);
|
_mi_stat_increase(&os_stats->purged, size);
|
||||||
|
|
||||||
if (mi_option_is_enabled(mi_option_purge_decommits) && // should decommit?
|
if (mi_option_is_enabled(mi_option_purge_decommits) && // should decommit?
|
||||||
!_mi_preloading()) // don't decommit during preloading (unsafe)
|
!_mi_preloading()) // don't decommit during preloading (unsafe)
|
||||||
{
|
{
|
||||||
bool needs_recommit = true;
|
bool needs_recommit = true;
|
||||||
mi_os_decommit_ex(p, size, &needs_recommit, stats);
|
mi_os_decommit_ex(p, size, &needs_recommit);
|
||||||
return needs_recommit;
|
return needs_recommit;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (allow_reset) { // this can sometimes be not allowed if the range is not fully committed
|
if (allow_reset) { // this can sometimes be not allowed if the range is not fully committed
|
||||||
_mi_os_reset(p, size, stats);
|
_mi_os_reset(p, size);
|
||||||
}
|
}
|
||||||
return false; // needs no recommit
|
return false; // needs no recommit
|
||||||
}
|
}
|
||||||
|
@ -515,8 +504,8 @@ bool _mi_os_purge_ex(void* p, size_t size, bool allow_reset, mi_stats_t* stats)
|
||||||
|
|
||||||
// either resets or decommits memory, returns true if the memory needs
|
// either resets or decommits memory, returns true if the memory needs
|
||||||
// to be recommitted if it is to be re-used later on.
|
// to be recommitted if it is to be re-used later on.
|
||||||
bool _mi_os_purge(void* p, size_t size, mi_stats_t * stats) {
|
bool _mi_os_purge(void* p, size_t size) {
|
||||||
return _mi_os_purge_ex(p, size, true, stats);
|
return _mi_os_purge_ex(p, size, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Protect a region in memory to be not accessible.
|
// Protect a region in memory to be not accessible.
|
||||||
|
@ -623,15 +612,15 @@ void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_mse
|
||||||
// no success, issue a warning and break
|
// no success, issue a warning and break
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
_mi_warning_message("could not allocate contiguous huge OS page %zu at %p\n", page, addr);
|
_mi_warning_message("could not allocate contiguous huge OS page %zu at %p\n", page, addr);
|
||||||
mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, true, &_mi_stats_main);
|
mi_os_prim_free(p, MI_HUGE_OS_PAGE_SIZE, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// success, record it
|
// success, record it
|
||||||
page++; // increase before timeout check (see issue #711)
|
page++; // increase before timeout check (see issue #711)
|
||||||
_mi_stat_increase(&_mi_stats_main.committed, MI_HUGE_OS_PAGE_SIZE);
|
_mi_stat_increase(&os_stats->committed, MI_HUGE_OS_PAGE_SIZE);
|
||||||
_mi_stat_increase(&_mi_stats_main.reserved, MI_HUGE_OS_PAGE_SIZE);
|
_mi_stat_increase(&os_stats->reserved, MI_HUGE_OS_PAGE_SIZE);
|
||||||
|
|
||||||
// check for timeout
|
// check for timeout
|
||||||
if (max_msecs > 0) {
|
if (max_msecs > 0) {
|
||||||
|
@ -665,11 +654,11 @@ void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_mse
|
||||||
|
|
||||||
// free every huge page in a range individually (as we allocated per page)
|
// free every huge page in a range individually (as we allocated per page)
|
||||||
// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems.
|
// note: needed with VirtualAlloc but could potentially be done in one go on mmap'd systems.
|
||||||
static void mi_os_free_huge_os_pages(void* p, size_t size, mi_stats_t* stats) {
|
static void mi_os_free_huge_os_pages(void* p, size_t size) {
|
||||||
if (p==NULL || size==0) return;
|
if (p==NULL || size==0) return;
|
||||||
uint8_t* base = (uint8_t*)p;
|
uint8_t* base = (uint8_t*)p;
|
||||||
while (size >= MI_HUGE_OS_PAGE_SIZE) {
|
while (size >= MI_HUGE_OS_PAGE_SIZE) {
|
||||||
mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, true, stats);
|
mi_os_prim_free(base, MI_HUGE_OS_PAGE_SIZE, true);
|
||||||
size -= MI_HUGE_OS_PAGE_SIZE;
|
size -= MI_HUGE_OS_PAGE_SIZE;
|
||||||
base += MI_HUGE_OS_PAGE_SIZE;
|
base += MI_HUGE_OS_PAGE_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -698,8 +687,7 @@ size_t _mi_os_numa_node_count_get(void) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
int _mi_os_numa_node_get(mi_os_tld_t* tld) {
|
int _mi_os_numa_node_get(void) {
|
||||||
MI_UNUSED(tld);
|
|
||||||
size_t numa_count = _mi_os_numa_node_count();
|
size_t numa_count = _mi_os_numa_node_count();
|
||||||
if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0
|
if (numa_count<=1) return 0; // optimize on single numa node systems: always node 0
|
||||||
// never more than the node count and >= 0
|
// never more than the node count and >= 0
|
||||||
|
|
|
@ -276,7 +276,7 @@ static mi_page_t* mi_page_fresh_alloc(mi_heap_t* heap, mi_page_queue_t* pq, size
|
||||||
mi_assert_internal(mi_heap_contains_queue(heap, pq));
|
mi_assert_internal(mi_heap_contains_queue(heap, pq));
|
||||||
mi_assert_internal(page_alignment > 0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || block_size == pq->block_size);
|
mi_assert_internal(page_alignment > 0 || block_size > MI_MEDIUM_OBJ_SIZE_MAX || block_size == pq->block_size);
|
||||||
#endif
|
#endif
|
||||||
mi_page_t* page = _mi_segment_page_alloc(heap, block_size, page_alignment, &heap->tld->segments, &heap->tld->os);
|
mi_page_t* page = _mi_segment_page_alloc(heap, block_size, page_alignment, &heap->tld->segments);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
// this may be out-of-memory, or an abandoned page was reclaimed (and in our queue)
|
// this may be out-of-memory, or an abandoned page was reclaimed (and in our queue)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -55,11 +55,11 @@ static mi_segmap_part_t* mi_segment_map_index_of(const mi_segment_t* segment, bo
|
||||||
if (part == NULL) {
|
if (part == NULL) {
|
||||||
if (!create_on_demand) return NULL;
|
if (!create_on_demand) return NULL;
|
||||||
mi_memid_t memid;
|
mi_memid_t memid;
|
||||||
part = (mi_segmap_part_t*)_mi_os_alloc(sizeof(mi_segmap_part_t), &memid, NULL);
|
part = (mi_segmap_part_t*)_mi_os_alloc(sizeof(mi_segmap_part_t), &memid);
|
||||||
if (part == NULL) return NULL;
|
if (part == NULL) return NULL;
|
||||||
mi_segmap_part_t* expected = NULL;
|
mi_segmap_part_t* expected = NULL;
|
||||||
if (!mi_atomic_cas_ptr_strong_release(mi_segmap_part_t, &mi_segment_map[segindex], &expected, part)) {
|
if (!mi_atomic_cas_ptr_strong_release(mi_segmap_part_t, &mi_segment_map[segindex], &expected, part)) {
|
||||||
_mi_os_free(part, sizeof(mi_segmap_part_t), memid, NULL);
|
_mi_os_free(part, sizeof(mi_segmap_part_t), memid);
|
||||||
part = expected;
|
part = expected;
|
||||||
if (part == NULL) return NULL;
|
if (part == NULL) return NULL;
|
||||||
}
|
}
|
||||||
|
|
100
src/segment.c
100
src/segment.c
|
@ -17,7 +17,7 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats);
|
static void mi_segment_try_purge(mi_segment_t* segment, bool force);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
|
@ -410,7 +410,7 @@ static void mi_segment_os_free(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||||
const size_t size = mi_segment_size(segment);
|
const size_t size = mi_segment_size(segment);
|
||||||
const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size);
|
const size_t csize = _mi_commit_mask_committed_size(&segment->commit_mask, size);
|
||||||
|
|
||||||
_mi_arena_free(segment, mi_segment_size(segment), csize, segment->memid, tld->stats);
|
_mi_arena_free(segment, mi_segment_size(segment), csize, segment->memid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
|
@ -467,7 +467,7 @@ static void mi_segment_commit_mask(mi_segment_t* segment, bool conservative, uin
|
||||||
mi_commit_mask_create(bitidx, bitcount, cm);
|
mi_commit_mask_create(bitidx, bitcount, cm);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size) {
|
||||||
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
||||||
|
|
||||||
// commit liberal
|
// commit liberal
|
||||||
|
@ -483,7 +483,7 @@ static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size, mi
|
||||||
mi_commit_mask_t cmask;
|
mi_commit_mask_t cmask;
|
||||||
mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
|
mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
|
||||||
_mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap
|
_mi_stat_decrease(&_mi_stats_main.committed, _mi_commit_mask_committed_size(&cmask, MI_SEGMENT_SIZE)); // adjust for overlap
|
||||||
if (!_mi_os_commit(start, full_size, &is_zero, stats)) return false;
|
if (!_mi_os_commit(start, full_size, &is_zero)) return false;
|
||||||
mi_commit_mask_set(&segment->commit_mask, &mask);
|
mi_commit_mask_set(&segment->commit_mask, &mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -497,15 +497,15 @@ static bool mi_segment_commit(mi_segment_t* segment, uint8_t* p, size_t size, mi
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
static bool mi_segment_ensure_committed(mi_segment_t* segment, uint8_t* p, size_t size) {
|
||||||
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
||||||
// note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow
|
// note: assumes commit_mask is always full for huge segments as otherwise the commit mask bits can overflow
|
||||||
if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->purge_mask)) return true; // fully committed
|
if (mi_commit_mask_is_full(&segment->commit_mask) && mi_commit_mask_is_empty(&segment->purge_mask)) return true; // fully committed
|
||||||
mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);
|
mi_assert_internal(segment->kind != MI_SEGMENT_HUGE);
|
||||||
return mi_segment_commit(segment, p, size, stats);
|
return mi_segment_commit(segment, p, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size) {
|
||||||
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
mi_assert_internal(mi_commit_mask_all_set(&segment->commit_mask, &segment->purge_mask));
|
||||||
if (!segment->allow_purge) return true;
|
if (!segment->allow_purge) return true;
|
||||||
|
|
||||||
|
@ -520,7 +520,7 @@ static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_
|
||||||
// purging
|
// purging
|
||||||
mi_assert_internal((void*)start != (void*)segment);
|
mi_assert_internal((void*)start != (void*)segment);
|
||||||
mi_assert_internal(segment->allow_decommit);
|
mi_assert_internal(segment->allow_decommit);
|
||||||
const bool decommitted = _mi_os_purge(start, full_size, stats); // reset or decommit
|
const bool decommitted = _mi_os_purge(start, full_size); // reset or decommit
|
||||||
if (decommitted) {
|
if (decommitted) {
|
||||||
mi_commit_mask_t cmask;
|
mi_commit_mask_t cmask;
|
||||||
mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
|
mi_commit_mask_create_intersect(&segment->commit_mask, &mask, &cmask);
|
||||||
|
@ -534,11 +534,11 @@ static bool mi_segment_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t size, mi_stats_t* stats) {
|
static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t size) {
|
||||||
if (!segment->allow_purge) return;
|
if (!segment->allow_purge) return;
|
||||||
|
|
||||||
if (mi_option_get(mi_option_purge_delay) == 0) {
|
if (mi_option_get(mi_option_purge_delay) == 0) {
|
||||||
mi_segment_purge(segment, p, size, stats);
|
mi_segment_purge(segment, p, size);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// register for future purge in the purge mask
|
// register for future purge in the purge mask
|
||||||
|
@ -561,7 +561,7 @@ static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t
|
||||||
else if (segment->purge_expire <= now) {
|
else if (segment->purge_expire <= now) {
|
||||||
// previous purge mask already expired
|
// previous purge mask already expired
|
||||||
if (segment->purge_expire + mi_option_get(mi_option_purge_extend_delay) <= now) {
|
if (segment->purge_expire + mi_option_get(mi_option_purge_extend_delay) <= now) {
|
||||||
mi_segment_try_purge(segment, true, stats);
|
mi_segment_try_purge(segment, true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
segment->purge_expire = now + mi_option_get(mi_option_purge_extend_delay); // (mi_option_get(mi_option_purge_delay) / 8); // wait a tiny bit longer in case there is a series of free's
|
segment->purge_expire = now + mi_option_get(mi_option_purge_extend_delay); // (mi_option_get(mi_option_purge_delay) / 8); // wait a tiny bit longer in case there is a series of free's
|
||||||
|
@ -574,7 +574,7 @@ static void mi_segment_schedule_purge(mi_segment_t* segment, uint8_t* p, size_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t* stats) {
|
static void mi_segment_try_purge(mi_segment_t* segment, bool force) {
|
||||||
if (!segment->allow_purge || segment->purge_expire == 0 || mi_commit_mask_is_empty(&segment->purge_mask)) return;
|
if (!segment->allow_purge || segment->purge_expire == 0 || mi_commit_mask_is_empty(&segment->purge_mask)) return;
|
||||||
mi_msecs_t now = _mi_clock_now();
|
mi_msecs_t now = _mi_clock_now();
|
||||||
if (!force && now < segment->purge_expire) return;
|
if (!force && now < segment->purge_expire) return;
|
||||||
|
@ -590,7 +590,7 @@ static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t*
|
||||||
if (count > 0) {
|
if (count > 0) {
|
||||||
uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE);
|
uint8_t* p = (uint8_t*)segment + (idx*MI_COMMIT_SIZE);
|
||||||
size_t size = count * MI_COMMIT_SIZE;
|
size_t size = count * MI_COMMIT_SIZE;
|
||||||
mi_segment_purge(segment, p, size, stats);
|
mi_segment_purge(segment, p, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mi_commit_mask_foreach_end()
|
mi_commit_mask_foreach_end()
|
||||||
|
@ -599,8 +599,8 @@ static void mi_segment_try_purge(mi_segment_t* segment, bool force, mi_stats_t*
|
||||||
|
|
||||||
// called from `mi_heap_collect_ex`
|
// called from `mi_heap_collect_ex`
|
||||||
// this can be called per-page so it is important that try_purge has fast exit path
|
// this can be called per-page so it is important that try_purge has fast exit path
|
||||||
void _mi_segment_collect(mi_segment_t* segment, bool force, mi_segments_tld_t* tld) {
|
void _mi_segment_collect(mi_segment_t* segment, bool force) {
|
||||||
mi_segment_try_purge(segment, force, tld->stats);
|
mi_segment_try_purge(segment, force);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
|
@ -635,7 +635,7 @@ static void mi_segment_span_free(mi_segment_t* segment, size_t slice_index, size
|
||||||
|
|
||||||
// perhaps decommit
|
// perhaps decommit
|
||||||
if (allow_purge) {
|
if (allow_purge) {
|
||||||
mi_segment_schedule_purge(segment, mi_slice_start(slice), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats);
|
mi_segment_schedule_purge(segment, mi_slice_start(slice), slice_count * MI_SEGMENT_SLICE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// and push it on the free page queue (if it was not a huge page)
|
// and push it on the free page queue (if it was not a huge page)
|
||||||
|
@ -712,13 +712,13 @@ static mi_slice_t* mi_segment_span_free_coalesce(mi_slice_t* slice, mi_segments_
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
// Note: may still return NULL if committing the memory failed
|
// Note: may still return NULL if committing the memory failed
|
||||||
static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count, mi_segments_tld_t* tld) {
|
static mi_page_t* mi_segment_span_allocate(mi_segment_t* segment, size_t slice_index, size_t slice_count) {
|
||||||
mi_assert_internal(slice_index < segment->slice_entries);
|
mi_assert_internal(slice_index < segment->slice_entries);
|
||||||
mi_slice_t* const slice = &segment->slices[slice_index];
|
mi_slice_t* const slice = &segment->slices[slice_index];
|
||||||
mi_assert_internal(slice->block_size==0 || slice->block_size==1);
|
mi_assert_internal(slice->block_size==0 || slice->block_size==1);
|
||||||
|
|
||||||
// commit before changing the slice data
|
// commit before changing the slice data
|
||||||
if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE, tld->stats)) {
|
if (!mi_segment_ensure_committed(segment, _mi_segment_page_start_from_slice(segment, slice, 0, NULL), slice_count * MI_SEGMENT_SLICE_SIZE)) {
|
||||||
return NULL; // commit failed!
|
return NULL; // commit failed!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -791,7 +791,7 @@ static mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_aren
|
||||||
mi_segment_slice_split(segment, slice, slice_count, tld);
|
mi_segment_slice_split(segment, slice, slice_count, tld);
|
||||||
}
|
}
|
||||||
mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->block_size > 0);
|
mi_assert_internal(slice != NULL && slice->slice_count == slice_count && slice->block_size > 0);
|
||||||
mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count, tld);
|
mi_page_t* page = mi_segment_span_allocate(segment, mi_slice_index(slice), slice->slice_count);
|
||||||
if (page == NULL) {
|
if (page == NULL) {
|
||||||
// commit failed; return NULL but first restore the slice
|
// commit failed; return NULL but first restore the slice
|
||||||
mi_segment_span_free_coalesce(slice, tld);
|
mi_segment_span_free_coalesce(slice, tld);
|
||||||
|
@ -814,7 +814,7 @@ static mi_page_t* mi_segments_page_find_and_allocate(size_t slice_count, mi_aren
|
||||||
|
|
||||||
static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment, bool eager_delayed, mi_arena_id_t req_arena_id,
|
static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment, bool eager_delayed, mi_arena_id_t req_arena_id,
|
||||||
size_t* psegment_slices, size_t* pinfo_slices,
|
size_t* psegment_slices, size_t* pinfo_slices,
|
||||||
bool commit, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
|
bool commit, mi_segments_tld_t* tld)
|
||||||
|
|
||||||
{
|
{
|
||||||
mi_memid_t memid;
|
mi_memid_t memid;
|
||||||
|
@ -835,7 +835,7 @@ static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE;
|
const size_t segment_size = (*psegment_slices) * MI_SEGMENT_SLICE_SIZE;
|
||||||
mi_segment_t* segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, alignment, align_offset, commit, allow_large, req_arena_id, &memid, os_tld);
|
mi_segment_t* segment = (mi_segment_t*)_mi_arena_alloc_aligned(segment_size, alignment, align_offset, commit, allow_large, req_arena_id, &memid);
|
||||||
if (segment == NULL) {
|
if (segment == NULL) {
|
||||||
return NULL; // failed to allocate
|
return NULL; // failed to allocate
|
||||||
}
|
}
|
||||||
|
@ -851,8 +851,8 @@ static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment
|
||||||
mi_assert_internal(commit_needed>0);
|
mi_assert_internal(commit_needed>0);
|
||||||
mi_commit_mask_create(0, commit_needed, &commit_mask);
|
mi_commit_mask_create(0, commit_needed, &commit_mask);
|
||||||
mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= (*pinfo_slices)*MI_SEGMENT_SLICE_SIZE);
|
mi_assert_internal(commit_needed*MI_COMMIT_SIZE >= (*pinfo_slices)*MI_SEGMENT_SLICE_SIZE);
|
||||||
if (!_mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, NULL, tld->stats)) {
|
if (!_mi_os_commit(segment, commit_needed*MI_COMMIT_SIZE, NULL)) {
|
||||||
_mi_arena_free(segment,segment_size,0,memid,tld->stats);
|
_mi_arena_free(segment,segment_size,0,memid);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -874,7 +874,7 @@ static mi_segment_t* mi_segment_os_alloc( size_t required, size_t page_alignment
|
||||||
|
|
||||||
|
|
||||||
// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .
|
// Allocate a segment from the OS aligned to `MI_SEGMENT_SIZE` .
|
||||||
static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld, mi_page_t** huge_page)
|
static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_page_t** huge_page)
|
||||||
{
|
{
|
||||||
mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL));
|
mi_assert_internal((required==0 && huge_page==NULL) || (required>0 && huge_page != NULL));
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi
|
||||||
|
|
||||||
// Allocate the segment from the OS
|
// Allocate the segment from the OS
|
||||||
mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id,
|
mi_segment_t* segment = mi_segment_os_alloc(required, page_alignment, eager_delay, req_arena_id,
|
||||||
&segment_slices, &info_slices, commit, tld, os_tld);
|
&segment_slices, &info_slices, commit, tld);
|
||||||
if (segment == NULL) return NULL;
|
if (segment == NULL) return NULL;
|
||||||
|
|
||||||
// zero the segment info? -- not always needed as it may be zero initialized from the OS
|
// zero the segment info? -- not always needed as it may be zero initialized from the OS
|
||||||
|
@ -923,14 +923,14 @@ static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi
|
||||||
size_t os_pagesize = _mi_os_page_size();
|
size_t os_pagesize = _mi_os_page_size();
|
||||||
_mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);
|
_mi_os_protect((uint8_t*)segment + mi_segment_info_size(segment) - os_pagesize, os_pagesize);
|
||||||
uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;
|
uint8_t* end = (uint8_t*)segment + mi_segment_size(segment) - os_pagesize;
|
||||||
mi_segment_ensure_committed(segment, end, os_pagesize, tld->stats);
|
mi_segment_ensure_committed(segment, end, os_pagesize);
|
||||||
_mi_os_protect(end, os_pagesize);
|
_mi_os_protect(end, os_pagesize);
|
||||||
if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-(
|
if (slice_entries == segment_slices) segment->slice_entries--; // don't use the last slice :-(
|
||||||
guard_slices = 1;
|
guard_slices = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// reserve first slices for segment info
|
// reserve first slices for segment info
|
||||||
mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices, tld);
|
mi_page_t* page0 = mi_segment_span_allocate(segment, 0, info_slices);
|
||||||
mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance
|
mi_assert_internal(page0!=NULL); if (page0==NULL) return NULL; // cannot fail as we always commit in advance
|
||||||
mi_assert_internal(segment->used == 1);
|
mi_assert_internal(segment->used == 1);
|
||||||
segment->used = 0; // don't count our internal slices towards usage
|
segment->used = 0; // don't count our internal slices towards usage
|
||||||
|
@ -944,7 +944,7 @@ static mi_segment_t* mi_segment_alloc(size_t required, size_t page_alignment, mi
|
||||||
mi_assert_internal(huge_page!=NULL);
|
mi_assert_internal(huge_page!=NULL);
|
||||||
mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask));
|
mi_assert_internal(mi_commit_mask_is_empty(&segment->purge_mask));
|
||||||
mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask));
|
mi_assert_internal(mi_commit_mask_is_full(&segment->commit_mask));
|
||||||
*huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices, tld);
|
*huge_page = mi_segment_span_allocate(segment, info_slices, segment_slices - info_slices - guard_slices);
|
||||||
mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance
|
mi_assert_internal(*huge_page != NULL); // cannot fail as we commit in advance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1011,7 +1011,7 @@ static mi_slice_t* mi_segment_page_clear(mi_page_t* page, mi_segments_tld_t* tld
|
||||||
if (segment->allow_decommit && mi_option_is_enabled(mi_option_deprecated_page_reset)) {
|
if (segment->allow_decommit && mi_option_is_enabled(mi_option_deprecated_page_reset)) {
|
||||||
size_t psize;
|
size_t psize;
|
||||||
uint8_t* start = _mi_segment_page_start(segment, page, &psize);
|
uint8_t* start = _mi_segment_page_start(segment, page, &psize);
|
||||||
_mi_os_reset(start, psize, tld->stats);
|
_mi_os_reset(start, psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
// zero the page data, but not the segment fields and heap tag
|
// zero the page data, but not the segment fields and heap tag
|
||||||
|
@ -1050,7 +1050,7 @@ void _mi_segment_page_free(mi_page_t* page, bool force, mi_segments_tld_t* tld)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// perform delayed purges
|
// perform delayed purges
|
||||||
mi_segment_try_purge(segment, false /* force? */, tld->stats);
|
mi_segment_try_purge(segment, false /* force? */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1100,7 +1100,7 @@ static void mi_segment_abandon(mi_segment_t* segment, mi_segments_tld_t* tld) {
|
||||||
// Only abandoned segments in arena memory can be reclaimed without a free
|
// Only abandoned segments in arena memory can be reclaimed without a free
|
||||||
// so if a segment is not from an arena we force purge here to be conservative.
|
// so if a segment is not from an arena we force purge here to be conservative.
|
||||||
const bool force_purge = (segment->memid.memkind != MI_MEM_ARENA) || mi_option_is_enabled(mi_option_abandoned_page_purge);
|
const bool force_purge = (segment->memid.memkind != MI_MEM_ARENA) || mi_option_is_enabled(mi_option_abandoned_page_purge);
|
||||||
mi_segment_try_purge(segment, force_purge, tld->stats);
|
mi_segment_try_purge(segment, force_purge);
|
||||||
|
|
||||||
// all pages in the segment are abandoned; add it to the abandoned list
|
// all pages in the segment are abandoned; add it to the abandoned list
|
||||||
_mi_stat_increase(&tld->stats->segments_abandoned, 1);
|
_mi_stat_increase(&tld->stats->segments_abandoned, 1);
|
||||||
|
@ -1350,7 +1350,7 @@ static mi_segment_t* mi_segment_try_reclaim(mi_heap_t* heap, size_t needed_slice
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// otherwise, push on the visited list so it gets not looked at too quickly again
|
// otherwise, push on the visited list so it gets not looked at too quickly again
|
||||||
mi_segment_try_purge(segment, false /* true force? */, tld->stats); // force purge if needed as we may not visit soon again
|
mi_segment_try_purge(segment, false /* true force? */); // force purge if needed as we may not visit soon again
|
||||||
_mi_arena_segment_mark_abandoned(segment);
|
_mi_arena_segment_mark_abandoned(segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1375,7 +1375,7 @@ void _mi_abandoned_collect(mi_heap_t* heap, bool force, mi_segments_tld_t* tld)
|
||||||
else {
|
else {
|
||||||
// otherwise, purge if needed and push on the visited list
|
// otherwise, purge if needed and push on the visited list
|
||||||
// note: forced purge can be expensive if many threads are destroyed/created as in mstress.
|
// note: forced purge can be expensive if many threads are destroyed/created as in mstress.
|
||||||
mi_segment_try_purge(segment, force, tld->stats);
|
mi_segment_try_purge(segment, force);
|
||||||
_mi_arena_segment_mark_abandoned(segment);
|
_mi_arena_segment_mark_abandoned(segment);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1434,7 +1434,7 @@ static void mi_segment_force_abandon(mi_segment_t* segment, mi_segments_tld_t* t
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// perform delayed purges
|
// perform delayed purges
|
||||||
mi_segment_try_purge(segment, false /* force? */, tld->stats);
|
mi_segment_try_purge(segment, false /* force? */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1483,7 +1483,7 @@ void mi_collect_reduce(size_t target_size) mi_attr_noexcept {
|
||||||
Reclaim or allocate
|
Reclaim or allocate
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
|
static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_slices, size_t block_size, mi_segments_tld_t* tld)
|
||||||
{
|
{
|
||||||
mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX);
|
mi_assert_internal(block_size <= MI_LARGE_OBJ_SIZE_MAX);
|
||||||
|
|
||||||
|
@ -1503,7 +1503,7 @@ static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_
|
||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
// 2. otherwise allocate a fresh segment
|
// 2. otherwise allocate a fresh segment
|
||||||
return mi_segment_alloc(0, 0, heap->arena_id, tld, os_tld, NULL);
|
return mi_segment_alloc(0, 0, heap->arena_id, tld, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1511,7 +1511,7 @@ static mi_segment_t* mi_segment_reclaim_or_alloc(mi_heap_t* heap, size_t needed_
|
||||||
Page allocation
|
Page allocation
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
|
static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_kind, size_t required, size_t block_size, mi_segments_tld_t* tld)
|
||||||
{
|
{
|
||||||
mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE);
|
mi_assert_internal(required <= MI_LARGE_OBJ_SIZE_MAX && page_kind <= MI_PAGE_LARGE);
|
||||||
|
|
||||||
|
@ -1522,18 +1522,18 @@ static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_ki
|
||||||
mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, heap->arena_id, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld);
|
mi_page_t* page = mi_segments_page_find_and_allocate(slices_needed, heap->arena_id, tld); //(required <= MI_SMALL_SIZE_MAX ? 0 : slices_needed), tld);
|
||||||
if (page==NULL) {
|
if (page==NULL) {
|
||||||
// no free page, allocate a new segment and try again
|
// no free page, allocate a new segment and try again
|
||||||
if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld, os_tld) == NULL) {
|
if (mi_segment_reclaim_or_alloc(heap, slices_needed, block_size, tld) == NULL) {
|
||||||
// OOM or reclaimed a good page in the heap
|
// OOM or reclaimed a good page in the heap
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// otherwise try again
|
// otherwise try again
|
||||||
return mi_segments_page_alloc(heap, page_kind, required, block_size, tld, os_tld);
|
return mi_segments_page_alloc(heap, page_kind, required, block_size, tld);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size);
|
mi_assert_internal(page != NULL && page->slice_count*MI_SEGMENT_SLICE_SIZE == page_size);
|
||||||
mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id());
|
mi_assert_internal(_mi_ptr_segment(page)->thread_id == _mi_thread_id());
|
||||||
mi_segment_try_purge(_mi_ptr_segment(page), false, tld->stats);
|
mi_segment_try_purge(_mi_ptr_segment(page), false);
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1543,10 +1543,10 @@ static mi_page_t* mi_segments_page_alloc(mi_heap_t* heap, mi_page_kind_t page_ki
|
||||||
Huge page allocation
|
Huge page allocation
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
|
|
||||||
static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld, mi_os_tld_t* os_tld)
|
static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment, mi_arena_id_t req_arena_id, mi_segments_tld_t* tld)
|
||||||
{
|
{
|
||||||
mi_page_t* page = NULL;
|
mi_page_t* page = NULL;
|
||||||
mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,os_tld,&page);
|
mi_segment_t* segment = mi_segment_alloc(size,page_alignment,req_arena_id,tld,&page);
|
||||||
if (segment == NULL || page==NULL) return NULL;
|
if (segment == NULL || page==NULL) return NULL;
|
||||||
mi_assert_internal(segment->used==1);
|
mi_assert_internal(segment->used==1);
|
||||||
mi_assert_internal(mi_page_block_size(page) >= size);
|
mi_assert_internal(mi_page_block_size(page) >= size);
|
||||||
|
@ -1568,7 +1568,7 @@ static mi_page_t* mi_segment_huge_page_alloc(size_t size, size_t page_alignment,
|
||||||
mi_assert_internal(psize - (aligned_p - start) >= size);
|
mi_assert_internal(psize - (aligned_p - start) >= size);
|
||||||
uint8_t* decommit_start = start + sizeof(mi_block_t); // for the free list
|
uint8_t* decommit_start = start + sizeof(mi_block_t); // for the free list
|
||||||
ptrdiff_t decommit_size = aligned_p - decommit_start;
|
ptrdiff_t decommit_size = aligned_p - decommit_start;
|
||||||
_mi_os_reset(decommit_start, decommit_size, &_mi_stats_main); // note: cannot use segment_decommit on huge segments
|
_mi_os_reset(decommit_start, decommit_size); // note: cannot use segment_decommit on huge segments
|
||||||
}
|
}
|
||||||
|
|
||||||
return page;
|
return page;
|
||||||
|
@ -1615,7 +1615,7 @@ void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_bloc
|
||||||
if (csize > sizeof(mi_block_t)) {
|
if (csize > sizeof(mi_block_t)) {
|
||||||
csize = csize - sizeof(mi_block_t);
|
csize = csize - sizeof(mi_block_t);
|
||||||
uint8_t* p = (uint8_t*)block + sizeof(mi_block_t);
|
uint8_t* p = (uint8_t*)block + sizeof(mi_block_t);
|
||||||
_mi_os_reset(p, csize, &_mi_stats_main); // note: cannot use segment_decommit on huge segments
|
_mi_os_reset(p, csize); // note: cannot use segment_decommit on huge segments
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1624,25 +1624,25 @@ void _mi_segment_huge_page_reset(mi_segment_t* segment, mi_page_t* page, mi_bloc
|
||||||
/* -----------------------------------------------------------
|
/* -----------------------------------------------------------
|
||||||
Page allocation and free
|
Page allocation and free
|
||||||
----------------------------------------------------------- */
|
----------------------------------------------------------- */
|
||||||
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld, mi_os_tld_t* os_tld) {
|
mi_page_t* _mi_segment_page_alloc(mi_heap_t* heap, size_t block_size, size_t page_alignment, mi_segments_tld_t* tld) {
|
||||||
mi_page_t* page;
|
mi_page_t* page;
|
||||||
if mi_unlikely(page_alignment > MI_BLOCK_ALIGNMENT_MAX) {
|
if mi_unlikely(page_alignment > MI_BLOCK_ALIGNMENT_MAX) {
|
||||||
mi_assert_internal(_mi_is_power_of_two(page_alignment));
|
mi_assert_internal(_mi_is_power_of_two(page_alignment));
|
||||||
mi_assert_internal(page_alignment >= MI_SEGMENT_SIZE);
|
mi_assert_internal(page_alignment >= MI_SEGMENT_SIZE);
|
||||||
if (page_alignment < MI_SEGMENT_SIZE) { page_alignment = MI_SEGMENT_SIZE; }
|
if (page_alignment < MI_SEGMENT_SIZE) { page_alignment = MI_SEGMENT_SIZE; }
|
||||||
page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld);
|
page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld);
|
||||||
}
|
}
|
||||||
else if (block_size <= MI_SMALL_OBJ_SIZE_MAX) {
|
else if (block_size <= MI_SMALL_OBJ_SIZE_MAX) {
|
||||||
page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld,os_tld);
|
page = mi_segments_page_alloc(heap,MI_PAGE_SMALL,block_size,block_size,tld);
|
||||||
}
|
}
|
||||||
else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) {
|
else if (block_size <= MI_MEDIUM_OBJ_SIZE_MAX) {
|
||||||
page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld, os_tld);
|
page = mi_segments_page_alloc(heap,MI_PAGE_MEDIUM,MI_MEDIUM_PAGE_SIZE,block_size,tld);
|
||||||
}
|
}
|
||||||
else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) {
|
else if (block_size <= MI_LARGE_OBJ_SIZE_MAX) {
|
||||||
page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld, os_tld);
|
page = mi_segments_page_alloc(heap,MI_PAGE_LARGE,block_size,block_size,tld);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld,os_tld);
|
page = mi_segment_huge_page_alloc(block_size,page_alignment,heap->arena_id,tld);
|
||||||
}
|
}
|
||||||
mi_assert_internal(page == NULL || _mi_heap_memid_is_suitable(heap, _mi_page_segment(page)->memid));
|
mi_assert_internal(page == NULL || _mi_heap_memid_is_suitable(heap, _mi_page_segment(page)->memid));
|
||||||
mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld));
|
mi_assert_expensive(page == NULL || mi_segment_is_valid(_mi_page_segment(page),tld));
|
||||||
|
|
|
@ -316,11 +316,11 @@ static void test_large_pages(void) {
|
||||||
static inline uint8_t mi_bsr32(uint32_t x);
|
static inline uint8_t mi_bsr32(uint32_t x);
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#include <windows.h>
|
//#include <Windows.h>
|
||||||
#include <intrin.h>
|
#include <intrin.h>
|
||||||
static inline uint8_t mi_bsr32(uint32_t x) {
|
static inline uint8_t mi_bsr32(uint32_t x) {
|
||||||
uint32_t idx;
|
uint32_t idx;
|
||||||
_BitScanReverse((DWORD*)&idx, x);
|
_BitScanReverse(&idx, x);
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
#elif defined(__GNUC__) || defined(__clang__)
|
#elif defined(__GNUC__) || defined(__clang__)
|
||||||
|
@ -344,7 +344,7 @@ static inline uint8_t mi_bsr32(uint32_t x) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
// Bit scan reverse: return the index of the highest bit.
|
// Bit scan reverse: return the index of the highest bit.
|
||||||
uint8_t _mi_bsr(uintptr_t x) {
|
uint8_t _mi_bsr(uintptr_t x) {
|
||||||
if (x == 0) return 0;
|
if (x == 0) return 0;
|
||||||
|
@ -357,7 +357,7 @@ uint8_t _mi_bsr(uintptr_t x) {
|
||||||
# error "define bsr for non-32 or 64-bit platforms"
|
# error "define bsr for non-32 or 64-bit platforms"
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
static inline size_t _mi_wsize_from_size(size_t size) {
|
static inline size_t _mi_wsize_from_size(size_t size) {
|
||||||
|
@ -434,11 +434,20 @@ static inline uint8_t _mi_bin4(size_t size) {
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t _mi_binx4(size_t bsize) {
|
static size_t _mi_binx4(size_t wsize) {
|
||||||
if (bsize==0) return 0;
|
size_t bin;
|
||||||
uint8_t b = mi_bsr32((uint32_t)bsize);
|
if (wsize <= 1) {
|
||||||
if (b <= 1) return bsize;
|
bin = 1;
|
||||||
size_t bin = ((b << 1) | (bsize >> (b - 1))&0x01);
|
}
|
||||||
|
else if (wsize <= 8) {
|
||||||
|
// bin = (wsize+1)&~1; // round to double word sizes
|
||||||
|
bin = (uint8_t)wsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t b = mi_bsr32((uint32_t)wsize);
|
||||||
|
if (b <= 1) return wsize;
|
||||||
|
bin = ((b << 1) | (wsize >> (b - 1))&0x01) + 3;
|
||||||
|
}
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,22 +459,40 @@ static size_t _mi_binx8(size_t bsize) {
|
||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline size_t mi_bin(size_t wsize) {
|
||||||
|
uint8_t bin;
|
||||||
|
if (wsize <= 1) {
|
||||||
|
bin = 1;
|
||||||
|
}
|
||||||
|
else if (wsize <= 8) {
|
||||||
|
// bin = (wsize+1)&~1; // round to double word sizes
|
||||||
|
bin = (uint8_t)wsize;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
wsize--;
|
||||||
|
// find the highest bit
|
||||||
|
uint8_t b = (uint8_t)mi_bsr32((uint32_t)wsize); // note: wsize != 0
|
||||||
|
// and use the top 3 bits to determine the bin (~12.5% worst internal fragmentation).
|
||||||
|
// - adjust with 3 because we use do not round the first 8 sizes
|
||||||
|
// which each get an exact bin
|
||||||
|
bin = ((b << 2) + (uint8_t)((wsize >> (b - 2)) & 0x03)) - 3;
|
||||||
|
}
|
||||||
|
return bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void mi_bins(void) {
|
static void mi_bins(void) {
|
||||||
//printf(" QNULL(1), /* 0 */ \\\n ");
|
//printf(" QNULL(1), /* 0 */ \\\n ");
|
||||||
size_t last_bin = 0;
|
size_t last_bin = 0;
|
||||||
size_t min_bsize = 0;
|
for (size_t wsize = 1; wsize <= (4*1024*1024) / 8 + 1024; wsize++) {
|
||||||
size_t last_bsize = 0;
|
size_t bin = mi_bin(wsize);
|
||||||
for (size_t bsize = 1; bsize < 2*1024; bsize++) {
|
|
||||||
size_t size = bsize * 64 * 1024;
|
|
||||||
size_t bin = _mi_binx8(bsize);
|
|
||||||
if (bin != last_bin) {
|
if (bin != last_bin) {
|
||||||
printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_bsize, last_bsize, last_bin);
|
//printf("min bsize: %6zd, max bsize: %6zd, bin: %6zd\n", min_wsize, last_wsize, last_bin);
|
||||||
//printf("QNULL(%6zd), ", wsize);
|
printf("QNULL(%6zd), ", wsize-1);
|
||||||
//if (last_bin%8 == 0) printf("/* %i */ \\\n ", last_bin);
|
if (last_bin%8 == 0) printf("/* %zu */ \\\n ", last_bin);
|
||||||
last_bin = bin;
|
last_bin = bin;
|
||||||
min_bsize = bsize;
|
|
||||||
}
|
}
|
||||||
last_bsize = bsize;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -47,8 +47,8 @@ static void test_stl_allocators();
|
||||||
|
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
// mi_stats_reset(); // ignore earlier allocations
|
mi_stats_reset(); // ignore earlier allocations
|
||||||
|
various_tests();
|
||||||
test_mixed1();
|
test_mixed1();
|
||||||
//test_std_string();
|
//test_std_string();
|
||||||
//test_thread_local();
|
//test_thread_local();
|
||||||
|
|
|
@ -23,7 +23,7 @@ terms of the MIT license.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
// #define MI_GUARDED
|
// #define MI_GUARDED
|
||||||
// #define USE_STD_MALLOC
|
#define USE_STD_MALLOC
|
||||||
|
|
||||||
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
// > mimalloc-test-stress [THREADS] [SCALE] [ITER]
|
||||||
//
|
//
|
||||||
|
@ -36,13 +36,13 @@ static int ITER = 400;
|
||||||
static int THREADS = 8;
|
static int THREADS = 8;
|
||||||
static int SCALE = 25;
|
static int SCALE = 25;
|
||||||
static int ITER = 20;
|
static int ITER = 20;
|
||||||
#elif defined(xMI_GUARDED) // with debug guard pages reduce parameters to stay within the azure pipeline limits
|
#elif defined(MI_GUARDED) // with debug guard pages reduce parameters to stay within the azure pipeline limits
|
||||||
static int THREADS = 8;
|
static int THREADS = 8;
|
||||||
static int SCALE = 10;
|
static int SCALE = 10;
|
||||||
static int ITER = 10;
|
static int ITER = 10;
|
||||||
#else
|
#else
|
||||||
static int THREADS = 32; // more repeatable if THREADS <= #processors
|
static int THREADS = 32; // more repeatable if THREADS <= #processors
|
||||||
static int SCALE = 25; // scaling factor
|
static int SCALE = 50; // scaling factor
|
||||||
static int ITER = 50; // N full iterations destructing and re-creating all threads
|
static int ITER = 50; // N full iterations destructing and re-creating all threads
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -50,7 +50,7 @@ static int ITER = 50; // N full iterations destructing and re-creating a
|
||||||
|
|
||||||
#define STRESS // undefine for leak test
|
#define STRESS // undefine for leak test
|
||||||
|
|
||||||
static bool allow_large_objects = true; // allow very large objects? (set to `true` if SCALE>100)
|
static bool allow_large_objects = false; // allow very large objects? (set to `true` if SCALE>100)
|
||||||
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
|
static size_t use_one_size = 0; // use single object size of `N * sizeof(uintptr_t)`?
|
||||||
|
|
||||||
static bool main_participates = false; // main thread participates as a worker too
|
static bool main_participates = false; // main thread participates as a worker too
|
||||||
|
@ -326,6 +326,7 @@ int main(int argc, char** argv) {
|
||||||
#endif
|
#endif
|
||||||
mi_stats_print(NULL);
|
mi_stats_print(NULL);
|
||||||
#endif
|
#endif
|
||||||
|
mi_stats_print(NULL);
|
||||||
//bench_end_program();
|
//bench_end_program();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue