You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The primary purpose of this feature is to prevent the use of global variables in the C language for storing runtime arguments and context.
This requirement has emerged from several embedded platforms where there is no POSIX-like process isolation. On these platforms, when multiple tasks or threads execute wasm_runtime_full_init() with various RuntimeInitArgs, such as using different MemAllocOption to execute different allocation strategies, conflicts arise. This is because the incoming RuntimeInitArgs are stored in global variables, which are actually shared among tasks or threads.
All tasks and threads are required to share the same runtime configuration. This encompasses a range of settings, including but not limited to: memory allocation strategy, running mode, gc heap size, JIT policy, WASI context, registered native functions, logging levels, error information, and more. This is not the solution that many products anticipate.
Design choice
let's refer to the outcome of wasm_runtime_full_init() as a runtime instance,
Smallest unit
The first question we need to address is whether we allow multiple runtime instances within a single task or thread. In other words, what is the smallest execution unit for a runtime instance? The concept of "nanoprocesses" comes to mind. If tasks or threads are the smallest unit, then Thread Local Storage (TLS) might be an option for storing the runtime context. However, if we agree that the smallest unit is smaller than a task or thread, or if it should not be tied to the current process/task/thread concepts(may let embedding decide), then creating a new runtime instance structure becomes necessary.
Global variables
Examine the global variables within the libvm.so library carefully. $ readelf -s --wide --demangle libvmlib.a | grep OBJECT.
LLVM ORC JIT
The LLVM environment should be initialized just once per process. It is permissible to create multiple LLJIT instances for different target machines. Each LLJIT instance can include multiple passes with varying optimization levels and size requirements for the generated binary. Every LLJIT instance possesses its own thread-safe module to house jitted functions and its own JITDyLib to manage symbols, which helps prevent symbols from being accessed unexpectedly. Thus, it appears to be acceptable for each runtime instance to create its own LLJIT instances, generate jitted code, and execute it.
The remaining issue to address is the potential consequences of calling LLVMInitializeXXX() multiple times within a single process.
ASM JIT
to be continued
Consts
Some global variables are used as .rodata and can be shared across multiple runtime-instances. Below is a brief list of such variables:
aot_stack_xxx
handle_table in interpreters
invokeNative_XXX
exception_msgs for conversion from exception ids to strings
MEMORY_PAGE_SIZE and wasm_limits_max_default in wasm_c_api.h
quick_aot_entries
native_symbols_xxx and native_globals_xxx
valid_xxx, bit_cnt_llvm_intrinsic, block_name_xxx, target_sym_map, g_intrinsic_xxx, section_ids for aot and llvm jit
more
Variables
Other global variables should be converted into field members of a runtime instance and will be utilized in various ways across multiple runtime instances.
aot_error
g_shared_memory_lock, wait_map for shared-memory feature
externref_xxx for externref recording
reader, destroyer, register_module_xxx, loading_module_xxx for multi-module feature.
It appears correct that all runtime instances share the content of loaded module files(untouch) while maintaining their own linking resources (instances).
runtime_ref_count, runtime_lock. These are utilized to create a singleton runtime instance, which may no longer be necessary. Plus singleton_engine and engine_lock in wasm_c_api.c
runtime_running_mode
llvm_jit_options
jit_options for fast-jit
g_context_dtors, g_wasi_context_keys
g_native_symbols_list
global_pool_size, free_fuc, realloc_func, malloc_func, enlarge_memory_error_used_data, enlarge_memory_error_cb, pool_allocator, memory_mode from wasm_memory.
total_time_ms, last_time_ms, log_verbose_level from bh_log
prev_sig_act_XXX from pthread_manager
g_blocking_op_xxx from posix_blocking_ops
RuntimeInitArgs
more
The text was updated successfully, but these errors were encountered:
Background
The primary purpose of this feature is to prevent the use of global variables in the C language for storing runtime arguments and context.
This requirement has emerged from several embedded platforms where there is no POSIX-like process isolation. On these platforms, when multiple tasks or threads execute
wasm_runtime_full_init()
with variousRuntimeInitArgs
, such as using differentMemAllocOption
to execute different allocation strategies, conflicts arise. This is because the incomingRuntimeInitArgs
are stored in global variables, which are actually shared among tasks or threads.All tasks and threads are required to share the same runtime configuration. This encompasses a range of settings, including but not limited to: memory allocation strategy, running mode, gc heap size, JIT policy, WASI context, registered native functions, logging levels, error information, and more. This is not the solution that many products anticipate.
Design choice
let's refer to the outcome of
wasm_runtime_full_init()
as a runtime instance,Smallest unit
The first question we need to address is whether we allow multiple runtime instances within a single task or thread. In other words, what is the smallest execution unit for a runtime instance? The concept of "nanoprocesses" comes to mind. If tasks or threads are the smallest unit, then Thread Local Storage (TLS) might be an option for storing the runtime context. However, if we agree that the smallest unit is smaller than a task or thread, or if it should not be tied to the current process/task/thread concepts(may let embedding decide), then creating a new runtime instance structure becomes necessary.
Global variables
Examine the global variables within the libvm.so library carefully.
$ readelf -s --wide --demangle libvmlib.a | grep OBJECT
.LLVM ORC JIT
The LLVM environment should be initialized just once per process. It is permissible to create multiple LLJIT instances for different target machines. Each LLJIT instance can include multiple passes with varying optimization levels and size requirements for the generated binary. Every LLJIT instance possesses its own thread-safe module to house jitted functions and its own JITDyLib to manage symbols, which helps prevent symbols from being accessed unexpectedly. Thus, it appears to be acceptable for each runtime instance to create its own LLJIT instances, generate jitted code, and execute it.
The remaining issue to address is the potential consequences of calling
LLVMInitializeXXX()
multiple times within a single process.ASM JIT
to be continued
Consts
Some global variables are used as .rodata and can be shared across multiple runtime-instances. Below is a brief list of such variables:
aot_stack_xxx
handle_table
in interpretersinvokeNative_XXX
exception_msgs
for conversion from exception ids to stringsMEMORY_PAGE_SIZE
andwasm_limits_max_default
in wasm_c_api.hquick_aot_entries
native_symbols_xxx
andnative_globals_xxx
valid_xxx
,bit_cnt_llvm_intrinsic
,block_name_xxx
,target_sym_map
,g_intrinsic_xxx
,section_ids
for aot and llvm jitVariables
Other global variables should be converted into field members of a runtime instance and will be utilized in various ways across multiple runtime instances.
aot_error
g_shared_memory_lock
,wait_map
for shared-memory featureexternref_xxx
for externref recordingreader
,destroyer
,register_module_xxx
,loading_module_xxx
for multi-module feature.It appears correct that all runtime instances share the content of loaded module files(untouch) while maintaining their own linking resources (instances).
runtime_ref_count
,runtime_lock
. These are utilized to create a singleton runtime instance, which may no longer be necessary. Plussingleton_engine
andengine_lock
in wasm_c_api.cruntime_running_mode
llvm_jit_options
jit_options
for fast-jitg_context_dtors
,g_wasi_context_keys
g_native_symbols_list
global_pool_size
,free_fuc
,realloc_func
,malloc_func
,enlarge_memory_error_used_data
,enlarge_memory_error_cb
,pool_allocator
,memory_mode
from wasm_memory.total_time_ms
,last_time_ms
,log_verbose_level
from bh_logprev_sig_act_XXX
from pthread_managerg_blocking_op_xxx
from posix_blocking_opsRuntimeInitArgs
The text was updated successfully, but these errors were encountered: