Skip to content

Commit 90dd57e

Browse files
committed
Enable OS memory provider on Windows
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent b6b4ffd commit 90dd57e

File tree

8 files changed

+194
-17
lines changed

8 files changed

+194
-17
lines changed

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,11 @@ install(
111111
TARGETS umf_headers
112112
EXPORT ${PROJECT_NAME}-targets)
113113

114+
if(UMF_BUILD_OS_MEMORY_PROVIDER AND (LINUX OR WINDOWS))
115+
# Do not use pkgconfig, because it sets wrong paths on Windows
116+
find_package(LIBHWLOC REQUIRED hwloc)
117+
endif()
118+
114119
add_subdirectory(src)
115120

116121
if(UMF_BUILD_TESTS)

cmake/FindLIBHWLOC.cmake

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,23 @@ message(STATUS "Checking for module 'libhwloc' using find_library()")
77
find_library(LIBHWLOC_LIBRARY NAMES libhwloc hwloc)
88
set(LIBHWLOC_LIBRARIES ${LIBHWLOC_LIBRARY})
99

10+
find_file(LIBHWLOC_HEADER NAMES hwloc.h HINTS /usr/include/ ${CMAKE_PREFIX_PATH}/include)
11+
get_filename_component(LIBHWLOC_INCLUDE_DIR ${LIBHWLOC_HEADER} DIRECTORY)
12+
set(LIBHWLOC_INCLUDE_DIRS ${LIBHWLOC_INCLUDE_DIR})
13+
14+
if(WINDOWS)
15+
find_file(LIBHWLOC_DLL NAMES hwloc-15.dll libhwloc-15.dll HINTS ${CMAKE_PREFIX_PATH}/bin)
16+
get_filename_component(LIBHWLOC_DLL_DIR ${LIBHWLOC_DLL} DIRECTORY)
17+
set(LIBHWLOC_DLL_DIRS ${LIBHWLOC_DLL_DIR})
18+
endif()
19+
1020
if(LIBHWLOC_LIBRARY)
1121
message(STATUS " Found libhwloc using find_library()")
22+
message(STATUS " LIBHWLOC_LIBRARIES = ${LIBHWLOC_LIBRARIES}")
23+
message(STATUS " LIBHWLOC_INCLUDE_DIRS = ${LIBHWLOC_INCLUDE_DIRS}")
24+
if(WINDOWS)
25+
message(STATUS " LIBHWLOC_DLL_DIRS = ${LIBHWLOC_DLL_DIRS}")
26+
endif()
1227
else()
1328
set(MSG_NOT_FOUND "libhwloc NOT found (set CMAKE_PREFIX_PATH to point the location)")
1429
if(LIBHWLOC_FIND_REQUIRED)

src/CMakeLists.txt

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ set(UMF_SOURCES_MACOSX
5353
)
5454

5555
# Compile definitions for UMF library
56-
# TODO: Cleanup the compile definitions across all the Cmake files
57-
set(UMF_COMPILE_DEFINITIONS "")
56+
# TODO: Cleanup the compile definitions across all the CMake files
57+
set(UMF_PUBLIC_COMPILE_DEFINITIONS "")
5858

5959
if(UMF_BUILD_OS_MEMORY_PROVIDER)
6060
set(UMF_SOURCES_LINUX ${UMF_SOURCES_LINUX}
@@ -64,16 +64,14 @@ if(UMF_BUILD_OS_MEMORY_PROVIDER)
6464
memspaces/memspace_numa.c
6565
memspaces/memspace_host_all.c)
6666

67-
if(LINUX)
68-
if(PkgConfig_FOUND)
69-
pkg_check_modules(LIBHWLOC hwloc)
70-
endif()
71-
if(NOT LIBHWLOC_FOUND)
72-
find_package(LIBHWLOC REQUIRED hwloc)
73-
endif()
67+
set(UMF_SOURCES_WINDOWS ${UMF_SOURCES_WINDOWS}
68+
provider/provider_os_memory.c
69+
provider/provider_os_memory_windows.c)
70+
71+
if(LINUX OR WINDOWS)
7472
set(UMF_LIBS ${UMF_LIBS} ${LIBHWLOC_LIBRARIES})
75-
# Currently, OS provider is only built for Linux
76-
set(UMF_COMPILE_DEFINITIONS ${UMF_COMPILE_DEFINITIONS} "UMF_BUILD_OS_MEMORY_PROVIDER=1")
73+
# Currently, OS provider is only built for Linux and Windows
74+
set(UMF_PUBLIC_COMPILE_DEFINITIONS ${UMF_PUBLIC_COMPILE_DEFINITIONS} "UMF_BUILD_OS_MEMORY_PROVIDER=1")
7775
endif()
7876
endif()
7977

@@ -86,13 +84,22 @@ elseif(MACOSX)
8684
endif()
8785

8886
if(UMF_BUILD_SHARED_LIBRARY)
87+
if(WINDOWS)
88+
# TODO: replace that with generating def and map files
89+
if(UMF_BUILD_OS_MEMORY_PROVIDER)
90+
set(UMF_DEF_FILE "libumf.def")
91+
else()
92+
set(UMF_DEF_FILE "libumf_noOS.def")
93+
endif()
94+
endif()
95+
8996
add_umf_library(NAME umf
9097
TYPE SHARED
9198
SRCS ${UMF_SOURCES}
9299
LIBS ${UMF_LIBS}
93100
LINUX_MAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libumf.map
94-
WINDOWS_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/libumf.def)
95-
set(UMF_COMPILE_DEFINITIONS ${UMF_COMPILE_DEFINITIONS} "UMF_SHARED_LIBRARY")
101+
WINDOWS_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${UMF_DEF_FILE})
102+
set(UMF_PUBLIC_COMPILE_DEFINITIONS ${UMF_PUBLIC_COMPILE_DEFINITIONS} "UMF_SHARED_LIBRARY")
96103
set_target_properties(umf PROPERTIES
97104
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_UMF_OUTPUT_DIRECTORY})
98105
else()
@@ -102,7 +109,7 @@ else()
102109
LIBS ${UMF_LIBS})
103110
endif()
104111

105-
target_compile_definitions(umf PUBLIC ${UMF_COMPILE_DEFINITIONS})
112+
target_compile_definitions(umf PUBLIC ${UMF_PUBLIC_COMPILE_DEFINITIONS})
106113

107114
if (UMF_ENABLE_POOL_TRACKING)
108115
target_sources(umf PRIVATE memory_pool_tracking.c)
@@ -112,6 +119,10 @@ endif()
112119

113120
add_library(${PROJECT_NAME}::umf ALIAS umf)
114121

122+
if(LIBHWLOC_INCLUDE_DIRS)
123+
target_include_directories(umf PRIVATE ${LIBHWLOC_INCLUDE_DIRS})
124+
endif()
125+
115126
target_include_directories(umf PUBLIC
116127
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
117128
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>

src/libumf.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ EXPORTS
3939
umfPoolMallocUsableSize
4040
umfPoolRealloc
4141
umfProxyPoolOps
42+
umfOsMemoryProviderOps

src/libumf_noOS.def

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
;;;; Begin Copyright Notice
2+
; Copyright (C) 2024 Intel Corporation
3+
; Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
4+
; SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
5+
;;;; End Copyright Notice
6+
7+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
8+
; TODO: this is a TEMPORARY solution.
9+
; The def file should be generated
10+
; depending on the chosen configuration.
11+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
12+
13+
LIBRARY umf
14+
15+
VERSION 1.0
16+
17+
EXPORTS
18+
DllMain
19+
umfFree
20+
umfGetLastFailedMemoryProvider
21+
umfMemoryProviderAlloc
22+
umfMemoryProviderAllocationMerge
23+
umfMemoryProviderAllocationSplit
24+
umfMemoryProviderCreate
25+
umfMemoryProviderCreateFromMemspace
26+
umfMemoryProviderDestroy
27+
umfMemoryProviderFree
28+
umfMemoryProviderGetLastNativeError
29+
umfMemoryProviderGetMinPageSize
30+
umfMemoryProviderGetName
31+
umfMemoryProviderGetRecommendedPageSize
32+
umfMemoryProviderPurgeForce
33+
umfMemoryProviderPurgeLazy
34+
umfMemspaceDestroy
35+
umfPoolAlignedMalloc
36+
umfPoolByPtr
37+
umfPoolCalloc
38+
umfPoolCreate
39+
umfPoolCreateFromMemspace
40+
umfPoolDestroy
41+
umfPoolFree
42+
umfPoolGetLastAllocationError
43+
umfPoolGetMemoryProvider
44+
umfPoolMalloc
45+
umfPoolMallocUsableSize
46+
umfPoolRealloc
47+
umfProxyPoolOps

src/provider/provider_os_memory.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@
55
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
*/
77

8+
#ifdef _WIN32
9+
#pragma warning(push)
10+
// Disable the warning:
11+
// hwloc-win64-build-2.10.0\include\hwloc/helper.h(1266):
12+
// warning C4996: 'sscanf': This function or variable may be unsafe.
13+
// Consider using sscanf_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS.
14+
#pragma warning(disable : 4996)
15+
#include <hwloc.h>
16+
#pragma warning(pop)
17+
#else
18+
#include <hwloc.h>
19+
#endif
20+
821
#include <assert.h>
922
#include <errno.h>
1023
#include <hwloc.h>
@@ -464,7 +477,9 @@ static umf_result_t os_alloc(void *provider, size_t size, size_t alignment,
464477
if (os_provider->traces) {
465478
perror("binding memory to NUMA node failed");
466479
}
467-
if (errno != ENOSYS) { // ENOSYS - Function not implemented
480+
// TODO: (errno == 0) when hwloc_set_area_membind() fails on Windows - ignore this temporarily
481+
if (errno != ENOSYS &&
482+
errno != 0) { // ENOSYS - Function not implemented
468483
// Do not error out if memory binding is not implemented at all (like in case of WSL on Windows).
469484
goto err_unmap;
470485
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright (C) 2023 Intel Corporation
3+
*
4+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
5+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
*/
7+
8+
#include <windows.h>
9+
10+
#include <assert.h>
11+
#include <stdio.h>
12+
#include <string.h>
13+
#include <sysinfoapi.h>
14+
15+
#include <umf/providers/provider_os_memory.h>
16+
17+
#include "utils_concurrency.h"
18+
19+
static UTIL_ONCE_FLAG Page_size_is_initialized = UTIL_ONCE_FLAG_INIT;
20+
static size_t Page_size;
21+
22+
int os_translate_mem_protection_flags(unsigned protection) {
23+
switch (protection) {
24+
case UMF_PROTECTION_NONE:
25+
return PAGE_NOACCESS;
26+
case UMF_PROTECTION_EXEC:
27+
return PAGE_EXECUTE;
28+
case (UMF_PROTECTION_EXEC | UMF_PROTECTION_READ):
29+
return PAGE_EXECUTE_READ;
30+
case (UMF_PROTECTION_EXEC | UMF_PROTECTION_READ | UMF_PROTECTION_WRITE):
31+
return PAGE_EXECUTE_READWRITE;
32+
case (UMF_PROTECTION_EXEC | UMF_PROTECTION_WRITE):
33+
return PAGE_EXECUTE_WRITECOPY;
34+
case UMF_PROTECTION_READ:
35+
return PAGE_READONLY;
36+
case (UMF_PROTECTION_READ | UMF_PROTECTION_WRITE):
37+
return PAGE_READWRITE;
38+
case UMF_PROTECTION_WRITE:
39+
return PAGE_WRITECOPY;
40+
}
41+
fprintf(stderr,
42+
"os_translate_mem_protection_flags(): unsupported protection flag: "
43+
"%u\n",
44+
protection);
45+
assert(0);
46+
return -1;
47+
}
48+
49+
void *os_mmap(void *hint_addr, size_t length, int prot) {
50+
return VirtualAlloc(hint_addr, length, MEM_RESERVE | MEM_COMMIT, prot);
51+
}
52+
53+
int os_munmap(void *addr, size_t length) {
54+
// If VirtualFree() succeeds, the return value is nonzero.
55+
// If VirtualFree() fails, the return value is 0 (zero).
56+
(void)length; // unused
57+
return (VirtualFree(addr, 0, MEM_RELEASE) == 0);
58+
}
59+
60+
int os_purge(void *addr, size_t length, int advice) {
61+
// If VirtualFree() succeeds, the return value is nonzero.
62+
// If VirtualFree() fails, the return value is 0 (zero).
63+
(void)advice; // unused
64+
return (VirtualFree(addr, length, MEM_DECOMMIT) == 0);
65+
}
66+
67+
static void _os_get_page_size(void) {
68+
SYSTEM_INFO SystemInfo;
69+
GetSystemInfo(&SystemInfo);
70+
Page_size = SystemInfo.dwPageSize;
71+
}
72+
73+
size_t os_get_page_size(void) {
74+
util_init_once(&Page_size_is_initialized, _os_get_page_size);
75+
return Page_size;
76+
}
77+
78+
void os_strerror(int errnum, char *buf, size_t buflen) {
79+
strerror_s(buf, buflen, errnum);
80+
}

test/CMakeLists.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,11 @@ function(add_umf_test)
5050
set_tests_properties(${TEST_NAME} PROPERTIES LABELS "umf")
5151

5252
if(WIN32)
53-
set_property(TEST ${TEST_NAME} PROPERTY ENVIRONMENT_MODIFICATION
54-
"PATH=path_list_append:../bin/$<CONFIG>")
53+
set(PATH_LIST "PATH=path_list_append:../bin/$<CONFIG>")
54+
if(LIBHWLOC_DLL_DIRS)
55+
set(PATH_LIST "${PATH_LIST};PATH=path_list_append:${LIBHWLOC_DLL_DIRS}")
56+
endif()
57+
set_property(TEST ${TEST_NAME} PROPERTY ENVIRONMENT_MODIFICATION "${PATH_LIST}")
5558
endif()
5659

5760
if (UMF_ENABLE_POOL_TRACKING)

0 commit comments

Comments
 (0)