Add support for aligned allocation on Windows using VirtualAlloc2
This commit is contained in:
parent
38eb0a9449
commit
6eaf387891
@ -145,7 +145,12 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\test\test-api.c" />
|
||||
<ClCompile Include="..\..\test\test-api.c">
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
<AssemblerOutput Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AssemblyAndSourceCode</AssemblerOutput>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="mimalloc.vcxproj">
|
||||
|
@ -99,6 +99,12 @@
|
||||
<AdditionalIncludeDirectories>../../include</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>MI_DEBUG=3;_MBCS;%(PreprocessorDefinitions);</PreprocessorDefinitions>
|
||||
</ClCompile>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
@ -117,6 +123,12 @@
|
||||
<EntryPointSymbol>
|
||||
</EntryPointSymbol>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
@ -141,6 +153,12 @@
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
@ -171,6 +189,12 @@
|
||||
<Command>
|
||||
</Command>
|
||||
</PostBuildEvent>
|
||||
<Lib>
|
||||
<AdditionalLibraryDirectories>
|
||||
</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies>
|
||||
</AdditionalDependencies>
|
||||
</Lib>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\src\alloc-aligned.c">
|
||||
|
40
src/os.c
40
src/os.c
@ -22,6 +22,10 @@ terms of the MIT license. A copy of the license can be found in the file
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <windows.h>
|
||||
#if defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) // rough check it VirtualAlloc2 is available (needs windows 10 or Windows server 2016)
|
||||
#pragma comment(lib, "mincore.lib") // seems needed to resolve VirtualAlloc2
|
||||
#define USE_VIRTUALALLOC2 // allows aligned allocation
|
||||
#endif
|
||||
#else
|
||||
#include <sys/mman.h> // mmap
|
||||
#include <unistd.h> // sysconf
|
||||
@ -117,6 +121,32 @@ static void* mi_mmap(void* addr, size_t size, int extra_flags, mi_stats_t* stats
|
||||
return p;
|
||||
}
|
||||
|
||||
static void* mi_mmap_aligned(size_t size, size_t alignment, mi_stats_t* stats) {
|
||||
if (alignment < _mi_os_page_size() || ((alignment & (~alignment + 1)) != alignment)) return NULL;
|
||||
void* p = NULL;
|
||||
#if defined(_WIN32) && defined(USE_VIRTUALALLOC2)
|
||||
// on modern Windows use VirtualAlloc2
|
||||
MEM_ADDRESS_REQUIREMENTS reqs = {0};
|
||||
reqs.Alignment = alignment;
|
||||
MEM_EXTENDED_PARAMETER param = { 0 };
|
||||
param.Type = MemExtendedParameterAddressRequirements;
|
||||
param.Pointer = &reqs;
|
||||
p = VirtualAlloc2(NULL, NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE, ¶m, 1);
|
||||
#elif defined(MAP_ALIGNED)
|
||||
// on BSD, use the aligned mmap api
|
||||
size_t n = _mi_bsr(alignment);
|
||||
if ((size_t)1 << n == alignment && n >= 12) { // alignment is a power of 2 and >= 4096
|
||||
p = mi_mmap(suggest, size, MAP_ALIGNED(n), tld->stats); // use the NetBSD/freeBSD aligned flags
|
||||
}
|
||||
#else
|
||||
UNUSED(size);
|
||||
UNUSED(alignment);
|
||||
#endif
|
||||
mi_assert(p == NULL || (uintptr_t)p % alignment == 0);
|
||||
if (p != NULL) mi_stat_increase(stats->mmap_calls, 1);
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
static void* mi_os_page_align_region(void* addr, size_t size, size_t* newsize) {
|
||||
mi_assert(addr != NULL && size > 0);
|
||||
@ -208,7 +238,7 @@ bool _mi_os_shrink(void* p, size_t oldsize, size_t newsize) {
|
||||
size_t size = 0;
|
||||
void* start = mi_os_page_align_region(addr, oldsize - newsize, &size);
|
||||
if (size==0 || start != addr) return false;
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
// we cannot shrink on windows
|
||||
return false;
|
||||
@ -289,13 +319,7 @@ void* _mi_os_alloc_aligned(size_t size, size_t alignment, mi_os_tld_t* tld)
|
||||
|
||||
void* suggest = NULL;
|
||||
|
||||
#if defined(MAP_ALIGNED)
|
||||
// on BSD, use the aligned mmap api
|
||||
size_t n = _mi_bsr(alignment);
|
||||
if ((size_t)1 << n == alignment && n >= 12) { // alignment is a power of 2 and >= 4096
|
||||
p = mi_mmap(suggest, size, MAP_ALIGNED(n), tld->stats); // use the NetBSD/freeBSD aligned flags
|
||||
}
|
||||
#endif
|
||||
p = mi_mmap_aligned(size,alignment,tld->stats);
|
||||
if (p==NULL && (tld->mmap_next_probable % alignment) == 0) {
|
||||
// if the next probable address is aligned,
|
||||
// then try to just allocate `size` and hope it is aligned...
|
||||
|
@ -28,7 +28,6 @@ we therefore test the API over various inputs. Please add more tests :-)
|
||||
#include "mimalloc.h"
|
||||
#include "mimalloc-internal.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Test macros: CHECK(name,predicate) and CHECK_BODY(name,body)
|
||||
// ---------------------------------------------------------------------------
|
||||
@ -140,7 +139,6 @@ int main() {
|
||||
CHECK("heap_destroy", test_heap1());
|
||||
CHECK("heap_delete", test_heap2());
|
||||
|
||||
|
||||
// ---------------------------------------------------
|
||||
// Done
|
||||
// ---------------------------------------------------[]
|
||||
|
Loading…
Reference in New Issue
Block a user