Implement module instance context APIs (#2436)
Introduce module instance context APIs which can set one or more contexts created
by the embedder for a wasm module instance:
```C
wasm_runtime_create_context_key
wasm_runtime_destroy_context_key
wasm_runtime_set_context
wasm_runtime_set_context_spread
wasm_runtime_get_context
```
And make libc-wasi use it and set wasi context as the first context bound to the wasm
module instance.
Also add samples.
Refer to https://github.com/bytecodealliance/wasm-micro-runtime/issues/2460.
This commit is contained in:
@ -480,4 +480,9 @@
|
||||
#define WASM_MEM_DUAL_BUS_MIRROR 0
|
||||
#endif
|
||||
|
||||
/* The max number of module instance contexts. */
|
||||
#ifndef WASM_MAX_INSTANCE_CONTEXTS
|
||||
#define WASM_MAX_INSTANCE_CONTEXTS 8
|
||||
#endif
|
||||
|
||||
#endif /* end of _CONFIG_H_ */
|
||||
|
||||
@ -1276,12 +1276,10 @@ aot_deinstantiate(AOTModuleInstance *module_inst, bool is_sub_inst)
|
||||
->common.c_api_func_imports);
|
||||
|
||||
if (!is_sub_inst) {
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
#if WASM_ENABLE_WASI_NN != 0
|
||||
wasi_nn_destroy(module_inst);
|
||||
#endif
|
||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||
}
|
||||
|
||||
wasm_runtime_free(module_inst);
|
||||
|
||||
@ -6,6 +6,15 @@
|
||||
#include "wasm_native.h"
|
||||
#include "wasm_runtime_common.h"
|
||||
#include "bh_log.h"
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
#include "../interpreter/wasm_runtime.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
#include "../aot/aot_runtime.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
#include "../libraries/thread-mgr/thread_manager.h"
|
||||
#endif
|
||||
|
||||
#if !defined(BH_PLATFORM_ZEPHYR) && !defined(BH_PLATFORM_ALIOS_THINGS) \
|
||||
&& !defined(BH_PLATFORM_OPENRTOS) && !defined(BH_PLATFORM_ESP_IDF)
|
||||
@ -22,6 +31,10 @@
|
||||
|
||||
static NativeSymbolsList g_native_symbols_list = NULL;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
static void *g_wasi_context_key;
|
||||
#endif /* WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
uint32
|
||||
get_libc_builtin_export_apis(NativeSymbol **p_libc_builtin_apis);
|
||||
|
||||
@ -394,6 +407,155 @@ wasm_native_unregister_natives(const char *module_name,
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
static uint32
|
||||
context_key_to_idx(void *key)
|
||||
{
|
||||
bh_assert(key != NULL);
|
||||
uint32 idx = (uint32)(uintptr_t)key;
|
||||
bh_assert(idx > 0);
|
||||
bh_assert(idx <= WASM_MAX_INSTANCE_CONTEXTS);
|
||||
return idx - 1;
|
||||
}
|
||||
|
||||
static void *
|
||||
context_idx_to_key(uint32 idx)
|
||||
{
|
||||
bh_assert(idx < WASM_MAX_INSTANCE_CONTEXTS);
|
||||
return (void *)(uintptr_t)(idx + 1);
|
||||
}
|
||||
|
||||
typedef void (*dtor_t)(WASMModuleInstanceCommon *, void *);
|
||||
static dtor_t g_context_dtors[WASM_MAX_INSTANCE_CONTEXTS];
|
||||
|
||||
static void
|
||||
dtor_noop(WASMModuleInstanceCommon *inst, void *ctx)
|
||||
{}
|
||||
|
||||
void *
|
||||
wasm_native_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx))
|
||||
{
|
||||
uint32 i;
|
||||
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
|
||||
if (g_context_dtors[i] == NULL) {
|
||||
if (dtor == NULL) {
|
||||
dtor = dtor_noop;
|
||||
}
|
||||
g_context_dtors[i] = dtor;
|
||||
return context_idx_to_key(i);
|
||||
}
|
||||
}
|
||||
LOG_ERROR("failed to allocate instance context key");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_destroy_context_key(void *key)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
bh_assert(g_context_dtors[idx] != NULL);
|
||||
g_context_dtors[idx] = NULL;
|
||||
}
|
||||
|
||||
static WASMModuleInstanceExtraCommon *
|
||||
wasm_module_inst_extra_common(WASMModuleInstanceCommon *inst)
|
||||
{
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (inst->module_type == Wasm_Module_Bytecode) {
|
||||
return &((WASMModuleInstance *)inst)->e->common;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (inst->module_type == Wasm_Module_AoT) {
|
||||
return &((AOTModuleInstanceExtra *)((AOTModuleInstance *)inst)->e)
|
||||
->common;
|
||||
}
|
||||
#endif
|
||||
bh_assert(false);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
common->contexts[idx] = ctx;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx)
|
||||
{
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
wasm_cluster_set_context(inst, key, ctx);
|
||||
#else
|
||||
wasm_native_set_context(inst, key, ctx);
|
||||
#endif
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_native_get_context(WASMModuleInstanceCommon *inst, void *key)
|
||||
{
|
||||
uint32 idx = context_key_to_idx(key);
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
return common->contexts[idx];
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_call_context_dtors(WASMModuleInstanceCommon *inst)
|
||||
{
|
||||
WASMModuleInstanceExtraCommon *common = wasm_module_inst_extra_common(inst);
|
||||
uint32 i;
|
||||
for (i = 0; i < WASM_MAX_INSTANCE_CONTEXTS; i++) {
|
||||
dtor_t dtor = g_context_dtors[i];
|
||||
if (dtor != NULL) {
|
||||
dtor(inst, common->contexts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
wasm_native_inherit_contexts(WASMModuleInstanceCommon *child,
|
||||
WASMModuleInstanceCommon *parent)
|
||||
{
|
||||
WASMModuleInstanceExtraCommon *parent_common =
|
||||
wasm_module_inst_extra_common(parent);
|
||||
WASMModuleInstanceExtraCommon *child_common =
|
||||
wasm_module_inst_extra_common(child);
|
||||
bh_memcpy_s(child_common->contexts,
|
||||
sizeof(*child_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS,
|
||||
parent_common->contexts,
|
||||
sizeof(*parent_common->contexts) * WASM_MAX_INSTANCE_CONTEXTS);
|
||||
}
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
return wasm_native_get_context(module_inst_comm, g_wasi_context_key);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
return wasm_native_set_context(module_inst_comm, g_wasi_context_key,
|
||||
wasi_ctx);
|
||||
}
|
||||
|
||||
static void
|
||||
wasi_context_dtor(WASMModuleInstanceCommon *inst, void *ctx)
|
||||
{
|
||||
if (ctx == NULL) {
|
||||
return;
|
||||
}
|
||||
wasm_runtime_destroy_wasi(inst);
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
bool
|
||||
wasm_native_init()
|
||||
{
|
||||
@ -420,6 +582,10 @@ wasm_native_init()
|
||||
#endif /* WASM_ENABLE_SPEC_TEST */
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
g_wasi_context_key = wasm_native_create_context_key(wasi_context_dtor);
|
||||
if (g_wasi_context_key == NULL) {
|
||||
goto fail;
|
||||
}
|
||||
n_native_symbols = get_libc_wasi_export_apis(&native_symbols);
|
||||
if (!wasm_native_register_natives("wasi_unstable", native_symbols,
|
||||
n_native_symbols))
|
||||
@ -507,6 +673,12 @@ wasm_native_destroy()
|
||||
{
|
||||
NativeSymbolsNode *node, *node_next;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
if (g_wasi_context_key != NULL) {
|
||||
wasm_native_destroy_context_key(g_wasi_context_key);
|
||||
g_wasi_context_key = NULL;
|
||||
}
|
||||
#endif
|
||||
#if WASM_ENABLE_LIB_PTHREAD != 0
|
||||
lib_pthread_destroy();
|
||||
#endif
|
||||
|
||||
@ -68,6 +68,36 @@ bool
|
||||
wasm_native_unregister_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols);
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
struct WASMModuleInstanceCommon;
|
||||
|
||||
void *
|
||||
wasm_native_create_context_key(
|
||||
void (*dtor)(struct WASMModuleInstanceCommon *inst, void *ctx));
|
||||
|
||||
void
|
||||
wasm_native_destroy_context_key(void *key);
|
||||
|
||||
void
|
||||
wasm_native_set_context(struct WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
void
|
||||
wasm_native_set_context_spread(struct WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
void *
|
||||
wasm_native_get_context(struct WASMModuleInstanceCommon *inst, void *key);
|
||||
|
||||
void
|
||||
wasm_native_call_context_dtors(struct WASMModuleInstanceCommon *inst);
|
||||
|
||||
void
|
||||
wasm_native_inherit_contexts(struct WASMModuleInstanceCommon *child,
|
||||
struct WASMModuleInstanceCommon *parent);
|
||||
#else /* WASM_ENABLE_MODULE_INST_CONTEXT */
|
||||
#define wasm_native_call_context_dtors(inst) (void)(inst)
|
||||
#define wasm_native_inherit_contexts(child, parent) (void)(parent)
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT */
|
||||
|
||||
bool
|
||||
wasm_native_init();
|
||||
|
||||
|
||||
@ -3311,27 +3311,6 @@ wasm_runtime_get_wasi_exit_code(WASMModuleInstanceCommon *module_inst)
|
||||
#endif
|
||||
return wasi_ctx->exit_code;
|
||||
}
|
||||
|
||||
WASIContext *
|
||||
wasm_runtime_get_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
return module_inst->wasi_ctx;
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_wasi_ctx(WASMModuleInstanceCommon *module_inst_comm,
|
||||
WASIContext *wasi_ctx)
|
||||
{
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module_inst_comm;
|
||||
|
||||
bh_assert(module_inst_comm->module_type == Wasm_Module_Bytecode
|
||||
|| module_inst_comm->module_type == Wasm_Module_AoT);
|
||||
module_inst->wasi_ctx = wasi_ctx;
|
||||
}
|
||||
#endif /* end of WASM_ENABLE_LIBC_WASI */
|
||||
|
||||
WASMModuleCommon *
|
||||
@ -5681,3 +5660,37 @@ wasm_runtime_is_import_global_linked(const char *module_name,
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
void *
|
||||
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx))
|
||||
{
|
||||
return wasm_native_create_context_key(dtor);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_destroy_context_key(void *key)
|
||||
{
|
||||
wasm_native_destroy_context_key(key);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx)
|
||||
{
|
||||
wasm_native_set_context(inst, key, ctx);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx)
|
||||
{
|
||||
wasm_native_set_context_spread(inst, key, ctx);
|
||||
}
|
||||
|
||||
void *
|
||||
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key)
|
||||
{
|
||||
return wasm_native_get_context(inst, key);
|
||||
}
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
|
||||
|
||||
@ -939,6 +939,26 @@ WASM_RUNTIME_API_EXTERN bool
|
||||
wasm_runtime_unregister_natives(const char *module_name,
|
||||
NativeSymbol *native_symbols);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_create_context_key(void (*dtor)(WASMModuleInstanceCommon *inst,
|
||||
void *ctx));
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_destroy_context_key(void *key);
|
||||
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context(WASMModuleInstanceCommon *inst, void *key, void *ctx);
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context_spread(WASMModuleInstanceCommon *inst, void *key,
|
||||
void *ctx);
|
||||
/* See wasm_export.h for description */
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_get_context(WASMModuleInstanceCommon *inst, void *key);
|
||||
|
||||
bool
|
||||
wasm_runtime_invoke_native(WASMExecEnv *exec_env, void *func_ptr,
|
||||
const WASMType *func_type, const char *signature,
|
||||
|
||||
@ -1456,6 +1456,74 @@ WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_enlarge_mem_error_callback(
|
||||
const enlarge_memory_error_callback_t callback);
|
||||
|
||||
/*
|
||||
* module instance context APIs
|
||||
* wasm_runtime_create_context_key
|
||||
* wasm_runtime_destroy_context_key
|
||||
* wasm_runtime_set_context
|
||||
* wasm_runtime_set_context_spread
|
||||
* wasm_runtime_get_context
|
||||
*
|
||||
* This set of APIs is intended to be used by an embedder which provides
|
||||
* extra sets of native functions, which need per module instance state
|
||||
* and are maintained outside of the WAMR tree.
|
||||
*
|
||||
* It's modelled after the pthread specific API.
|
||||
*
|
||||
* wasm_runtime_set_context_spread is similar to
|
||||
* wasm_runtime_set_context, except that
|
||||
* wasm_runtime_set_context_spread applies the change
|
||||
* to all threads in the cluster.
|
||||
* It's an undefined behavior if multiple threads in a cluster call
|
||||
* wasm_runtime_set_context_spread on the same key
|
||||
* simultaneously. It's a caller's resposibility to perform necessary
|
||||
* serialization if necessary. For example:
|
||||
*
|
||||
* if (wasm_runtime_get_context(inst, key) == NULL) {
|
||||
* newctx = alloc_and_init(...);
|
||||
* lock(some_lock);
|
||||
* if (wasm_runtime_get_context(inst, key) == NULL) {
|
||||
* // this thread won the race
|
||||
* wasm_runtime_set_context_spread(inst, key, newctx);
|
||||
* newctx = NULL;
|
||||
* }
|
||||
* unlock(some_lock);
|
||||
* if (newctx != NULL) {
|
||||
* // this thread lost the race, free it
|
||||
* cleanup_and_free(newctx);
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* Note: dynamic key create/destroy while instances are live is not
|
||||
* implemented as of writing this.
|
||||
* it's caller's resposibility to ensure destorying all module instances
|
||||
* before calling wasm_runtime_create_context_key or
|
||||
* wasm_runtime_destroy_context_key.
|
||||
* otherwise, it's an undefined behavior.
|
||||
*
|
||||
* Note about threads:
|
||||
* - When spawning a thread, the contexts (the pointers given to
|
||||
* wasm_runtime_set_context) are copied from the parent
|
||||
* instance.
|
||||
* - The destructor is called only on the main instance.
|
||||
*/
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_create_context_key(
|
||||
void (*dtor)(wasm_module_inst_t inst, void *ctx));
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_destroy_context_key(void *key);
|
||||
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context(wasm_module_inst_t inst, void *key,
|
||||
void *ctx);
|
||||
WASM_RUNTIME_API_EXTERN void
|
||||
wasm_runtime_set_context_spread(wasm_module_inst_t inst, void *key,
|
||||
void *ctx);
|
||||
WASM_RUNTIME_API_EXTERN void *
|
||||
wasm_runtime_get_context(wasm_module_inst_t inst, void *key);
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -2233,12 +2233,10 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst)
|
||||
wasm_runtime_free(module_inst->e->common.c_api_func_imports);
|
||||
|
||||
if (!is_sub_inst) {
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasm_runtime_destroy_wasi((WASMModuleInstanceCommon *)module_inst);
|
||||
#endif
|
||||
#if WASM_ENABLE_WASI_NN != 0
|
||||
wasi_nn_destroy(module_inst);
|
||||
#endif
|
||||
wasm_native_call_context_dtors((WASMModuleInstanceCommon *)module_inst);
|
||||
}
|
||||
|
||||
wasm_runtime_free(module_inst);
|
||||
|
||||
@ -212,6 +212,7 @@ typedef struct CApiFuncImport {
|
||||
|
||||
/* The common part of WASMModuleInstanceExtra and AOTModuleInstanceExtra */
|
||||
typedef struct WASMModuleInstanceExtraCommon {
|
||||
void *contexts[WASM_MAX_INSTANCE_CONTEXTS];
|
||||
CApiFuncImport *c_api_func_imports;
|
||||
/* pointer to the exec env currently used */
|
||||
WASMExecEnv *cur_exec_env;
|
||||
@ -299,12 +300,8 @@ struct WASMModuleInstance {
|
||||
it denotes `AOTModule *` */
|
||||
DefPointer(WASMModule *, module);
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI
|
||||
/* WASI context */
|
||||
DefPointer(WASIContext *, wasi_ctx);
|
||||
#else
|
||||
DefPointer(void *, wasi_ctx);
|
||||
#endif
|
||||
DefPointer(void *, used_to_be_wasi_ctx); /* unused */
|
||||
|
||||
DefPointer(WASMExecEnv *, exec_env_singleton);
|
||||
/* Array of function pointers to import functions,
|
||||
not available in AOTModuleInstance */
|
||||
|
||||
@ -559,9 +559,6 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||
uint32 thread_handle;
|
||||
uint32 stack_size = 8192;
|
||||
int32 ret = -1;
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *wasi_ctx;
|
||||
#endif
|
||||
|
||||
bh_assert(module);
|
||||
bh_assert(module_inst);
|
||||
@ -588,11 +585,7 @@ pthread_create_wrapper(wasm_exec_env_t exec_env,
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasi_ctx = get_wasi_ctx(module_inst);
|
||||
if (wasi_ctx)
|
||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||
#endif
|
||||
wasm_native_inherit_contexts(new_module_inst, module_inst);
|
||||
|
||||
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
|
||||
goto fail;
|
||||
|
||||
@ -80,9 +80,6 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
|
||||
int32 thread_id;
|
||||
uint32 stack_size = 8192;
|
||||
int32 ret = -1;
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *wasi_ctx;
|
||||
#endif
|
||||
|
||||
bh_assert(module);
|
||||
bh_assert(module_inst);
|
||||
@ -99,11 +96,7 @@ thread_spawn_wrapper(wasm_exec_env_t exec_env, uint32 start_arg)
|
||||
if (!(wasm_cluster_dup_c_api_imports(new_module_inst, module_inst)))
|
||||
goto thread_preparation_fail;
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
|
||||
if (wasi_ctx)
|
||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||
#endif
|
||||
wasm_native_inherit_contexts(new_module_inst, module_inst);
|
||||
|
||||
start_func = wasm_runtime_lookup_function(new_module_inst,
|
||||
THREAD_START_FUNCTION, NULL);
|
||||
|
||||
@ -480,9 +480,6 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
||||
wasm_module_inst_t module_inst = get_module_inst(exec_env);
|
||||
wasm_module_t module;
|
||||
wasm_module_inst_t new_module_inst;
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
WASIContext *wasi_ctx;
|
||||
#endif
|
||||
WASMExecEnv *new_exec_env;
|
||||
uint32 aux_stack_start, aux_stack_size;
|
||||
uint32 stack_size = 8192;
|
||||
@ -520,10 +517,7 @@ wasm_cluster_spawn_exec_env(WASMExecEnv *exec_env)
|
||||
wasm_runtime_set_custom_data_internal(
|
||||
new_module_inst, wasm_runtime_get_custom_data(module_inst));
|
||||
|
||||
#if WASM_ENABLE_LIBC_WASI != 0
|
||||
wasi_ctx = wasm_runtime_get_wasi_ctx(module_inst);
|
||||
wasm_runtime_set_wasi_ctx(new_module_inst, wasi_ctx);
|
||||
#endif
|
||||
wasm_native_inherit_contexts(new_module_inst, module_inst);
|
||||
|
||||
new_exec_env = wasm_exec_env_create_internal(new_module_inst,
|
||||
exec_env->wasm_stack_size);
|
||||
@ -1324,6 +1318,48 @@ wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
|
||||
}
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_MODULE_INST_CONTEXT != 0
|
||||
struct inst_set_context_data {
|
||||
void *key;
|
||||
void *ctx;
|
||||
};
|
||||
|
||||
static void
|
||||
set_context_visitor(void *node, void *user_data)
|
||||
{
|
||||
WASMExecEnv *curr_exec_env = (WASMExecEnv *)node;
|
||||
WASMModuleInstanceCommon *module_inst = get_module_inst(curr_exec_env);
|
||||
const struct inst_set_context_data *data = user_data;
|
||||
|
||||
wasm_runtime_set_context(module_inst, data->key, data->ctx);
|
||||
}
|
||||
|
||||
void
|
||||
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
|
||||
void *ctx)
|
||||
{
|
||||
WASMExecEnv *exec_env = wasm_clusters_search_exec_env(module_inst);
|
||||
|
||||
if (exec_env == NULL) {
|
||||
/* Maybe threads have not been started yet. */
|
||||
wasm_runtime_set_context(module_inst, key, ctx);
|
||||
}
|
||||
else {
|
||||
WASMCluster *cluster;
|
||||
struct inst_set_context_data data;
|
||||
data.key = key;
|
||||
data.ctx = ctx;
|
||||
|
||||
cluster = wasm_exec_env_get_cluster(exec_env);
|
||||
bh_assert(cluster);
|
||||
|
||||
os_mutex_lock(&cluster->lock);
|
||||
traverse_list(&cluster->exec_env_list, set_context_visitor, &data);
|
||||
os_mutex_unlock(&cluster->lock);
|
||||
}
|
||||
}
|
||||
#endif /* WASM_ENABLE_MODULE_INST_CONTEXT != 0 */
|
||||
|
||||
bool
|
||||
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env)
|
||||
{
|
||||
|
||||
@ -151,6 +151,10 @@ void
|
||||
wasm_cluster_spread_custom_data(WASMModuleInstanceCommon *module_inst,
|
||||
void *custom_data);
|
||||
|
||||
void
|
||||
wasm_cluster_set_context(WASMModuleInstanceCommon *module_inst, void *key,
|
||||
void *ctx);
|
||||
|
||||
bool
|
||||
wasm_cluster_is_thread_terminated(WASMExecEnv *exec_env);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user