Skip to content

Commit fad47c3

Browse files
authored
Merge pull request #320 from ldorau/Enable_the_proxy_library_on_Windows
Enable the proxy library on windows
2 parents 8ac6d3d + 06e8ee4 commit fad47c3

File tree

9 files changed

+173
-63
lines changed

9 files changed

+173
-63
lines changed

.github/workflows/basic.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ jobs:
232232
-B ${{env.BUILD_DIR}}
233233
${{matrix.toolset}}
234234
-DCMAKE_PREFIX_PATH="${{env.VCPKG_PATH}}"
235+
-DCMAKE_BUILD_TYPE=${{matrix.build_type}}
235236
-DCMAKE_C_COMPILER=${{matrix.compiler.c}}
236237
-DCMAKE_CXX_COMPILER=${{matrix.compiler.cxx}}
237238
-DUMF_BUILD_SHARED_LIBRARY=${{matrix.shared_library}}

CMakeLists.txt

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ option(USE_TSAN "Enable ThreadSanitizer checks" OFF)
2525
option(USE_MSAN "Enable MemorySanitizer checks" OFF)
2626
option(USE_VALGRIND "Enable Valgrind instrumentation" OFF)
2727

28+
# set UMF_PROXY_LIB_BASED_ON_POOL to one of: SCALABLE or JEMALLOC
29+
set(UMF_PROXY_LIB_BASED_ON_POOL SCALABLE CACHE STRING "A UMF pool the proxy library is based on (SCALABLE or JEMALLOC)" FORCE)
30+
2831
set(KNOWN_BUILD_TYPES Release Debug RelWithDebInfo MinSizeRel)
2932
string(REPLACE ";" " " KNOWN_BUILD_TYPES_STR "${KNOWN_BUILD_TYPES}")
3033

@@ -131,9 +134,13 @@ install(
131134
EXPORT ${PROJECT_NAME}-targets)
132135

133136
if(WINDOWS)
134-
# set PATH to DLLs on Windows
135-
set(DLL_PATH_LIST "PATH=path_list_append:../bin/$<CONFIG>")
136137
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
138+
# set PATH to DLLs on Windows
139+
set(DLL_PATH_LIST "PATH=path_list_append:${PROJECT_BINARY_DIR}/bin/$<CONFIG>")
140+
# add path to the proxy lib DLL
141+
set(DLL_PATH_LIST "${DLL_PATH_LIST};PATH=path_list_append:${PROJECT_BINARY_DIR}/src/proxy_lib")
142+
# MSVC implicitly adds $<CONFIG> to the output path
143+
set(DLL_PATH_LIST "${DLL_PATH_LIST};PATH=path_list_append:${PROJECT_BINARY_DIR}/src/proxy_lib/$<CONFIG>")
137144
endif()
138145

139146
pkg_check_modules(LIBHWLOC hwloc)
@@ -161,6 +168,32 @@ if(UMF_BUILD_LIBUMF_POOL_JEMALLOC AND (LINUX OR WINDOWS))
161168
set(DLL_PATH_LIST "${DLL_PATH_LIST};PATH=path_list_append:${JEMALLOC_LIBRARY_DIRS}/../bin")
162169
endif()
163170

171+
# set UMF_PROXY_LIB_ENABLED
172+
if(LINUX OR WINDOWS)
173+
# TODO: enable the proxy library in the Debug build on Windows
174+
if(WINDOWS AND NOT (CMAKE_BUILD_TYPE STREQUAL "Release"))
175+
message(STATUS "Disabling the proxy library, because it is supported only in the Release build on Windows (CMAKE_BUILD_TYPE = ${CMAKE_BUILD_TYPE})")
176+
elseif(UMF_PROXY_LIB_BASED_ON_POOL STREQUAL SCALABLE)
177+
if(UMF_BUILD_LIBUMF_POOL_SCALABLE)
178+
set(UMF_PROXY_LIB_ENABLED ON)
179+
set(PROXY_LIB_USES_SCALABLE_POOL ON)
180+
set(PROXY_LIBS umf scalable_pool)
181+
else()
182+
message(STATUS "Disabling the proxy library, because UMF_PROXY_LIB_BASED_ON_POOL==SCALABLE but UMF_BUILD_LIBUMF_POOL_SCALABLE is OFF")
183+
endif()
184+
elseif(UMF_PROXY_LIB_BASED_ON_POOL STREQUAL JEMALLOC)
185+
if(UMF_BUILD_LIBUMF_POOL_JEMALLOC)
186+
set(UMF_PROXY_LIB_ENABLED ON)
187+
set(PROXY_LIB_USES_JEMALLOC_POOL ON)
188+
set(PROXY_LIBS umf jemalloc_pool)
189+
else()
190+
message(STATUS "Disabling the proxy library, because UMF_PROXY_LIB_BASED_ON_POOL==JEMALLOC but UMF_BUILD_LIBUMF_POOL_JEMALLOC is OFF")
191+
endif()
192+
else()
193+
message(FATAL_ERROR "Proxy library: pool manager not chosen or set to a non-supported one (see UMF_PROXY_LIB_BASED_ON_POOL)")
194+
endif()
195+
endif()
196+
164197
add_subdirectory(src)
165198

166199
if(UMF_BUILD_TESTS)

src/CMakeLists.txt

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,6 @@ if(UMF_BUILD_LEVEL_ZERO_PROVIDER)
2626
message(STATUS "Level Zero include directory: ${LEVEL_ZERO_INCLUDE_DIRS}")
2727
endif()
2828

29-
# set UMF_PROXY_LIB_BASED_ON_POOL to one of:
30-
# - SCALABLE
31-
# - JEMALLOC
32-
set(UMF_PROXY_LIB_BASED_ON_POOL SCALABLE CACHE STRING "A UMF pool the proxy library is based on (SCALABLE or JEMALLOC)" FORCE)
33-
3429
add_subdirectory(utils)
3530

3631
set(UMF_LIBS umf_utils)
@@ -166,25 +161,6 @@ install(TARGETS umf
166161

167162
add_subdirectory(pool)
168163

169-
# TODO: enable proxy_lib on Windows
170-
if(LINUX)
171-
if(UMF_PROXY_LIB_BASED_ON_POOL STREQUAL SCALABLE)
172-
set(PROXY_LIB_USES_SCALABLE_POOL ON)
173-
set(PROXY_LIBS umf scalable_pool)
174-
if(UMF_BUILD_LIBUMF_POOL_SCALABLE)
175-
add_subdirectory(proxy_lib)
176-
else()
177-
message(STATUS "Disabling the proxy library, because UMF_PROXY_LIB_BASED_ON_POOL==SCALABLE but UMF_BUILD_LIBUMF_POOL_SCALABLE is OFF")
178-
endif()
179-
elseif(UMF_PROXY_LIB_BASED_ON_POOL STREQUAL JEMALLOC)
180-
set(PROXY_LIB_USES_JEMALLOC_POOL ON)
181-
set(PROXY_LIBS umf jemalloc_pool)
182-
if(UMF_BUILD_LIBUMF_POOL_JEMALLOC)
183-
add_subdirectory(proxy_lib)
184-
else()
185-
message(STATUS "Disabling the proxy library, because UMF_PROXY_LIB_BASED_ON_POOL==JEMALLOC but UMF_BUILD_LIBUMF_POOL_JEMALLOC is OFF")
186-
endif()
187-
else()
188-
message(FATAL_ERROR "Proxy library: pool manager not chosen or set to a non-supported one (see UMF_PROXY_LIB_BASED_ON_POOL)")
189-
endif()
164+
if(UMF_PROXY_LIB_ENABLED)
165+
add_subdirectory(proxy_lib)
190166
endif()

src/proxy_lib/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ add_umf_library(NAME umf_proxy
3737

3838
add_library(${PROJECT_NAME}::proxy ALIAS umf_proxy)
3939

40+
target_link_directories(umf_proxy PRIVATE ${LIBHWLOC_LIBRARY_DIRS})
41+
4042
if(PROXY_LIB_USES_SCALABLE_POOL)
4143
target_compile_definitions(umf_proxy PRIVATE PROXY_LIB_USES_SCALABLE_POOL=1)
4244
elseif(PROXY_LIB_USES_JEMALLOC_POOL)

src/proxy_lib/proxy_lib.c

Lines changed: 72 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@
2828
#endif
2929

3030
#include <assert.h>
31-
#include <stdlib.h>
32-
#include <string.h>
31+
#include <stdio.h>
3332

3433
#include <umf/memory_pool.h>
3534
#include <umf/memory_provider.h>
@@ -38,8 +37,27 @@
3837
#include "base_alloc_linear.h"
3938
#include "proxy_lib.h"
4039
#include "utils_common.h"
40+
41+
#ifdef _WIN32 /* Windows ***************************************/
42+
43+
#define _X86_
44+
#include <process.h>
45+
#include <synchapi.h>
46+
47+
#define UTIL_ONCE_FLAG INIT_ONCE
48+
#define UTIL_ONCE_FLAG_INIT INIT_ONCE_STATIC_INIT
49+
50+
void util_init_once(UTIL_ONCE_FLAG *flag, void (*onceCb)(void));
51+
52+
#else /* Linux *************************************************/
53+
54+
#include <stdlib.h>
55+
#include <string.h>
56+
4157
#include "utils_concurrency.h"
4258

59+
#endif /* _WIN32 ***********************************************/
60+
4361
/*
4462
* The UMF proxy library uses two memory allocators:
4563
* 1) the "LEAK" internal linear base allocator based on the anonymous mapped
@@ -100,9 +118,20 @@ void proxy_lib_create_common(void) {
100118
}
101119

102120
void proxy_lib_destroy_common(void) {
103-
// We cannot destroy 'Base_alloc_leak' nor 'Proxy_pool' nor 'OS_memory_provider',
104-
// because it could lead to use-after-free in the program's unloader
105-
// (for example _dl_fini() on Linux).
121+
if (util_is_running_in_proxy_lib()) {
122+
// We cannot destroy 'Base_alloc_leak' nor 'Proxy_pool' nor 'OS_memory_provider',
123+
// because it could lead to use-after-free in the program's unloader
124+
// (for example _dl_fini() on Linux).
125+
return;
126+
}
127+
128+
umf_memory_pool_handle_t pool = Proxy_pool;
129+
Proxy_pool = NULL;
130+
umfPoolDestroy(pool);
131+
132+
umf_memory_provider_handle_t provider = OS_memory_provider;
133+
OS_memory_provider = NULL;
134+
umfMemoryProviderDestroy(provider);
106135
}
107136

108137
/*****************************************************************************/
@@ -202,6 +231,34 @@ void *calloc(size_t nmemb, size_t size) {
202231
return ba_leak_calloc(nmemb, size);
203232
}
204233

234+
void free(void *ptr) {
235+
if (ptr == NULL) {
236+
return;
237+
}
238+
239+
if (ba_leak_free(ptr) == 0) {
240+
return;
241+
}
242+
243+
if (Proxy_pool) {
244+
if (umfPoolFree(Proxy_pool, ptr) != UMF_RESULT_SUCCESS) {
245+
fprintf(stderr, "error: umfPoolFree() failed\n");
246+
assert(0);
247+
}
248+
return;
249+
}
250+
251+
assert(0);
252+
return;
253+
}
254+
255+
#ifdef _WIN32
256+
void _free_dbg(void *userData, int blockType) {
257+
(void)blockType; // unused
258+
free(userData);
259+
}
260+
#endif
261+
205262
void *realloc(void *ptr, size_t size) {
206263
if (ptr == NULL) {
207264
return malloc(size);
@@ -228,27 +285,6 @@ void *realloc(void *ptr, size_t size) {
228285
return NULL;
229286
}
230287

231-
void free(void *ptr) {
232-
if (ptr == NULL) {
233-
return;
234-
}
235-
236-
if (ba_leak_free(ptr) == 0) {
237-
return;
238-
}
239-
240-
if (Proxy_pool) {
241-
if (umfPoolFree(Proxy_pool, ptr) != UMF_RESULT_SUCCESS) {
242-
fprintf(stderr, "error: umfPoolFree() failed\n");
243-
assert(0);
244-
}
245-
return;
246-
}
247-
248-
assert(0);
249-
return;
250-
}
251-
252288
void *aligned_alloc(size_t alignment, size_t size) {
253289
if (!was_called_from_umfPool && Proxy_pool) {
254290
was_called_from_umfPool = 1;
@@ -260,7 +296,17 @@ void *aligned_alloc(size_t alignment, size_t size) {
260296
return ba_leak_aligned_alloc(alignment, size);
261297
}
262298

299+
#ifdef _WIN32
300+
size_t _msize(void *ptr) {
301+
#else
263302
size_t malloc_usable_size(void *ptr) {
303+
#endif
304+
305+
// a check to verify we are running the proxy library
306+
if (ptr == (void *)0x01) {
307+
return 0xDEADBEEF;
308+
}
309+
264310
if (!was_called_from_umfPool && Proxy_pool) {
265311
was_called_from_umfPool = 1;
266312
size_t size = umfPoolMallocUsableSize(Proxy_pool, ptr);

src/proxy_lib/proxy_lib.def

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ EXPORTS
99
DllMain
1010
aligned_alloc
1111
calloc
12+
_free_dbg
1213
free
1314
malloc
14-
malloc_usable_size
15+
_msize
1516
realloc

test/CMakeLists.txt

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@ function(add_umf_test)
3737
set(LIB_DIRS ${LIB_DIRS} ${JEMALLOC_LIBRARY_DIRS})
3838
endif()
3939

40-
set(TEST_LIBS test_common
40+
set(TEST_LIBS
41+
test_common
4142
umf
43+
${ARG_LIBS}
4244
GTest::gtest_main
43-
${LIBS_OPTIONAL}
44-
${ARG_LIBS})
45+
${LIBS_OPTIONAL})
46+
4547
add_umf_executable(NAME ${TEST_TARGET_NAME} SRCS ${ARG_SRCS} LIBS ${TEST_LIBS})
4648

4749
target_link_directories(${TEST_TARGET_NAME} PRIVATE ${LIB_DIRS})
@@ -171,3 +173,15 @@ add_umf_test(NAME base_alloc_linear
171173
add_umf_test(NAME base_alloc_global
172174
SRCS ${BA_SOURCES_FOR_TEST} pools/pool_base_alloc.cpp malloc_compliance_tests.cpp
173175
LIBS umf_utils)
176+
177+
# tests for the proxy library
178+
if(UMF_PROXY_LIB_ENABLED AND UMF_BUILD_SHARED_LIBRARY)
179+
add_umf_test(NAME proxy_lib_basic
180+
SRCS test_proxy_lib.cpp
181+
LIBS umf_proxy)
182+
183+
# the memoryPool test run with the proxy library
184+
add_umf_test(NAME proxy_lib_memoryPool
185+
SRCS memoryPoolAPI.cpp malloc_compliance_tests.cpp
186+
LIBS umf_proxy)
187+
endif()

test/test_installation.py

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,20 @@ def _create_match_list(self) -> List[str]:
6969
lib_ext_shared = "dylib"
7070
lib_prefix = "lib"
7171

72+
# Currently the proxy library uses and requires the scalable pool
73+
# The proxy library does not work in the Debug build on Windows yet.
74+
if ("scalable_pool" in self.pools) and not (platform.system() == "Windows" and self.build_type == "debug"):
75+
is_umf_proxy = True
76+
else:
77+
is_umf_proxy = False
78+
7279
bin = []
73-
if platform.system() == "Windows" and self.shared_library:
80+
if platform.system() == "Windows" and (self.shared_library or is_umf_proxy):
7481
bin.append("bin")
75-
bin.append("bin/umf.dll")
82+
if self.shared_library:
83+
bin.append("bin/umf.dll")
84+
if is_umf_proxy:
85+
bin.append("bin/umf_proxy.dll")
7686

7787
include_dir = Path(self.workspace_dir, "include")
7888
include = [
@@ -94,9 +104,7 @@ def _create_match_list(self) -> List[str]:
94104
lib.append(f"lib/{lib_prefix}{pool}.{lib_ext_static}")
95105
lib_ext = lib_ext_shared if self.shared_library else lib_ext_static
96106
lib.append(f"lib/{lib_prefix}umf.{lib_ext}")
97-
if platform.system() != "Windows" and (
98-
"jemalloc_pool" in self.pools or "scalable_pool" in self.pools
99-
):
107+
if is_umf_proxy:
100108
lib.append(f"lib/{lib_prefix}umf_proxy.{lib_ext_shared}")
101109
lib.append(f"lib/{lib_prefix}umf_utils.{lib_ext_static}")
102110

test/test_proxy_lib.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* Copyright (C) 2024 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 <malloc.h>
9+
10+
#include "base.hpp"
11+
#include "test_helpers.h"
12+
13+
using umf_test::test;
14+
15+
TEST_F(test, proxyLibBasic) {
16+
17+
::free(::malloc(64));
18+
19+
// a check to verify we are running the proxy library
20+
void *ptr = (void *)0x01;
21+
#ifdef _WIN32
22+
size_t size = _msize(ptr);
23+
#elif __APPLE__
24+
size_t size = ::malloc_size(ptr);
25+
#else
26+
size_t size = ::malloc_usable_size(ptr);
27+
#endif
28+
UT_ASSERTeq(size, 0xDEADBEEF);
29+
}

0 commit comments

Comments
 (0)