The newer API (Windows 10 and newer) allows the allocator to ask for
strongly aligned memory.

This is enabled only if the `WINVER` macro is set to target Windows 10
or newer.  There is now a CMake option to target older versions of
Windows, so we can test both code paths.

The Azure Pipelines config now includes a test of the compatibility
version.  This runs only the release build, because it's mainly there as
a sanity check - 99% of the code is the same as the default Windows
config.
This commit is contained in:
David Chisnall 2019-02-19 12:34:53 +00:00 коммит произвёл David Chisnall
Родитель 6ec84856df
Коммит 2ee3ba59ee
3 изменённых файлов: 56 добавлений и 8 удалений

Просмотреть файл

@ -24,10 +24,21 @@ macro(linklibs project)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
target_link_libraries(${project} atomic)
endif()
else()
# VirtualAlloc2 is exposed by mincore.lib, not Kernel32.lib (as the
# documentation says)
target_link_libraries(${project} mincore)
endif()
endmacro()
if(MSVC)
set(WIN8COMPAT FALSE CACHE BOOL "Avoid Windows 10 APIs")
if (WIN8COMPAT)
add_definitions(-DWINVER=0x0603)
message(STATUS "Avoiding Windows 10 APIs")
else()
message(STATUS "Using Windows 10 APIs")
endif()
# Force to always compile with W4
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

Просмотреть файл

@ -79,6 +79,30 @@ phases:
workingDirectory: build
displayName: 'Run Ctest'
- phase: Windows8Compat
queue:
name: 'Hosted VS2017'
parallel: 2
matrix:
Release:
BuildType: Release
steps:
- task: CMake@1
displayName: 'CMake .. -G"Visual Studio 15 2017 Win64"'
inputs:
cmakeArgs: '.. -G"Visual Studio 15 2017 Win64" -DWIN8COMPAT=TRUE'
- task: MSBuild@1
displayName: 'Build solution build/snmalloc.sln'
inputs:
solution: build/snmalloc.sln
msbuildArguments: '/m /p:Configuration=$(BuildType)'
- script: 'ctest -j 4 --interactive-debug-mode 0 --output-on-failure'
workingDirectory: build
displayName: 'Run Ctest'
- phase: Windows32bit
queue:
name: 'Hosted VS2017'

Просмотреть файл

@ -68,19 +68,31 @@ namespace snmalloc
template<bool committed>
void* reserve(size_t* size, size_t align) noexcept
{
DWORD flags = MEM_RESERVE;
if (committed)
flags |= MEM_COMMIT;
# if (WINVER >= _WIN32_WINNT_WIN10) && !defined(USE_SYSTEMATIC_TESTING)
// If we're on Windows 10 or newer, we can use the VirtualAlloc2
// function. The FromApp variant is useable by UWP applications and
// cannot allocate executable memory.
MEM_ADDRESS_REQUIREMENTS addressReqs = {0};
MEM_EXTENDED_PARAMETER param = {0};
addressReqs.Alignment = align;
param.Type = MemExtendedParameterAddressRequirements;
param.Pointer = &addressReqs;
return VirtualAlloc2FromApp(
nullptr, nullptr, *size, flags, PAGE_READWRITE, &param, 1);
# else
// Add align, so we can guarantee to provide at least size.
size_t request = *size + align;
// Alignment must be a power of 2.
assert(align == bits::next_pow2(align));
DWORD flags = MEM_RESERVE;
if (committed)
flags |= MEM_COMMIT;
void* p;
# ifdef USE_SYSTEMATIC_TESTING
# ifdef USE_SYSTEMATIC_TESTING
size_t retries = 1000;
do
{
@ -90,9 +102,9 @@ namespace snmalloc
systematic_bump_ptr() += request;
retries--;
} while (p == nullptr && retries > 0);
# else
# else
p = VirtualAlloc(nullptr, request, flags, PAGE_READWRITE);
# endif
# endif
uintptr_t aligned_p = bits::align_up((size_t)p, align);
@ -105,6 +117,7 @@ namespace snmalloc
}
*size = request;
return p;
# endif
}
};
}