eal/windows: fix build with MinGW-w64 8
MinGW-w64 above 8.0.0 exposes VirtualAlloc2() API in headers, but lacks
it in import libraries. Hence, availability of this API at compile-time
can't be used to choose between locating VirtualAlloc2() manually or
relying on the dynamic linker.
Fix redefinition compile-time errors.
Always link VirtualAlloc2() when using GCC.
Fixes: 2a5d547a4a
("eal/windows: implement basic memory management")
Cc: stable@dpdk.org
Reported-by: Thomas Monjalon <thomas@monjalon.net>
Signed-off-by: Dmitry Kozlyuk <dmitry.kozliuk@gmail.com>
Tested-by: Thomas Monjalon <thomas@monjalon.net>
This commit is contained in:
parent
d3fa7b89f0
commit
93bf432dd5
@ -18,13 +18,12 @@
|
||||
#include <rte_virt2phys.h>
|
||||
|
||||
/* MinGW-w64 headers lack VirtualAlloc2() in some distributions.
|
||||
* Provide a copy of definitions and code to load it dynamically.
|
||||
* Note: definitions are copied verbatim from Microsoft documentation
|
||||
* and don't follow DPDK code style.
|
||||
*
|
||||
* MEM_RESERVE_PLACEHOLDER being defined means VirtualAlloc2() is present too.
|
||||
*/
|
||||
#ifndef MEM_PRESERVE_PLACEHOLDER
|
||||
#ifndef MEM_EXTENDED_PARAMETER_TYPE_BITS
|
||||
|
||||
#define MEM_EXTENDED_PARAMETER_TYPE_BITS 4
|
||||
|
||||
/* https://docs.microsoft.com/en-us/windows/win32/api/winnt/ne-winnt-mem_extended_parameter_type */
|
||||
typedef enum MEM_EXTENDED_PARAMETER_TYPE {
|
||||
@ -37,8 +36,6 @@ typedef enum MEM_EXTENDED_PARAMETER_TYPE {
|
||||
MemExtendedParameterMax
|
||||
} *PMEM_EXTENDED_PARAMETER_TYPE;
|
||||
|
||||
#define MEM_EXTENDED_PARAMETER_TYPE_BITS 4
|
||||
|
||||
/* https://docs.microsoft.com/en-us/windows/win32/api/winnt/ns-winnt-mem_extended_parameter */
|
||||
typedef struct MEM_EXTENDED_PARAMETER {
|
||||
struct {
|
||||
@ -54,6 +51,8 @@ typedef struct MEM_EXTENDED_PARAMETER {
|
||||
} DUMMYUNIONNAME;
|
||||
} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;
|
||||
|
||||
#endif /* defined(MEM_EXTENDED_PARAMETER_TYPE_BITS) */
|
||||
|
||||
/* https://docs.microsoft.com/en-us/windows/win32/api/memoryapi/nf-memoryapi-virtualalloc2 */
|
||||
typedef PVOID (*VirtualAlloc2_type)(
|
||||
HANDLE Process,
|
||||
@ -65,17 +64,19 @@ typedef PVOID (*VirtualAlloc2_type)(
|
||||
ULONG ParameterCount
|
||||
);
|
||||
|
||||
/* VirtualAlloc2() flags. */
|
||||
/* MinGW-w64 distributions, even those that declare VirtualAlloc2(),
|
||||
* lack it in import libraries, which results in a failure at link time.
|
||||
* Link it dynamically in such case.
|
||||
*/
|
||||
static VirtualAlloc2_type VirtualAlloc2_ptr;
|
||||
|
||||
#ifdef RTE_TOOLCHAIN_GCC
|
||||
|
||||
#define MEM_COALESCE_PLACEHOLDERS 0x00000001
|
||||
#define MEM_PRESERVE_PLACEHOLDER 0x00000002
|
||||
#define MEM_REPLACE_PLACEHOLDER 0x00004000
|
||||
#define MEM_RESERVE_PLACEHOLDER 0x00040000
|
||||
|
||||
/* Named exactly as the function, so that user code does not depend
|
||||
* on it being found at compile time or dynamically.
|
||||
*/
|
||||
static VirtualAlloc2_type VirtualAlloc2;
|
||||
|
||||
int
|
||||
eal_mem_win32api_init(void)
|
||||
{
|
||||
@ -89,7 +90,7 @@ eal_mem_win32api_init(void)
|
||||
int ret = 0;
|
||||
|
||||
/* Already done. */
|
||||
if (VirtualAlloc2 != NULL)
|
||||
if (VirtualAlloc2_ptr != NULL)
|
||||
return 0;
|
||||
|
||||
library = LoadLibraryA(library_name);
|
||||
@ -98,9 +99,9 @@ eal_mem_win32api_init(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
VirtualAlloc2 = (VirtualAlloc2_type)(
|
||||
VirtualAlloc2_ptr = (VirtualAlloc2_type)(
|
||||
(void *)GetProcAddress(library, function));
|
||||
if (VirtualAlloc2 == NULL) {
|
||||
if (VirtualAlloc2_ptr == NULL) {
|
||||
RTE_LOG_WIN32_ERR("GetProcAddress(\"%s\", \"%s\")\n",
|
||||
library_name, function);
|
||||
|
||||
@ -117,14 +118,15 @@ eal_mem_win32api_init(void)
|
||||
|
||||
#else
|
||||
|
||||
/* Stub in case VirtualAlloc2() is provided by the compiler. */
|
||||
/* Stub in case VirtualAlloc2() is provided by the toolchain. */
|
||||
int
|
||||
eal_mem_win32api_init(void)
|
||||
{
|
||||
VirtualAlloc2_ptr = VirtualAlloc2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* defined(MEM_RESERVE_PLACEHOLDER) */
|
||||
#endif /* defined(RTE_TOOLCHAIN_GCC) */
|
||||
|
||||
static HANDLE virt2phys_device = INVALID_HANDLE_VALUE;
|
||||
|
||||
@ -278,7 +280,7 @@ eal_mem_reserve(void *requested_addr, size_t size, int flags)
|
||||
|
||||
process = GetCurrentProcess();
|
||||
|
||||
virt = VirtualAlloc2(process, requested_addr, size,
|
||||
virt = VirtualAlloc2_ptr(process, requested_addr, size,
|
||||
MEM_RESERVE | MEM_RESERVE_PLACEHOLDER, PAGE_NOACCESS,
|
||||
NULL, 0);
|
||||
if (virt == NULL) {
|
||||
@ -364,7 +366,7 @@ eal_mem_commit(void *requested_addr, size_t size, int socket_id)
|
||||
}
|
||||
|
||||
flags = MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES;
|
||||
addr = VirtualAlloc2(process, requested_addr, size,
|
||||
addr = VirtualAlloc2_ptr(process, requested_addr, size,
|
||||
flags, PAGE_READWRITE, ¶m, param_count);
|
||||
if (addr == NULL) {
|
||||
/* Logging may overwrite GetLastError() result. */
|
||||
@ -406,7 +408,7 @@ eal_mem_decommit(void *addr, size_t size)
|
||||
}
|
||||
|
||||
flags = MEM_RESERVE | MEM_RESERVE_PLACEHOLDER;
|
||||
stub = VirtualAlloc2(
|
||||
stub = VirtualAlloc2_ptr(
|
||||
process, addr, size, flags, PAGE_NOACCESS, NULL, 0);
|
||||
if (stub == NULL) {
|
||||
/* We lost the race for the VA. */
|
||||
|
Loading…
Reference in New Issue
Block a user