Skip to content

Commit 3e8927a

Browse files
authored
Adding option to pass user data to allocator functions (#1765)
Add an option to pass user data to the allocator functions. It is common to do this so that the host embedder can pass a struct as user data and access that struct from the allocator, which gives the host embedder the ability to do things such as track allocation statistics within the allocator. Compile with `cmake -DWASM_MEM_ALLOC_WITH_USER_DATA=1` to enable the option, and the allocator functions provided by the host embedder should be like below (an extra argument `data` is added): void *malloc(void *data, uint32 size) { .. } void *realloc(void *data, uint32 size) { .. } void free(void *data, void *ptr) { .. } Signed-off-by: Andrew Chambers <[email protected]>
1 parent 216b2cb commit 3e8927a

File tree

6 files changed

+88
-9
lines changed

6 files changed

+88
-9
lines changed

build-scripts/config_common.cmake

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,3 +311,6 @@ endif ()
311311
if (WAMR_BUILD_WASI_NN EQUAL 1)
312312
message (" WASI-NN enabled")
313313
endif ()
314+
if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
315+
add_definitions(-DWASM_MEM_ALLOC_WITH_USER_DATA=1)
316+
endif()

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,4 +426,8 @@
426426
#define WASM_ENABLE_SGX_IPFS 0
427427
#endif
428428

429+
#ifndef WASM_MEM_ALLOC_WITH_USER_DATA
430+
#define WASM_MEM_ALLOC_WITH_USER_DATA 0
431+
#endif
432+
429433
#endif /* end of _CONFIG_H_ */

core/iwasm/common/wasm_c_api.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
340340
opts->allocator.free_func;
341341
init_args.mem_alloc_option.allocator.realloc_func =
342342
opts->allocator.realloc_func;
343+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
344+
init_args.mem_alloc_option.allocator.user_data =
345+
opts->allocator.user_data;
346+
#endif
343347
}
344348
else {
345349
init_args.mem_alloc_option.pool.heap_buf = NULL;

core/iwasm/common/wasm_memory.c

Lines changed: 71 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,25 @@
1111
typedef enum Memory_Mode {
1212
MEMORY_MODE_UNKNOWN = 0,
1313
MEMORY_MODE_POOL,
14-
MEMORY_MODE_ALLOCATOR
14+
MEMORY_MODE_ALLOCATOR,
15+
MEMORY_MODE_SYSTEM_ALLOCATOR
1516
} Memory_Mode;
1617

1718
static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
1819

1920
static mem_allocator_t pool_allocator = NULL;
2021

22+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
23+
static void *allocator_user_data = NULL;
24+
static void *(*malloc_func)(void *user_data, unsigned int size) = NULL;
25+
static void *(*realloc_func)(void *user_data, void *ptr,
26+
unsigned int size) = NULL;
27+
static void (*free_func)(void *user_data, void *ptr) = NULL;
28+
#else
2129
static void *(*malloc_func)(unsigned int size) = NULL;
2230
static void *(*realloc_func)(void *ptr, unsigned int size) = NULL;
2331
static void (*free_func)(void *ptr) = NULL;
32+
#endif
2433

2534
static unsigned int global_pool_size;
2635

@@ -39,6 +48,24 @@ wasm_memory_init_with_pool(void *mem, unsigned int bytes)
3948
return false;
4049
}
4150

51+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
52+
static bool
53+
wasm_memory_init_with_allocator(void *_user_data, void *_malloc_func,
54+
void *_realloc_func, void *_free_func)
55+
{
56+
if (_malloc_func && _free_func && _malloc_func != _free_func) {
57+
memory_mode = MEMORY_MODE_ALLOCATOR;
58+
allocator_user_data = _user_data;
59+
malloc_func = _malloc_func;
60+
realloc_func = _realloc_func;
61+
free_func = _free_func;
62+
return true;
63+
}
64+
LOG_ERROR("Init memory with allocator (%p, %p, %p, %p) failed.\n",
65+
_user_data, _malloc_func, _realloc_func, _free_func);
66+
return false;
67+
}
68+
#else
4269
static bool
4370
wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
4471
void *_free_func)
@@ -54,23 +81,37 @@ wasm_memory_init_with_allocator(void *_malloc_func, void *_realloc_func,
5481
_realloc_func, _free_func);
5582
return false;
5683
}
84+
#endif
5785

5886
bool
5987
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
6088
const MemAllocOption *alloc_option)
6189
{
62-
if (mem_alloc_type == Alloc_With_Pool)
90+
if (mem_alloc_type == Alloc_With_Pool) {
6391
return wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
6492
alloc_option->pool.heap_size);
65-
else if (mem_alloc_type == Alloc_With_Allocator)
93+
}
94+
else if (mem_alloc_type == Alloc_With_Allocator) {
95+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
6696
return wasm_memory_init_with_allocator(
97+
alloc_option->allocator.user_data,
6798
alloc_option->allocator.malloc_func,
6899
alloc_option->allocator.realloc_func,
69100
alloc_option->allocator.free_func);
70-
else if (mem_alloc_type == Alloc_With_System_Allocator)
71-
return wasm_memory_init_with_allocator(os_malloc, os_realloc, os_free);
72-
else
101+
#else
102+
return wasm_memory_init_with_allocator(
103+
alloc_option->allocator.malloc_func,
104+
alloc_option->allocator.realloc_func,
105+
alloc_option->allocator.free_func);
106+
#endif
107+
}
108+
else if (mem_alloc_type == Alloc_With_System_Allocator) {
109+
memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
110+
return true;
111+
}
112+
else {
73113
return false;
114+
}
74115
}
75116

76117
void
@@ -110,8 +151,15 @@ wasm_runtime_malloc_internal(unsigned int size)
110151
else if (memory_mode == MEMORY_MODE_POOL) {
111152
return mem_allocator_malloc(pool_allocator, size);
112153
}
113-
else {
154+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
155+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
156+
return malloc_func(allocator_user_data, size);
157+
#else
114158
return malloc_func(size);
159+
#endif
160+
}
161+
else {
162+
return os_malloc(size);
115163
}
116164
}
117165

@@ -126,12 +174,19 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
126174
else if (memory_mode == MEMORY_MODE_POOL) {
127175
return mem_allocator_realloc(pool_allocator, ptr, size);
128176
}
129-
else {
177+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
130178
if (realloc_func)
179+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
180+
return realloc_func(allocator_user_data, ptr, size);
181+
#else
131182
return realloc_func(ptr, size);
183+
#endif
132184
else
133185
return NULL;
134186
}
187+
else {
188+
return os_realloc(ptr, size);
189+
}
135190
}
136191

137192
static inline void
@@ -152,8 +207,15 @@ wasm_runtime_free_internal(void *ptr)
152207
else if (memory_mode == MEMORY_MODE_POOL) {
153208
mem_allocator_free(pool_allocator, ptr);
154209
}
155-
else {
210+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
211+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
212+
free_func(allocator_user_data, ptr);
213+
#else
156214
free_func(ptr);
215+
#endif
216+
}
217+
else {
218+
os_free(ptr);
157219
}
158220
}
159221

core/iwasm/include/wasm_c_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,9 @@ typedef union MemAllocOption {
186186
void *malloc_func;
187187
void *realloc_func;
188188
void *free_func;
189+
/* allocator user data, only used when
190+
WASM_MEM_ALLOC_WITH_USER_DATA is defined */
191+
void *user_data;
189192
} allocator;
190193
} MemAllocOption;
191194
#endif

core/iwasm/include/wasm_export.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,9 @@ typedef union MemAllocOption {
117117
void *malloc_func;
118118
void *realloc_func;
119119
void *free_func;
120+
/* allocator user data, only used when
121+
WASM_MEM_ALLOC_WITH_USER_DATA is defined */
122+
void *user_data;
120123
} allocator;
121124
} MemAllocOption;
122125
#endif

0 commit comments

Comments
 (0)