Skip to content

Commit 9d2aec5

Browse files
committed
Enable size threshold in the proxy library on_Windows
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent 4ac6b3e commit 9d2aec5

File tree

2 files changed

+44
-38
lines changed

2 files changed

+44
-38
lines changed

src/proxy_lib/proxy_lib.c

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ void utils_init_once(UTIL_ONCE_FLAG *flag, void (*onceCb)(void));
101101
* of a UMF pool to allocate memory needed by an application. It should be freed
102102
* by an application.
103103
*/
104-
#ifndef _WIN32
104+
105105
typedef void *(*system_aligned_alloc_t)(size_t alignment, size_t size);
106106
typedef void *(*system_calloc_t)(size_t nmemb, size_t size);
107107
typedef void (*system_free_t)(void *ptr);
@@ -110,6 +110,7 @@ typedef size_t (*system_malloc_usable_size_t)(void *ptr);
110110
typedef void *(*system_realloc_t)(void *ptr, size_t size);
111111

112112
// pointers to the default system allocator's API
113+
static void *System_library_handle;
113114
static system_aligned_alloc_t System_aligned_alloc;
114115
static system_calloc_t System_calloc;
115116
static system_free_t System_free;
@@ -118,7 +119,6 @@ static system_malloc_usable_size_t System_malloc_usable_size;
118119
static system_realloc_t System_realloc;
119120

120121
static size_t Size_threshold_value = 0;
121-
#endif /* _WIN32 */
122122

123123
static UTIL_ONCE_FLAG Base_alloc_leak_initialized = UTIL_ONCE_FLAG_INIT;
124124
static umf_ba_linear_pool_t *Base_alloc_leak = NULL;
@@ -132,7 +132,24 @@ static __TLS int was_called_from_umfPool = 0;
132132
/*** The constructor and destructor of the proxy library *********************/
133133
/*****************************************************************************/
134134

135-
#ifndef _WIN32
135+
// atoi() is defined in stdlib.h, but we cannot include it on Windows
136+
static size_t custom_atoi(const char *str) {
137+
size_t result = 0;
138+
139+
for (int i = 0; str[i]; i++) {
140+
if (str[i] < '0' || str[i] > '9') {
141+
LOG_ERR("proxy_lib_create_common: size threshold is not a valid "
142+
"number: %s",
143+
str);
144+
return 0;
145+
}
146+
147+
result = 10 * result + (size_t)(str[i] - '0');
148+
}
149+
150+
return result;
151+
}
152+
136153
static size_t get_size_threshold(void) {
137154
char *str_threshold = utils_env_var_get_str("UMF_PROXY", "size.threshold=");
138155
if (!str_threshold) {
@@ -148,25 +165,32 @@ static size_t get_size_threshold(void) {
148165
*end = '\0';
149166
}
150167

151-
size_t int_threshold = (size_t)atoi(str_threshold);
168+
size_t int_threshold = (size_t)custom_atoi(str_threshold);
152169
LOG_DEBUG("Size_threshold_value = (char *) %s, (int) %zu", str_threshold,
153170
int_threshold);
154171

155172
return int_threshold;
156173
}
157174

158175
static int get_system_allocator_symbols(void) {
176+
#ifdef _WIN32
177+
System_library_handle = utils_open_library("msvcrt.dll", 0);
178+
#else
179+
System_library_handle = RTLD_NEXT;
180+
#endif /* _WIN32 */
181+
159182
*((void **)(&System_aligned_alloc)) =
160-
utils_get_symbol_addr(RTLD_NEXT, "aligned_alloc", NULL);
183+
utils_get_symbol_addr(System_library_handle, "aligned_alloc", NULL);
161184
*((void **)(&System_calloc)) =
162-
utils_get_symbol_addr(RTLD_NEXT, "calloc", NULL);
163-
*((void **)(&System_free)) = utils_get_symbol_addr(RTLD_NEXT, "free", NULL);
185+
utils_get_symbol_addr(System_library_handle, "calloc", NULL);
186+
*((void **)(&System_free)) =
187+
utils_get_symbol_addr(System_library_handle, "free", NULL);
164188
*((void **)(&System_malloc)) =
165-
utils_get_symbol_addr(RTLD_NEXT, "malloc", NULL);
166-
*((void **)(&System_malloc_usable_size)) =
167-
utils_get_symbol_addr(RTLD_NEXT, "malloc_usable_size", NULL);
189+
utils_get_symbol_addr(System_library_handle, "malloc", NULL);
190+
*((void **)(&System_malloc_usable_size)) = utils_get_symbol_addr(
191+
System_library_handle, "malloc_usable_size", NULL);
168192
*((void **)(&System_realloc)) =
169-
utils_get_symbol_addr(RTLD_NEXT, "realloc", NULL);
193+
utils_get_symbol_addr(System_library_handle, "realloc", NULL);
170194

171195
if (System_aligned_alloc && System_calloc && System_free && System_malloc &&
172196
System_malloc_usable_size && System_realloc) {
@@ -182,15 +206,13 @@ static int get_system_allocator_symbols(void) {
182206

183207
return -1;
184208
}
185-
#endif /* _WIN32 */
186209

187210
void proxy_lib_create_common(void) {
188211
utils_log_init();
189212
umf_os_memory_provider_params_t os_params =
190213
umfOsMemoryProviderParamsDefault();
191214
umf_result_t umf_result;
192215

193-
#ifndef _WIN32
194216
size_t _threshold = get_size_threshold();
195217
if (_threshold > 0) {
196218
if (get_system_allocator_symbols()) {
@@ -203,6 +225,7 @@ void proxy_lib_create_common(void) {
203225
Size_threshold_value);
204226
}
205227

228+
#ifndef _WIN32
206229
if (utils_env_var_has_str("UMF_PROXY", "page.disposition=shared-fd")) {
207230
LOG_INFO("proxy_lib: using the MAP_SHARED visibility mode with the "
208231
"file descriptor duplication");
@@ -258,6 +281,14 @@ void proxy_lib_destroy_common(void) {
258281
umf_memory_provider_handle_t provider = OS_memory_provider;
259282
OS_memory_provider = NULL;
260283
umfMemoryProviderDestroy(provider);
284+
285+
#ifdef _WIN32
286+
if (System_library_handle) {
287+
utils_close_library(System_library_handle);
288+
System_library_handle = NULL;
289+
}
290+
#endif /* _WIN32 */
291+
261292
LOG_DEBUG("proxy library destroyed");
262293

263294
fini_proxy_lib_destroy_common:
@@ -340,11 +371,9 @@ static inline size_t ba_leak_pool_contains_pointer(void *ptr) {
340371
/*****************************************************************************/
341372

342373
void *malloc(size_t size) {
343-
#ifndef _WIN32
344374
if (size < Size_threshold_value) {
345375
return System_malloc(size);
346376
}
347-
#endif /* _WIN32 */
348377

349378
if (!was_called_from_umfPool && Proxy_pool) {
350379
was_called_from_umfPool = 1;
@@ -357,11 +386,9 @@ void *malloc(size_t size) {
357386
}
358387

359388
void *calloc(size_t nmemb, size_t size) {
360-
#ifndef _WIN32
361389
if ((nmemb * size) < Size_threshold_value) {
362390
return System_calloc(nmemb, size);
363391
}
364-
#endif /* _WIN32 */
365392

366393
if (!was_called_from_umfPool && Proxy_pool) {
367394
was_called_from_umfPool = 1;
@@ -389,12 +416,10 @@ void free(void *ptr) {
389416
return;
390417
}
391418

392-
#ifndef _WIN32
393419
if (Size_threshold_value) {
394420
System_free(ptr);
395421
return;
396422
}
397-
#endif /* _WIN32 */
398423

399424
LOG_ERR("free() failed: %p", ptr);
400425

@@ -423,23 +448,19 @@ void *realloc(void *ptr, size_t size) {
423448
return new_ptr;
424449
}
425450

426-
#ifndef _WIN32
427451
if (Size_threshold_value) {
428452
return System_realloc(ptr, size);
429453
}
430-
#endif /* _WIN32 */
431454

432455
LOG_ERR("realloc() failed: %p", ptr);
433456

434457
return NULL;
435458
}
436459

437460
void *aligned_alloc(size_t alignment, size_t size) {
438-
#ifndef _WIN32
439461
if (size < Size_threshold_value) {
440462
return System_aligned_alloc(alignment, size);
441463
}
442-
#endif /* _WIN32 */
443464

444465
if (!was_called_from_umfPool && Proxy_pool) {
445466
was_called_from_umfPool = 1;
@@ -472,11 +493,9 @@ size_t malloc_usable_size(void *ptr) {
472493
return size;
473494
}
474495

475-
#ifndef _WIN32
476496
if (Size_threshold_value) {
477497
return System_malloc_usable_size(ptr);
478498
}
479-
#endif /* _WIN32 */
480499

481500
LOG_ERR("malloc_usable_size() failed: %p", ptr);
482501

test/test_proxy_lib.cpp

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,8 @@ TEST_F(test, proxyLib_size_threshold_aligned_alloc) {
7070
ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_LT, ALIGN_1024)), 1);
7171
ASSERT_EQ((int)(IS_ALIGNED((uintptr_t)ptr_EQ, ALIGN_1024)), 1);
7272

73-
#ifndef _WIN32 /* the size threshold works only on Linux for now */
7473
// umfPoolByPtr(ptr_size_LT) == nullptr
7574
ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr);
76-
#endif
7775
// umfPoolByPtr(ptr_size_EQ) != nullptr
7876
ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr);
7977

@@ -93,10 +91,8 @@ TEST_F(test, proxyLib_size_threshold_malloc) {
9391
ASSERT_NE(ptr_LT, nullptr);
9492
ASSERT_NE(ptr_EQ, nullptr);
9593

96-
#ifndef _WIN32 /* the size threshold works only on Linux for now */
9794
// umfPoolByPtr(ptr_size_LT) == nullptr
9895
ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr);
99-
#endif
10096
// umfPoolByPtr(ptr_size_EQ) != nullptr
10197
ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr);
10298

@@ -111,10 +107,8 @@ TEST_F(test, proxyLib_size_threshold_calloc) {
111107
ASSERT_NE(ptr_LT, nullptr);
112108
ASSERT_NE(ptr_EQ, nullptr);
113109

114-
#ifndef _WIN32 /* the size threshold works only on Linux for now */
115110
// umfPoolByPtr(ptr_size_LT) == nullptr
116111
ASSERT_EQ(umfPoolByPtr(ptr_LT), nullptr);
117-
#endif
118112
// umfPoolByPtr(ptr_size_EQ) != nullptr
119113
ASSERT_NE(umfPoolByPtr(ptr_EQ), nullptr);
120114

@@ -135,10 +129,8 @@ TEST_F(test, proxyLib_size_threshold_realloc_up) {
135129
ASSERT_NE(ptr_LT_r, nullptr);
136130
ASSERT_NE(ptr_EQ_r, nullptr);
137131

138-
#ifndef _WIN32 /* the size threshold works only on Linux for now */
139132
// umfPoolByPtr(ptr_size_LT) == nullptr
140133
ASSERT_EQ(umfPoolByPtr(ptr_LT_r), nullptr);
141-
#endif
142134
// umfPoolByPtr(ptr_size_EQ) != nullptr
143135
ASSERT_NE(umfPoolByPtr(ptr_EQ_r), nullptr);
144136

@@ -159,15 +151,10 @@ TEST_F(test, proxyLib_size_threshold_realloc_down) {
159151
ASSERT_NE(ptr_LT_r, nullptr);
160152
ASSERT_NE(ptr_EQ_r, nullptr);
161153

162-
#ifndef _WIN32 /* the size threshold works only on Linux for now */
163154
// umfPoolByPtr(ptr_size_LT) == nullptr
164155
ASSERT_EQ(umfPoolByPtr(ptr_LT_r), nullptr);
165-
#endif
166156
// umfPoolByPtr(ptr_size_EQ) != nullptr
167157
ASSERT_NE(umfPoolByPtr(ptr_EQ_r), nullptr);
168-
169-
::free(ptr_LT_r);
170-
::free(ptr_EQ_r);
171158
}
172159

173160
TEST_F(test, proxyLib_size_threshold_malloc_usable_size) {

0 commit comments

Comments
 (0)