[1/2] eal/windows: fix build with MinGW-w64 8.0.0
diff mbox series

Message ID 20201201163959.9590-1-dmitry.kozliuk@gmail.com
State Accepted
Delegated to: Thomas Monjalon
Headers show
Series
  • [1/2] eal/windows: fix build with MinGW-w64 8.0.0
Related show

Checks

Context Check Description
ci/checkpatch success coding style OK

Commit Message

Dmitry Kozlyuk Dec. 1, 2020, 4:39 p.m. UTC
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: 2a5d547a4a9b ("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>
---
 lib/librte_eal/windows/eal_memory.c | 42 +++++++++++++++--------------
 1 file changed, 22 insertions(+), 20 deletions(-)

Patch
diff mbox series

diff --git a/lib/librte_eal/windows/eal_memory.c b/lib/librte_eal/windows/eal_memory.c
index 7f8d3c2fa..2cf5a5e64 100644
--- a/lib/librte_eal/windows/eal_memory.c
+++ b/lib/librte_eal/windows/eal_memory.c
@@ -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, &param, 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. */