Skip to content

Commit 253de2c

Browse files
committed
Add proxy library
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent c6a5e5b commit 253de2c

File tree

9 files changed

+382
-0
lines changed

9 files changed

+382
-0
lines changed

.github/workflows/codeql.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ jobs:
5353
-DUMF_FORMAT_CODE_STYLE=ON
5454
-DUMF_DEVELOPER_MODE=ON
5555
-DUMF_ENABLE_POOL_TRACKING=ON
56+
-DUMF_BUILD_LIBUMF_POOL_JEMALLOC=ON
5657
-DUMF_BUILD_LIBUMF_POOL_SCALABLE=${{matrix.pool_scalable}}
5758
5859
- name: Build

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,4 @@ install(TARGETS umf
103103
)
104104

105105
add_subdirectory(pool)
106+
add_subdirectory(proxy_lib)

src/proxy_lib/CMakeLists.txt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Copyright (C) 2023-2024 Intel Corporation
2+
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
include(${UMF_CMAKE_SOURCE_DIR}/cmake/helpers.cmake)
6+
7+
set(PROXY_LIBS umf jemalloc_pool)
8+
9+
set(PROXY_SOURCES
10+
proxy_lib.c
11+
)
12+
13+
set(PROXY_SOURCES_LINUX
14+
proxy_lib_linux.c
15+
)
16+
17+
set(PROXY_SOURCES_WINDOWS
18+
proxy_lib_windows.c
19+
)
20+
21+
set(PROXY_SOURCES_MACOSX
22+
proxy_lib_linux.c
23+
)
24+
25+
if(LINUX)
26+
set(PROXY_SOURCES ${PROXY_SOURCES} ${PROXY_SOURCES_LINUX})
27+
elseif(WINDOWS)
28+
set(PROXY_SOURCES ${PROXY_SOURCES} ${PROXY_SOURCES_WINDOWS})
29+
elseif(MACOSX)
30+
set(PROXY_SOURCES ${PROXY_SOURCES} ${PROXY_SOURCES_MACOSX})
31+
endif()
32+
33+
add_umf_library(NAME umf_proxy
34+
TYPE SHARED
35+
SRCS ${PROXY_SOURCES}
36+
LIBS ${PROXY_LIBS}
37+
LINUX_MAP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/proxy_lib.map
38+
WINDOWS_DEF_FILE ${CMAKE_CURRENT_SOURCE_DIR}/proxy_lib.def)
39+
40+
add_library(${PROJECT_NAME}::proxy ALIAS umf_proxy)
41+
42+
target_include_directories(umf_proxy PUBLIC
43+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
44+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src/utils>
45+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
46+
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
47+
)
48+
49+
install(TARGETS umf_proxy
50+
EXPORT ${PROJECT_NAME}-targets)

src/proxy_lib/proxy_lib.c

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
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 <assert.h>
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <string.h>
12+
13+
#include <umf/memory_pool.h>
14+
#include <umf/memory_provider.h>
15+
#include <umf/pools/pool_jemalloc.h>
16+
#include <umf/providers/provider_os_memory.h>
17+
18+
#include "proxy_lib.h"
19+
#include "utils_common.h"
20+
#include "utils_concurrency.h"
21+
22+
static UTIL_ONCE_FLAG alloc_hooks_are_initialized = UTIL_ONCE_FLAG_INIT;
23+
24+
static umf_memory_provider_handle_t OS_memory_provider = NULL;
25+
static umf_memory_pool_handle_t Proxy_pool = NULL;
26+
27+
// it protects us from recursion in umfPool*()
28+
static __TLS int was_called_from_umfPool = 0;
29+
30+
malloc_func_t System_malloc_func;
31+
calloc_func_t System_calloc_func;
32+
realloc_func_t System_realloc_func;
33+
free_func_t System_free_func;
34+
aligned_alloc_func_t System_aligned_alloc_func;
35+
36+
/******************************************************************************/
37+
38+
void proxy_lib_create_common(void) {
39+
umf_os_memory_provider_params_t os_params =
40+
umfOsMemoryProviderParamsDefault();
41+
enum umf_result_t umf_result;
42+
43+
umf_result = umfMemoryProviderCreate(umfOsMemoryProviderOps(), &os_params,
44+
&OS_memory_provider);
45+
if (umf_result != UMF_RESULT_SUCCESS) {
46+
fprintf(stderr, "error: creating OS memory provider failed\n");
47+
exit(-1);
48+
}
49+
50+
umf_result = umfPoolCreate(umfJemallocPoolOps(), OS_memory_provider, NULL,
51+
0, &Proxy_pool);
52+
if (umf_result != UMF_RESULT_SUCCESS) {
53+
fprintf(stderr, "error: creating jemalloc pool manager failed\n");
54+
exit(-1);
55+
}
56+
}
57+
58+
void proxy_lib_destroy_common(void) {
59+
umf_memory_pool_handle_t pool = Proxy_pool;
60+
Proxy_pool = NULL;
61+
umfPoolDestroy(pool);
62+
umfMemoryProviderDestroy(OS_memory_provider);
63+
}
64+
65+
/******************************************************************************/
66+
67+
static inline void *system_malloc(size_t size) {
68+
util_init_once(&alloc_hooks_are_initialized, proxy_lib_system_alloc_init);
69+
return System_malloc_func(size);
70+
}
71+
72+
static inline void *system_calloc(size_t nmemb, size_t size) {
73+
util_init_once(&alloc_hooks_are_initialized, proxy_lib_system_alloc_init);
74+
return System_calloc_func(nmemb, size);
75+
}
76+
77+
static inline void *system_realloc(void *ptr, size_t size) {
78+
util_init_once(&alloc_hooks_are_initialized, proxy_lib_system_alloc_init);
79+
return System_realloc_func(ptr, size);
80+
}
81+
82+
static inline void system_free(void *ptr) {
83+
util_init_once(&alloc_hooks_are_initialized, proxy_lib_system_alloc_init);
84+
System_free_func(ptr);
85+
}
86+
87+
static inline void *system_aligned_alloc(size_t alignment, size_t size) {
88+
util_init_once(&alloc_hooks_are_initialized, proxy_lib_system_alloc_init);
89+
if (!System_aligned_alloc_func) {
90+
return NULL; // unsupported
91+
}
92+
return System_aligned_alloc_func(alignment, size);
93+
}
94+
95+
/******************************************************************************/
96+
97+
WIN32_dllexport void *malloc(size_t size) {
98+
if (!was_called_from_umfPool && Proxy_pool) {
99+
was_called_from_umfPool = 1;
100+
void *ptr = umfPoolMalloc(Proxy_pool, size);
101+
was_called_from_umfPool = 0;
102+
return ptr;
103+
}
104+
105+
return system_malloc(size);
106+
}
107+
108+
WIN32_dllexport void *calloc(size_t nmemb, size_t size) {
109+
if (!was_called_from_umfPool && Proxy_pool) {
110+
was_called_from_umfPool = 1;
111+
void *ptr = umfPoolCalloc(Proxy_pool, nmemb, size);
112+
was_called_from_umfPool = 0;
113+
return ptr;
114+
}
115+
116+
return system_calloc(nmemb, size);
117+
}
118+
119+
WIN32_dllexport void *realloc(void *ptr, size_t size) {
120+
if (!was_called_from_umfPool && Proxy_pool) {
121+
was_called_from_umfPool = 1;
122+
void *new_ptr = umfPoolRealloc(Proxy_pool, ptr, size);
123+
was_called_from_umfPool = 0;
124+
return new_ptr;
125+
}
126+
127+
return system_realloc(ptr, size);
128+
}
129+
130+
WIN32_dllexport void free(void *ptr) {
131+
if (ptr == NULL) {
132+
return;
133+
}
134+
135+
umf_memory_pool_handle_t pool = umfPoolByPtr(ptr);
136+
if (pool == NULL) {
137+
system_free(ptr);
138+
return;
139+
}
140+
141+
enum umf_result_t umf_result = umfPoolFree(pool, ptr);
142+
if (umf_result != UMF_RESULT_SUCCESS) {
143+
fprintf(stderr, "error: umfPoolFree() failed\n");
144+
assert(0);
145+
}
146+
}
147+
148+
WIN32_dllexport void *aligned_alloc(size_t alignment, size_t size) {
149+
if (!was_called_from_umfPool && Proxy_pool) {
150+
was_called_from_umfPool = 1;
151+
void *ptr = umfPoolAlignedMalloc(Proxy_pool, size, alignment);
152+
was_called_from_umfPool = 0;
153+
return ptr;
154+
}
155+
156+
return system_aligned_alloc(alignment, size);
157+
}
158+
159+
WIN32_dllexport size_t malloc_usable_size(void *ptr) {
160+
if (!was_called_from_umfPool && Proxy_pool) {
161+
was_called_from_umfPool = 1;
162+
size_t size = umfPoolMallocUsableSize(Proxy_pool, ptr);
163+
was_called_from_umfPool = 0;
164+
return size;
165+
}
166+
167+
return 0; // unsupported in this case
168+
}

src/proxy_lib/proxy_lib.def

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
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+
LIBRARY UMF_PROXY
8+
EXPORTS
9+
aligned_alloc
10+
calloc
11+
free
12+
malloc
13+
malloc_usable_size
14+
realloc

src/proxy_lib/proxy_lib.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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+
#ifndef UMF_PROXY_LIB_H
9+
#define UMF_PROXY_LIB_H 1
10+
11+
#include <stddef.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
#ifdef _WIN32
18+
#define WIN32_dllexport __declspec(dllexport)
19+
#else
20+
#define WIN32_dllexport
21+
#endif
22+
23+
typedef void *(*malloc_func_t)(size_t size);
24+
typedef void *(*calloc_func_t)(size_t nmemb, size_t size);
25+
typedef void *(*realloc_func_t)(void *ptr, size_t size);
26+
typedef void (*free_func_t)(void *ptr);
27+
typedef void *(*aligned_alloc_func_t)(size_t alignment, size_t size);
28+
29+
extern malloc_func_t System_malloc_func;
30+
extern calloc_func_t System_calloc_func;
31+
extern realloc_func_t System_realloc_func;
32+
extern free_func_t System_free_func;
33+
extern aligned_alloc_func_t System_aligned_alloc_func;
34+
35+
void proxy_lib_create_common(void);
36+
void proxy_lib_destroy_common(void);
37+
void proxy_lib_system_alloc_init(void);
38+
39+
#ifdef __cplusplus
40+
}
41+
#endif
42+
43+
#endif /* UMF_PROXY_LIB_H */

src/proxy_lib/proxy_lib.map

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Copyright (C) 2024 Intel Corporation
2+
# Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
3+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
# linker VERSION script
6+
7+
{
8+
global:
9+
aligned_alloc;
10+
calloc;
11+
free;
12+
malloc;
13+
malloc_usable_size;
14+
realloc;
15+
local:
16+
*;
17+
};

src/proxy_lib/proxy_lib_linux.c

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
*
3+
* Copyright (C) 2024 Intel Corporation
4+
*
5+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
6+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
*
8+
*/
9+
10+
#define _GNU_SOURCE
11+
#include <dlfcn.h>
12+
13+
#include <stdio.h>
14+
#include <stdlib.h>
15+
16+
#include "proxy_lib.h"
17+
18+
void __attribute__((constructor(101))) proxy_lib_create(void) {
19+
proxy_lib_create_common();
20+
}
21+
22+
void __attribute__((destructor(101))) proxy_lib_destroy(void) {
23+
proxy_lib_destroy_common();
24+
}
25+
26+
void proxy_lib_system_alloc_init(void) {
27+
// ISO C forbids conversion of object pointer to function pointer type [-Werror=pedantic]
28+
*((void **)(&System_malloc_func)) = dlsym(RTLD_NEXT, "malloc");
29+
*((void **)(&System_calloc_func)) = dlsym(RTLD_NEXT, "calloc");
30+
*((void **)(&System_realloc_func)) = dlsym(RTLD_NEXT, "realloc");
31+
*((void **)(&System_free_func)) = dlsym(RTLD_NEXT, "free");
32+
*((void **)(&System_aligned_alloc_func)) =
33+
dlsym(RTLD_NEXT, "aligned_alloc");
34+
35+
// System_aligned_alloc_func can be NULL
36+
if (!System_malloc_func || !System_calloc_func || !System_realloc_func ||
37+
!System_free_func) {
38+
fprintf(stderr, "error: cannot find libc alloc functions\n");
39+
exit(-1);
40+
}
41+
}

src/proxy_lib/proxy_lib_windows.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
*
3+
* Copyright (C) 2024 Intel Corporation
4+
*
5+
* Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
6+
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7+
*
8+
*/
9+
10+
#include <Windows.h>
11+
12+
#include <stdio.h>
13+
14+
#include "proxy_lib.h"
15+
16+
static void proxy_lib_create(void) { proxy_lib_create_common(); }
17+
18+
static void proxy_lib_destroy(void) { proxy_lib_destroy_common(); }
19+
20+
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
21+
if (fdwReason == DLL_PROCESS_DETACH) {
22+
proxy_lib_destroy();
23+
} else if (fdwReason == DLL_PROCESS_ATTACH) {
24+
proxy_lib_create();
25+
}
26+
return TRUE;
27+
}
28+
29+
void proxy_lib_system_alloc_init(void) {
30+
/* there is a memleak here, we should unload this library in the destructor but there is no such thing */
31+
HMODULE mod = LoadLibrary(TEXT("msvcrt.dll"));
32+
33+
// ISO C forbids conversion of object pointer to function pointer type [-Werror=pedantic]
34+
*((void **)(&System_malloc_func)) = GetProcAddress(mod, "malloc");
35+
*((void **)(&System_calloc_func)) = GetProcAddress(mod, "calloc");
36+
*((void **)(&System_realloc_func)) = GetProcAddress(mod, "realloc");
37+
*((void **)(&System_free_func)) = GetProcAddress(mod, "free");
38+
*((void **)(&System_aligned_alloc_func)) =
39+
GetProcAddress(mod, "aligned_alloc");
40+
41+
// System_aligned_alloc_func can be NULL
42+
if (!System_malloc_func || !System_calloc_func || !System_realloc_func ||
43+
!System_free_func) {
44+
fprintf(stderr, "error: cannot find libc alloc functions\n");
45+
exit(-1);
46+
}
47+
}

0 commit comments

Comments
 (0)