Skip to content

Commit ab92585

Browse files
committed
add free handle POC
1 parent ac9094d commit ab92585

File tree

11 files changed

+291
-38
lines changed

11 files changed

+291
-38
lines changed

include/umf/proxy_lib_handlers.h

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
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_HANDLERS_H
9+
#define UMF_PROXY_LIB_HANDLERS_H 1
10+
11+
#include <umf/memory_pool.h>
12+
13+
#ifdef __cplusplus
14+
extern "C" {
15+
#endif
16+
17+
// TODO - improve and cleanup comments
18+
19+
// malloc API handlers
20+
// NOTE - in malloc/aligned_malloc pre handlers the default pool could be
21+
// changed along with the requested size and alignment
22+
typedef void (*umf_proxy_lib_handler_malloc_pre_t)(
23+
void *user_data, umf_memory_pool_handle_t *pool, size_t *size);
24+
typedef void (*umf_proxy_lib_handler_aligned_malloc_pre_t)(
25+
void *user_data, umf_memory_pool_handle_t *pool, size_t *size,
26+
size_t *alignment);
27+
typedef void (*umf_proxy_lib_handler_free_pre_t)(void *user_data, void *ptr,
28+
umf_memory_pool_handle_t pool);
29+
30+
void umfSetProxyLibHandlerMallocPre(umf_proxy_lib_handler_malloc_pre_t handler,
31+
void *user_data);
32+
void umfSetProxyLibHandlerAlignedMallocPre(
33+
umf_proxy_lib_handler_aligned_malloc_pre_t handler, void *user_data);
34+
void umfSetProxyLibHandlerFreePre(umf_proxy_lib_handler_free_pre_t handler,
35+
void *user_data);
36+
37+
// NOTE - in the malloc/aligned_malloc post handlers the pointer to allocated
38+
// data could be changed by the user
39+
typedef void (*umf_proxy_lib_handler_malloc_post_t)(
40+
void *user_data, void **ptr, umf_memory_pool_handle_t pool);
41+
typedef void (*umf_proxy_lib_handler_aligned_malloc_post_t)(
42+
void *user_data, void **ptr, umf_memory_pool_handle_t pool);
43+
44+
void umfSetProxyLibHandlerMallocPost(
45+
umf_proxy_lib_handler_malloc_post_t handler, void *user_data);
46+
void umfSetProxyLibHandlerAlignedMallocPost(
47+
umf_proxy_lib_handler_aligned_malloc_post_t handler, void *user_data);
48+
49+
#ifdef __cplusplus
50+
}
51+
#endif
52+
53+
#endif /* UMF_PROXY_LIB_HANDLERS_H */

src/proxy_lib/proxy_lib.c

Lines changed: 101 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,9 @@
5050
#include <umf/memory_pool.h>
5151
#include <umf/memory_provider.h>
5252
#include <umf/providers/provider_os_memory.h>
53+
#include <umf/proxy_lib_handlers.h>
5354

5455
#include "base_alloc_linear.h"
55-
#include "proxy_lib.h"
5656
#include "utils_common.h"
5757
#include "utils_load_library.h"
5858
#include "utils_log.h"
@@ -135,6 +135,22 @@ static __TLS int was_called_from_umfPool = 0;
135135
// TODO remove this WA when the issue is fixed.
136136
static __TLS int was_called_from_malloc_usable_size = 0;
137137

138+
// malloc API handlers
139+
static umf_proxy_lib_handler_malloc_pre_t Handler_malloc_pre = NULL;
140+
static umf_proxy_lib_handler_aligned_malloc_pre_t Handler_aligned_malloc_pre =
141+
NULL;
142+
static umf_proxy_lib_handler_free_pre_t Handler_free_pre = NULL;
143+
144+
static umf_proxy_lib_handler_malloc_post_t Handler_malloc_post = NULL;
145+
static umf_proxy_lib_handler_aligned_malloc_post_t Handler_aligned_malloc_post =
146+
NULL;
147+
148+
static void *Handler_malloc_pre_user_data = NULL;
149+
static void *Handler_aligned_malloc_pre_user_data = NULL;
150+
static void *Handler_free_pre_user_data = NULL;
151+
static void *Handler_malloc_post_user_data = NULL;
152+
static void *Handler_aligned_malloc_post_user_data = NULL;
153+
138154
/*****************************************************************************/
139155
/*** The constructor and destructor of the proxy library *********************/
140156
/*****************************************************************************/
@@ -353,20 +369,35 @@ static inline size_t ba_leak_pool_contains_pointer(void *ptr) {
353369
/*****************************************************************************/
354370

355371
void *malloc(size_t size) {
372+
umf_memory_pool_handle_t pool = Proxy_pool;
373+
if (Handler_malloc_pre) {
374+
Handler_malloc_pre(Handler_malloc_pre_user_data, &pool, &size);
375+
}
376+
377+
void *ptr = NULL;
356378
#ifndef _WIN32
357379
if (size < Size_threshold_value) {
358-
return System_malloc(size);
380+
ptr = System_malloc(size);
381+
goto handler_post;
359382
}
383+
360384
#endif /* _WIN32 */
361385

362-
if (!was_called_from_umfPool && Proxy_pool) {
386+
if (!was_called_from_umfPool && pool) {
363387
was_called_from_umfPool = 1;
364-
void *ptr = umfPoolMalloc(Proxy_pool, size);
388+
ptr = umfPoolMalloc(pool, size);
365389
was_called_from_umfPool = 0;
366-
return ptr;
390+
goto handler_post;
367391
}
368392

369-
return ba_leak_malloc(size);
393+
ptr = ba_leak_malloc(size);
394+
395+
handler_post:
396+
if (Handler_malloc_post) {
397+
Handler_malloc_post(Handler_malloc_post_user_data, &ptr, pool);
398+
}
399+
400+
return ptr;
370401
}
371402

372403
void *calloc(size_t nmemb, size_t size) {
@@ -391,11 +422,19 @@ void free(void *ptr) {
391422
return;
392423
}
393424

425+
// NOTE: for system allocations made during UMF and Proxy Lib
426+
// initialisation, we never call free handlers, as they should handle
427+
// only user-made allocations
394428
if (ba_leak_free(ptr) == 0) {
395429
return;
396430
}
397431

398-
if (Proxy_pool && (umfPoolByPtr(ptr) == Proxy_pool)) {
432+
umf_memory_pool_handle_t pool = umfPoolByPtr(ptr);
433+
if (Proxy_pool && (pool == Proxy_pool)) {
434+
if (Handler_free_pre) {
435+
Handler_free_pre(Handler_free_pre_user_data, ptr, pool);
436+
}
437+
399438
if (umfPoolFree(Proxy_pool, ptr) != UMF_RESULT_SUCCESS) {
400439
LOG_ERR("umfPoolFree() failed");
401440
}
@@ -404,6 +443,9 @@ void free(void *ptr) {
404443

405444
#ifndef _WIN32
406445
if (Size_threshold_value) {
446+
if (Handler_free_pre) {
447+
Handler_free_pre(Handler_free_pre_user_data, ptr, NULL);
448+
}
407449
System_free(ptr);
408450
return;
409451
}
@@ -448,20 +490,36 @@ void *realloc(void *ptr, size_t size) {
448490
}
449491

450492
void *aligned_alloc(size_t alignment, size_t size) {
493+
umf_memory_pool_handle_t pool = Proxy_pool;
494+
if (Handler_aligned_malloc_pre) {
495+
Handler_aligned_malloc_pre(Handler_aligned_malloc_pre_user_data, &pool,
496+
&size, &alignment);
497+
}
498+
499+
void *ptr = NULL;
451500
#ifndef _WIN32
452501
if (size < Size_threshold_value) {
453-
return System_aligned_alloc(alignment, size);
502+
ptr = System_aligned_alloc(alignment, size);
503+
goto handler_post;
454504
}
455505
#endif /* _WIN32 */
456506

457507
if (!was_called_from_umfPool && Proxy_pool) {
458508
was_called_from_umfPool = 1;
459-
void *ptr = umfPoolAlignedMalloc(Proxy_pool, size, alignment);
509+
ptr = umfPoolAlignedMalloc(Proxy_pool, size, alignment);
460510
was_called_from_umfPool = 0;
461-
return ptr;
511+
goto handler_post;
462512
}
463513

464-
return ba_leak_aligned_alloc(alignment, size);
514+
ptr = ba_leak_aligned_alloc(alignment, size);
515+
516+
handler_post:
517+
if (Handler_aligned_malloc_post) {
518+
Handler_aligned_malloc_post(Handler_aligned_malloc_post_user_data, &ptr,
519+
pool);
520+
}
521+
522+
return ptr;
465523
}
466524

467525
#ifdef _WIN32
@@ -555,3 +613,35 @@ void *_aligned_offset_recalloc(void *ptr, size_t num, size_t size,
555613
}
556614

557615
#endif
616+
617+
// malloc API handlers
618+
619+
void umfSetProxyLibHandlerMallocPre(umf_proxy_lib_handler_malloc_pre_t handler,
620+
void *user_data) {
621+
Handler_malloc_pre = handler;
622+
Handler_malloc_pre_user_data = user_data;
623+
}
624+
625+
void umfSetProxyLibHandlerAlignedMallocPre(
626+
umf_proxy_lib_handler_aligned_malloc_pre_t handler, void *user_data) {
627+
Handler_aligned_malloc_pre = handler;
628+
Handler_aligned_malloc_pre_user_data = user_data;
629+
}
630+
631+
void umfSetProxyLibHandlerFreePre(umf_proxy_lib_handler_free_pre_t handler,
632+
void *user_data) {
633+
Handler_free_pre = handler;
634+
Handler_free_pre_user_data = user_data;
635+
}
636+
637+
void umfSetProxyLibHandlerMallocPost(
638+
umf_proxy_lib_handler_malloc_post_t handler, void *user_data) {
639+
Handler_malloc_post = handler;
640+
Handler_malloc_post_user_data = user_data;
641+
}
642+
643+
void umfSetProxyLibHandlerAlignedMallocPost(
644+
umf_proxy_lib_handler_aligned_malloc_post_t handler, void *user_data) {
645+
Handler_aligned_malloc_post = handler;
646+
Handler_aligned_malloc_post_user_data = user_data;
647+
}

src/proxy_lib/proxy_lib.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,9 @@ EXPORTS
2121
_aligned_offset_malloc
2222
_aligned_offset_realloc
2323
_aligned_offset_recalloc
24+
; handlers
25+
umfSetProxyLibHandlerMallocPre
26+
umfSetProxyLibHandlerAlignedMallocPre
27+
umfSetProxyLibHandlerFreePre
28+
umfSetProxyLibHandlerMallocPost
29+
umfSetProxyLibHandlerAlignedMallocPost

src/proxy_lib/proxy_lib.h

Lines changed: 0 additions & 22 deletions
This file was deleted.

src/proxy_lib/proxy_lib.map

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44

55
# linker VERSION script
66

7-
{
7+
PROXY_LIB_0.10 {
88
global:
99
aligned_alloc;
1010
calloc;
1111
free;
1212
malloc;
1313
malloc_usable_size;
1414
realloc;
15+
# handlers
16+
umfSetProxyLibHandlerMallocPre;
17+
umfSetProxyLibHandlerAlignedMallocPre;
18+
umfSetProxyLibHandlerFreePre;
19+
umfSetProxyLibHandlerMallocPost;
20+
umfSetProxyLibHandlerAlignedMallocPost;
1521
local:
1622
*;
1723
};

src/proxy_lib/proxy_lib_linux.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,10 @@
77
*
88
*/
99

10-
#include "proxy_lib.h"
10+
#include <umf/proxy_lib_handlers.h>
11+
12+
void proxy_lib_create_common(void);
13+
void proxy_lib_destroy_common(void);
1114

1215
// The priority 102 is used, because the constructor should be called as the second one
1316
// (just after the first constructor of the base allocator with priority 101)

src/proxy_lib/proxy_lib_windows.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,10 @@
99

1010
#include <Windows.h>
1111

12-
#include "proxy_lib.h"
12+
#include <umf/proxy_lib_handlers.h>
13+
14+
void proxy_lib_create_common(void);
15+
void proxy_lib_destroy_common(void);
1316

1417
static void proxy_lib_create(void) { proxy_lib_create_common(); }
1518

test/CMakeLists.txt

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -447,14 +447,19 @@ add_umf_test(
447447
if(UMF_PROXY_LIB_ENABLED AND UMF_BUILD_SHARED_LIBRARY)
448448
add_umf_test(
449449
NAME proxy_lib_basic
450-
SRCS ${BA_SOURCES_FOR_TEST} test_proxy_lib.cpp
450+
SRCS ${BA_SOURCES_FOR_TEST} proxy_lib/proxy_lib.cpp
451+
LIBS ${UMF_UTILS_FOR_TEST} umf_proxy)
452+
453+
add_umf_test(
454+
NAME proxy_lib_handlers
455+
SRCS ${BA_SOURCES_FOR_TEST} proxy_lib/proxy_lib_handlers.cpp
451456
LIBS ${UMF_UTILS_FOR_TEST} umf_proxy)
452457

453458
# TODO enable this test on Windows
454459
if(LINUX)
455460
add_umf_test(
456461
NAME test_proxy_lib_size_threshold
457-
SRCS ${BA_SOURCES_FOR_TEST} test_proxy_lib_size_threshold.cpp
462+
SRCS ${BA_SOURCES_FOR_TEST} proxy_lib/proxy_lib_size_threshold.cpp
458463
LIBS ${UMF_UTILS_FOR_TEST} umf_proxy)
459464
set_property(TEST umf-test_proxy_lib_size_threshold
460465
PROPERTY ENVIRONMENT UMF_PROXY="size.threshold=64")
File renamed without changes.

0 commit comments

Comments
 (0)