Skip to content

Commit 53973f0

Browse files
committed
Implement a thread-level-singleton WASMRuntime
Plan to replace process-level global variables with thread-local variables. The reason for not using the variable attribute `__thread` is due to concerns that it is a GCC extension and requires significant support from the linker (ld), dynamic linker (ld.so), and system libraries (libc.so and libpthread.so), making it not available everywhere. Plus, memory initialization
1 parent 2343a14 commit 53973f0

File tree

9 files changed

+433
-109
lines changed

9 files changed

+433
-109
lines changed

core/iwasm/common/wasm_memory.c

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ static mem_allocator_t pool_allocator = NULL;
3030

3131
#if WASM_ENABLE_SHARED_HEAP != 0
3232
static WASMSharedHeap *shared_heap_list = NULL;
33+
// TODO: remove this when runtime-instance-feature is ready
3334
static korp_mutex shared_heap_list_lock;
3435
#endif
3536

@@ -78,14 +79,15 @@ align_as_and_cast(uint64 size, uint64 alignment)
7879
}
7980

8081
static bool
81-
wasm_memory_init_with_pool(void *mem, unsigned int bytes)
82+
wasm_memory_init_with_pool(void *mem, unsigned int bytes,
83+
WASMRuntimeAllocator *allocator)
8284
{
83-
mem_allocator_t allocator = mem_allocator_create(mem, bytes);
85+
mem_allocator_t mem_allocator = mem_allocator_create(mem, bytes);
8486

85-
if (allocator) {
86-
memory_mode = MEMORY_MODE_POOL;
87-
pool_allocator = allocator;
88-
global_pool_size = bytes;
87+
if (mem_allocator) {
88+
allocator->memory_mode = MEMORY_MODE_POOL;
89+
allocator->pool_allocator = mem_allocator;
90+
allocator->pool_size = bytes;
8991
return true;
9092
}
9193
LOG_ERROR("Init memory with pool (%p, %u) failed.\n", mem, bytes);
@@ -112,13 +114,14 @@ wasm_memory_init_with_allocator(void *_user_data, void *_malloc_func,
112114
#else
113115
static bool
114116
wasm_memory_init_with_allocator(void *malloc_func_ptr, void *realloc_func_ptr,
115-
void *free_func_ptr)
117+
void *free_func_ptr,
118+
WASMRuntimeAllocator *allocator)
116119
{
117120
if (malloc_func_ptr && free_func_ptr && malloc_func_ptr != free_func_ptr) {
118-
memory_mode = MEMORY_MODE_ALLOCATOR;
119-
malloc_func = malloc_func_ptr;
120-
realloc_func = realloc_func_ptr;
121-
free_func = free_func_ptr;
121+
allocator->memory_mode = MEMORY_MODE_ALLOCATOR;
122+
allocator->malloc_func = malloc_func_ptr;
123+
allocator->realloc_func = realloc_func_ptr;
124+
allocator->free_func = free_func_ptr;
122125
return true;
123126
}
124127
LOG_ERROR("Init memory with allocator (%p, %p, %p) failed.\n",
@@ -509,6 +512,15 @@ wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst, uint64 ptr)
509512
bool
510513
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
511514
const MemAllocOption *alloc_option)
515+
{
516+
DEPRECATED_API(wasm_runtime_memory_init, wasm_runtime_memory_init2);
517+
return false;
518+
}
519+
520+
bool
521+
wasm_runtime_memory_init2(mem_alloc_type_t mem_alloc_type,
522+
const MemAllocOption *alloc_option,
523+
WASMRuntimeAllocator *allocator)
512524
{
513525
bool ret = false;
514526

@@ -519,8 +531,9 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
519531
#endif
520532

521533
if (mem_alloc_type == Alloc_With_Pool) {
522-
ret = wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
523-
alloc_option->pool.heap_size);
534+
ret =
535+
wasm_memory_init_with_pool(alloc_option->pool.heap_buf,
536+
alloc_option->pool.heap_size, allocator);
524537
}
525538
else if (mem_alloc_type == Alloc_With_Allocator) {
526539
ret = wasm_memory_init_with_allocator(
@@ -529,10 +542,10 @@ wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
529542
#endif
530543
alloc_option->allocator.malloc_func,
531544
alloc_option->allocator.realloc_func,
532-
alloc_option->allocator.free_func);
545+
alloc_option->allocator.free_func, allocator);
533546
}
534547
else if (mem_alloc_type == Alloc_With_System_Allocator) {
535-
memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
548+
allocator->memory_mode = MEMORY_MODE_SYSTEM_ALLOCATOR;
536549
ret = true;
537550
}
538551
else {
@@ -580,23 +593,29 @@ destroy_shared_heaps()
580593

581594
void
582595
wasm_runtime_memory_destroy(void)
596+
{
597+
DEPRECATED_API(wasm_runtime_memory_destroy, wasm_runtime_memory_destroy2);
598+
}
599+
600+
void
601+
wasm_runtime_memory_destroy2(WASMRuntimeAllocator *allocator)
583602
{
584603
#if WASM_ENABLE_SHARED_HEAP != 0
585604
destroy_shared_heaps();
586605
#endif
587606

588-
if (memory_mode == MEMORY_MODE_POOL) {
607+
if (allocator->memory_mode == MEMORY_MODE_POOL) {
589608
#if BH_ENABLE_GC_VERIFY == 0
590-
(void)mem_allocator_destroy(pool_allocator);
609+
(void)mem_allocator_destroy(allocator->pool_allocator);
591610
#else
592-
int ret = mem_allocator_destroy(pool_allocator);
611+
int ret = mem_allocator_destroy(allocator->pool_allocator);
593612
if (ret != 0) {
594613
/* Memory leak detected */
595614
exit(-1);
596615
}
597616
#endif
598617
}
599-
memory_mode = MEMORY_MODE_UNKNOWN;
618+
allocator->memory_mode = MEMORY_MODE_UNKNOWN;
600619
}
601620

602621
unsigned
@@ -609,18 +628,21 @@ wasm_runtime_memory_pool_size(void)
609628
}
610629

611630
static inline void *
612-
wasm_runtime_malloc_internal(unsigned int size)
631+
wasm_runtime_malloc_internal(WASMRuntimeAllocator *allocator, int size)
613632
{
614-
if (memory_mode == MEMORY_MODE_UNKNOWN) {
633+
if (allocator->memory_mode == MEMORY_MODE_UNKNOWN) {
615634
LOG_WARNING(
616635
"wasm_runtime_malloc failed: memory hasn't been initialized.\n");
617636
return NULL;
618637
}
619-
else if (memory_mode == MEMORY_MODE_POOL) {
620-
return mem_allocator_malloc(pool_allocator, size);
638+
639+
// TODO: use allocator->malloc_func() when we assign variant malloc_func for
640+
// various memory mode
641+
if (allocator->memory_mode == MEMORY_MODE_POOL) {
642+
return mem_allocator_malloc(allocator->pool_allocator, size);
621643
}
622-
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
623-
return malloc_func(
644+
else if (allocator->memory_mode == MEMORY_MODE_ALLOCATOR) {
645+
return allocator->malloc_func(
624646
#if WASM_MEM_ALLOC_WITH_USAGE != 0
625647
Alloc_For_Runtime,
626648
#endif
@@ -664,7 +686,7 @@ wasm_runtime_realloc_internal(void *ptr, unsigned int size)
664686
}
665687

666688
static inline void
667-
wasm_runtime_free_internal(void *ptr)
689+
wasm_runtime_free_internal(WASMRuntimeAllocator *allocator, void *ptr)
668690
{
669691
if (!ptr) {
670692
LOG_WARNING("warning: wasm_runtime_free with NULL pointer\n");
@@ -674,15 +696,15 @@ wasm_runtime_free_internal(void *ptr)
674696
return;
675697
}
676698

677-
if (memory_mode == MEMORY_MODE_UNKNOWN) {
699+
if (allocator->memory_mode == MEMORY_MODE_UNKNOWN) {
678700
LOG_WARNING("warning: wasm_runtime_free failed: "
679701
"memory hasn't been initialize.\n");
680702
}
681-
else if (memory_mode == MEMORY_MODE_POOL) {
682-
mem_allocator_free(pool_allocator, ptr);
703+
else if (allocator->memory_mode == MEMORY_MODE_POOL) {
704+
mem_allocator_free(allocator->pool_allocator, ptr);
683705
}
684706
else if (memory_mode == MEMORY_MODE_ALLOCATOR) {
685-
free_func(
707+
allocator->free_func(
686708
#if WASM_MEM_ALLOC_WITH_USAGE != 0
687709
Alloc_For_Runtime,
688710
#endif
@@ -699,23 +721,35 @@ wasm_runtime_free_internal(void *ptr)
699721
void *
700722
wasm_runtime_malloc(unsigned int size)
701723
{
724+
WASMRuntimeAllocator *allocator;
725+
726+
allocator = wasm_runtime_get_local_allocator();
727+
return wasm_runtime_malloc2(allocator, size);
728+
}
729+
730+
void *
731+
wasm_runtime_malloc2(WASMRuntimeAllocator *allocator, unsigned int size)
732+
{
733+
CHECK_NULL_AND_RETURN(allocator, NULL);
734+
702735
if (size == 0) {
703-
LOG_WARNING("warning: wasm_runtime_malloc with size zero\n");
704-
/* At lease alloc 1 byte to avoid malloc failed */
736+
LOG_WARNING("warning: wasm_runtime_malloc failed: "
737+
"size is zero.\n");
705738
size = 1;
706739
#if BH_ENABLE_GC_VERIFY != 0
707740
exit(-1);
708741
#endif
709742
}
710743

744+
// TODO: move this to wasm_runtime_malloc_internal() if possible
711745
#if WASM_ENABLE_FUZZ_TEST != 0
712746
if (size >= WASM_MEM_ALLOC_MAX_SIZE) {
713747
LOG_WARNING("warning: wasm_runtime_malloc with too large size\n");
714748
return NULL;
715749
}
716750
#endif
717751

718-
return wasm_runtime_malloc_internal(size);
752+
return wasm_runtime_malloc_internal(allocator, size);
719753
}
720754

721755
void *
@@ -727,7 +761,18 @@ wasm_runtime_realloc(void *ptr, unsigned int size)
727761
void
728762
wasm_runtime_free(void *ptr)
729763
{
730-
wasm_runtime_free_internal(ptr);
764+
WASMRuntimeAllocator *allocator;
765+
766+
allocator = wasm_runtime_get_local_allocator();
767+
return wasm_runtime_free2(allocator, ptr);
768+
}
769+
770+
void
771+
wasm_runtime_free2(WASMRuntimeAllocator *allocator, void *ptr)
772+
{
773+
CHECK_NULL_AND_RETURN_VOID(allocator);
774+
775+
wasm_runtime_free_internal(allocator, ptr);
731776
}
732777

733778
bool

core/iwasm/common/wasm_memory.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,13 +70,35 @@ wasm_runtime_shared_heap_free(WASMModuleInstanceCommon *module_inst,
7070
uint64 ptr);
7171
#endif
7272

73+
// TODO: remove this when all the code is migrated to use the new API
7374
bool
7475
wasm_runtime_memory_init(mem_alloc_type_t mem_alloc_type,
7576
const MemAllocOption *alloc_option);
7677

7778
void
7879
wasm_runtime_memory_destroy(void);
7980

81+
typedef struct WASMRuntimeAllocator {
82+
uint8 memory_mode;
83+
// TODO: maybe, we can use a unionto save space
84+
85+
void *pool_allocator;
86+
unsigned int pool_size;
87+
88+
// TODO: maybe, we can just save the malloc/realloc/free function pointers
89+
void *(*malloc_func)(unsigned int size);
90+
void *(*realloc_func)(void *ptr, unsigned int size);
91+
void (*free_func)(void *ptr);
92+
} WASMRuntimeAllocator;
93+
94+
bool
95+
wasm_runtime_memory_init2(mem_alloc_type_t mem_alloc_type,
96+
const MemAllocOption *alloc_option,
97+
WASMRuntimeAllocator *allocator);
98+
99+
void
100+
wasm_runtime_memory_destroy2(WASMRuntimeAllocator *allocator);
101+
80102
unsigned
81103
wasm_runtime_memory_pool_size(void);
82104

0 commit comments

Comments
 (0)