Skip to content

Commit 7713d0c

Browse files
nchamznAndrew Chambers
authored andcommitted
Adding option to pass user data to allocator functions (bytecodealliance#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 86bdd8c commit 7713d0c

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
@@ -291,3 +291,6 @@ if (WAMR_BUILD_SGX_IPFS EQUAL 1)
291291
add_definitions (-DWASM_ENABLE_SGX_IPFS=1)
292292
message (" SGX IPFS enabled")
293293
endif ()
294+
if (WAMR_BUILD_ALLOC_WITH_USER_DATA EQUAL 1)
295+
add_definitions(-DWASM_MEM_ALLOC_WITH_USER_DATA=1)
296+
endif()

core/config.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -411,4 +411,8 @@
411411
#define WASM_ENABLE_SGX_IPFS 0
412412
#endif
413413

414+
#ifndef WASM_MEM_ALLOC_WITH_USER_DATA
415+
#define WASM_MEM_ALLOC_WITH_USER_DATA 0
416+
#endif
417+
414418
#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
@@ -291,6 +291,10 @@ wasm_engine_new_internal(mem_alloc_type_t type, const MemAllocOption *opts)
291291
opts->allocator.free_func;
292292
init_args.mem_alloc_option.allocator.realloc_func =
293293
opts->allocator.realloc_func;
294+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
295+
init_args.mem_alloc_option.allocator.user_data =
296+
opts->allocator.user_data;
297+
#endif
294298
}
295299
else {
296300
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
@@ -10,16 +10,25 @@
1010
typedef enum Memory_Mode {
1111
MEMORY_MODE_UNKNOWN = 0,
1212
MEMORY_MODE_POOL,
13-
MEMORY_MODE_ALLOCATOR
13+
MEMORY_MODE_ALLOCATOR,
14+
MEMORY_MODE_SYSTEM_ALLOCATOR
1415
} Memory_Mode;
1516

1617
static Memory_Mode memory_mode = MEMORY_MODE_UNKNOWN;
1718

1819
static mem_allocator_t pool_allocator = NULL;
1920

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

2433
static unsigned int global_pool_size;
2534

@@ -38,6 +47,24 @@ wasm_memory_init_with_pool(void *mem, unsigned int bytes)
3847
return false;
3948
}
4049

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

5785
bool
5886
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
5987
const MemAllocOption *alloc_option)
6088
{
61-
if (mem_alloc_type == Alloc_With_Pool)
89+
if (mem_alloc_type == Alloc_With_Pool) {
6290
return wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
6391
alloc_option->pool.heap_size);
64-
else if (mem_alloc_type == Alloc_With_Allocator)
92+
}
93+
else if (mem_alloc_type == Alloc_With_Allocator) {
94+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
6595
return wasm_memory_init_with_allocator(
96+
alloc_option->allocator.user_data,
6697
alloc_option->allocator.malloc_func,
6798
alloc_option->allocator.realloc_func,
6899
alloc_option->allocator.free_func);
69-
else if (mem_alloc_type == Alloc_With_System_Allocator)
70-
return wasm_memory_init_with_allocator(os_malloc, os_realloc, os_free);
71-
else
100+
#else
101+
return wasm_memory_init_with_allocator(
102+
alloc_option->allocator.malloc_func,
103+
alloc_option->allocator.realloc_func,
104+
alloc_option->allocator.free_func);
105+
#endif
106+
}
107+
else if (mem_alloc_type == Alloc_With_System_Allocator) {
108+
memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
109+
return true;
110+
}
111+
else {
72112
return false;
113+
}
73114
}
74115

75116
void
@@ -109,8 +150,15 @@ wasm_runtime_malloc_internal(unsigned int size)
109150
else if (memory_mode == MEMORY_MODE_POOL) {
110151
return mem_allocator_malloc(pool_allocator, size);
111152
}
112-
else {
153+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
154+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
155+
return malloc_func(allocator_user_data, size);
156+
#else
113157
return malloc_func(size);
158+
#endif
159+
}
160+
else {
161+
return os_malloc(size);
114162
}
115163
}
116164

@@ -125,12 +173,19 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
125173
else if (memory_mode == MEMORY_MODE_POOL) {
126174
return mem_allocator_realloc(pool_allocator, ptr, size);
127175
}
128-
else {
176+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
129177
if (realloc_func)
178+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
179+
return realloc_func(allocator_user_data, ptr, size);
180+
#else
130181
return realloc_func(ptr, size);
182+
#endif
131183
else
132184
return NULL;
133185
}
186+
else {
187+
return os_realloc(ptr, size);
188+
}
134189
}
135190

136191
static inline void
@@ -148,8 +203,15 @@ wasm_runtime_free_internal(void *ptr)
148203
else if (memory_mode == MEMORY_MODE_POOL) {
149204
mem_allocator_free(pool_allocator, ptr);
150205
}
151-
else {
206+
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
207+
#if WASM_MEM_ALLOC_WITH_USER_DATA != 0
208+
free_func(allocator_user_data, ptr);
209+
#else
152210
free_func(ptr);
211+
#endif
212+
}
213+
else {
214+
os_free(ptr);
153215
}
154216
}
155217

core/iwasm/include/wasm_c_api.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,9 @@ typedef union MemAllocOption {
173173
void *malloc_func;
174174
void *realloc_func;
175175
void *free_func;
176+
/* allocator user data, only used when
177+
WASM_MEM_ALLOC_WITH_USER_DATA is defined */
178+
void *user_data;
176179
} allocator;
177180
} MemAllocOption;
178181
#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)