Merge pull request #2426 from bytecodealliance/main
Merge branch main into dev/wasi-libc-windows
This commit is contained in:
@ -7,6 +7,7 @@
|
||||
#define _WASM_EXEC_ENV_H
|
||||
|
||||
#include "bh_assert.h"
|
||||
#include "wasm_suspend_flags.h"
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
#include "../interpreter/wasm.h"
|
||||
#endif
|
||||
@ -57,15 +58,8 @@ typedef struct WASMExecEnv {
|
||||
exception. */
|
||||
uint8 *native_stack_boundary;
|
||||
|
||||
/* Used to terminate or suspend current thread
|
||||
bit 0: need to terminate
|
||||
bit 1: need to suspend
|
||||
bit 2: need to go into breakpoint
|
||||
bit 3: return from pthread_exit */
|
||||
union {
|
||||
uint32 flags;
|
||||
uintptr_t __padding__;
|
||||
} suspend_flags;
|
||||
/* Used to terminate or suspend current thread */
|
||||
WASMSuspendFlags suspend_flags;
|
||||
|
||||
/* Auxiliary stack boundary */
|
||||
union {
|
||||
|
||||
@ -608,7 +608,7 @@ wasm_enlarge_memory_internal(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
}
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (memory->is_shared) {
|
||||
if (shared_memory_is_shared(memory)) {
|
||||
memory->num_bytes_per_page = num_bytes_per_page;
|
||||
memory->cur_page_count = total_page_count;
|
||||
memory->max_page_count = max_page_count;
|
||||
@ -769,52 +769,14 @@ wasm_enlarge_memory(WASMModuleInstance *module, uint32 inc_page_count)
|
||||
bool ret = false;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module->module);
|
||||
if (node)
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
if (module->memory_count > 0)
|
||||
shared_memory_lock(module->memories[0]);
|
||||
#endif
|
||||
ret = wasm_enlarge_memory_internal(module, inc_page_count);
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
if (module->memory_count > 0)
|
||||
shared_memory_unlock(module->memories[0]);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||
uint32
|
||||
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node)
|
||||
{
|
||||
uint32 num_bytes_per_page;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
|
||||
#endif
|
||||
num_bytes_per_page = memory->num_bytes_per_page;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
|
||||
#endif
|
||||
return num_bytes_per_page;
|
||||
}
|
||||
|
||||
uint32
|
||||
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node)
|
||||
{
|
||||
uint32 linear_mem_size;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_lock(&((WASMSharedMemNode *)node)->shared_mem_lock);
|
||||
#endif
|
||||
linear_mem_size = memory->num_bytes_per_page * memory->cur_page_count;
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&((WASMSharedMemNode *)node)->shared_mem_lock);
|
||||
#endif
|
||||
return linear_mem_size;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -24,16 +24,6 @@ wasm_runtime_memory_destroy();
|
||||
unsigned
|
||||
wasm_runtime_memory_pool_size();
|
||||
|
||||
#if !defined(OS_ENABLE_HW_BOUND_CHECK) \
|
||||
|| WASM_CPU_SUPPORTS_UNALIGNED_ADDR_ACCESS == 0 \
|
||||
|| WASM_ENABLE_BULK_MEMORY != 0
|
||||
uint32
|
||||
wasm_get_num_bytes_per_page(WASMMemoryInstance *memory, void *node);
|
||||
|
||||
uint32
|
||||
wasm_get_linear_memory_size(WASMMemoryInstance *memory, void *node);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1196,7 +1196,8 @@ wasm_runtime_unload(WASMModuleCommon *module)
|
||||
}
|
||||
|
||||
WASMModuleInstanceCommon *
|
||||
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
|
||||
wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, char *error_buf,
|
||||
uint32 error_buf_size)
|
||||
@ -1204,14 +1205,14 @@ wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
if (module->module_type == Wasm_Module_Bytecode)
|
||||
return (WASMModuleInstanceCommon *)wasm_instantiate(
|
||||
(WASMModule *)module, is_sub_inst, exec_env_main, stack_size,
|
||||
heap_size, error_buf, error_buf_size);
|
||||
(WASMModule *)module, (WASMModuleInstance *)parent, exec_env_main,
|
||||
stack_size, heap_size, error_buf, error_buf_size);
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
if (module->module_type == Wasm_Module_AoT)
|
||||
return (WASMModuleInstanceCommon *)aot_instantiate(
|
||||
(AOTModule *)module, is_sub_inst, exec_env_main, stack_size,
|
||||
heap_size, error_buf, error_buf_size);
|
||||
(AOTModule *)module, (AOTModuleInstance *)parent, exec_env_main,
|
||||
stack_size, heap_size, error_buf, error_buf_size);
|
||||
#endif
|
||||
set_error_buf(error_buf, error_buf_size,
|
||||
"Instantiate module failed, invalid module type");
|
||||
@ -1224,7 +1225,7 @@ wasm_runtime_instantiate(WASMModuleCommon *module, uint32 stack_size,
|
||||
uint32 error_buf_size)
|
||||
{
|
||||
return wasm_runtime_instantiate_internal(
|
||||
module, false, NULL, stack_size, heap_size, error_buf, error_buf_size);
|
||||
module, NULL, NULL, stack_size, heap_size, error_buf, error_buf_size);
|
||||
}
|
||||
|
||||
void
|
||||
@ -2310,10 +2311,8 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
WASMExecEnv *exec_env = NULL;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
|
||||
if (node)
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
#endif
|
||||
if (exception) {
|
||||
snprintf(module_inst->cur_exception, sizeof(module_inst->cur_exception),
|
||||
@ -2323,8 +2322,8 @@ wasm_set_exception(WASMModuleInstance *module_inst, const char *exception)
|
||||
module_inst->cur_exception[0] = '\0';
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
#endif
|
||||
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
@ -2386,10 +2385,8 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
|
||||
bool has_exception = false;
|
||||
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
WASMSharedMemNode *node =
|
||||
wasm_module_get_shared_memory((WASMModuleCommon *)module_inst->module);
|
||||
if (node)
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_lock(module_inst->memories[0]);
|
||||
#endif
|
||||
if (module_inst->cur_exception[0] != '\0') {
|
||||
/* NULL is passed if the caller is not interested in getting the
|
||||
@ -2403,8 +2400,8 @@ wasm_copy_exception(WASMModuleInstance *module_inst, char *exception_buf)
|
||||
has_exception = true;
|
||||
}
|
||||
#if WASM_ENABLE_SHARED_MEMORY != 0
|
||||
if (node)
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
if (module_inst->memory_count > 0)
|
||||
shared_memory_unlock(module_inst->memories[0]);
|
||||
#endif
|
||||
|
||||
return has_exception;
|
||||
|
||||
@ -498,7 +498,8 @@ wasm_runtime_unload(WASMModuleCommon *module);
|
||||
|
||||
/* Internal API */
|
||||
WASMModuleInstanceCommon *
|
||||
wasm_runtime_instantiate_internal(WASMModuleCommon *module, bool is_sub_inst,
|
||||
wasm_runtime_instantiate_internal(WASMModuleCommon *module,
|
||||
WASMModuleInstanceCommon *parent,
|
||||
WASMExecEnv *exec_env_main, uint32 stack_size,
|
||||
uint32 heap_size, char *error_buf,
|
||||
uint32 error_buf_size);
|
||||
|
||||
@ -9,9 +9,16 @@
|
||||
#include "../libraries/thread-mgr/thread_manager.h"
|
||||
#endif
|
||||
|
||||
static bh_list shared_memory_list_head;
|
||||
static bh_list *const shared_memory_list = &shared_memory_list_head;
|
||||
static korp_mutex shared_memory_list_lock;
|
||||
/*
|
||||
* Note: this lock can be per memory.
|
||||
*
|
||||
* For now, just use a global because:
|
||||
* - it's a bit cumbersome to extend WASMMemoryInstance w/o breaking
|
||||
* the AOT ABI.
|
||||
* - If you care performance, it's better to make the interpreters
|
||||
* use atomic ops.
|
||||
*/
|
||||
static korp_mutex _shared_memory_lock;
|
||||
|
||||
/* clang-format off */
|
||||
enum {
|
||||
@ -48,17 +55,15 @@ destroy_wait_info(void *wait_info);
|
||||
bool
|
||||
wasm_shared_memory_init()
|
||||
{
|
||||
if (os_mutex_init(&shared_memory_list_lock) != 0)
|
||||
if (os_mutex_init(&_shared_memory_lock) != 0)
|
||||
return false;
|
||||
|
||||
/* wait map not exists, create new map */
|
||||
if (!(wait_map = bh_hash_map_create(32, true, (HashFunc)wait_address_hash,
|
||||
(KeyEqualFunc)wait_address_equal, NULL,
|
||||
destroy_wait_info))) {
|
||||
os_mutex_destroy(&shared_memory_list_lock);
|
||||
os_mutex_destroy(&_shared_memory_lock);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -66,110 +71,79 @@ void
|
||||
wasm_shared_memory_destroy()
|
||||
{
|
||||
bh_hash_map_destroy(wait_map);
|
||||
os_mutex_destroy(&shared_memory_list_lock);
|
||||
os_mutex_destroy(&_shared_memory_lock);
|
||||
}
|
||||
|
||||
static WASMSharedMemNode *
|
||||
search_module(WASMModuleCommon *module)
|
||||
uint32
|
||||
shared_memory_inc_reference(WASMMemoryInstance *memory)
|
||||
{
|
||||
WASMSharedMemNode *node;
|
||||
|
||||
os_mutex_lock(&shared_memory_list_lock);
|
||||
node = bh_list_first_elem(shared_memory_list);
|
||||
|
||||
while (node) {
|
||||
if (module == node->module) {
|
||||
os_mutex_unlock(&shared_memory_list_lock);
|
||||
return node;
|
||||
}
|
||||
node = bh_list_elem_next(node);
|
||||
}
|
||||
|
||||
os_mutex_unlock(&shared_memory_list_lock);
|
||||
return NULL;
|
||||
bh_assert(shared_memory_is_shared(memory));
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_FETCH_ADD(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
#endif
|
||||
bh_assert(old >= 1);
|
||||
bh_assert(old < UINT32_MAX);
|
||||
return old + 1;
|
||||
}
|
||||
|
||||
WASMSharedMemNode *
|
||||
wasm_module_get_shared_memory(WASMModuleCommon *module)
|
||||
uint32
|
||||
shared_memory_dec_reference(WASMMemoryInstance *memory)
|
||||
{
|
||||
return search_module(module);
|
||||
bh_assert(shared_memory_is_shared(memory));
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_FETCH_SUB(memory->ref_count, 1);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
#endif
|
||||
bh_assert(old > 0);
|
||||
return old - 1;
|
||||
}
|
||||
|
||||
int32
|
||||
shared_memory_inc_reference(WASMModuleCommon *module)
|
||||
bool
|
||||
shared_memory_is_shared(WASMMemoryInstance *memory)
|
||||
{
|
||||
WASMSharedMemNode *node = search_module(module);
|
||||
uint32 ref_count = -1;
|
||||
if (node) {
|
||||
os_mutex_lock(&node->lock);
|
||||
ref_count = ++node->ref_count;
|
||||
os_mutex_unlock(&node->lock);
|
||||
}
|
||||
return ref_count;
|
||||
uint32 old;
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
#endif
|
||||
old = BH_ATOMIC_32_LOAD(memory->ref_count);
|
||||
#if BH_ATOMIC_32_IS_ATOMIC == 0
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
#endif
|
||||
return old > 0;
|
||||
}
|
||||
|
||||
int32
|
||||
shared_memory_dec_reference(WASMModuleCommon *module)
|
||||
static korp_mutex *
|
||||
shared_memory_get_lock_pointer(WASMMemoryInstance *memory)
|
||||
{
|
||||
WASMSharedMemNode *node = search_module(module);
|
||||
uint32 ref_count = 0;
|
||||
if (node) {
|
||||
os_mutex_lock(&node->lock);
|
||||
ref_count = --node->ref_count;
|
||||
os_mutex_unlock(&node->lock);
|
||||
if (ref_count == 0) {
|
||||
os_mutex_lock(&shared_memory_list_lock);
|
||||
bh_list_remove(shared_memory_list, node);
|
||||
os_mutex_unlock(&shared_memory_list_lock);
|
||||
|
||||
os_mutex_destroy(&node->shared_mem_lock);
|
||||
os_mutex_destroy(&node->lock);
|
||||
wasm_runtime_free(node);
|
||||
}
|
||||
return ref_count;
|
||||
}
|
||||
|
||||
return -1;
|
||||
bh_assert(memory != NULL);
|
||||
return &_shared_memory_lock;
|
||||
}
|
||||
|
||||
WASMMemoryInstanceCommon *
|
||||
shared_memory_get_memory_inst(WASMSharedMemNode *node)
|
||||
void
|
||||
shared_memory_lock(WASMMemoryInstance *memory)
|
||||
{
|
||||
return node->memory_inst;
|
||||
/*
|
||||
* Note: exception logic is currently abusing this lock.
|
||||
* cf. https://github.com/bytecodealliance/wasm-micro-runtime/issues/2407
|
||||
*/
|
||||
bh_assert(memory != NULL);
|
||||
os_mutex_lock(&_shared_memory_lock);
|
||||
}
|
||||
|
||||
WASMSharedMemNode *
|
||||
shared_memory_set_memory_inst(WASMModuleCommon *module,
|
||||
WASMMemoryInstanceCommon *memory)
|
||||
void
|
||||
shared_memory_unlock(WASMMemoryInstance *memory)
|
||||
{
|
||||
WASMSharedMemNode *node;
|
||||
bh_list_status ret;
|
||||
|
||||
if (!(node = wasm_runtime_malloc(sizeof(WASMSharedMemNode))))
|
||||
return NULL;
|
||||
|
||||
node->module = module;
|
||||
node->memory_inst = memory;
|
||||
node->ref_count = 1;
|
||||
|
||||
if (os_mutex_init(&node->shared_mem_lock) != 0) {
|
||||
wasm_runtime_free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (os_mutex_init(&node->lock) != 0) {
|
||||
os_mutex_destroy(&node->shared_mem_lock);
|
||||
wasm_runtime_free(node);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
os_mutex_lock(&shared_memory_list_lock);
|
||||
ret = bh_list_insert(shared_memory_list, node);
|
||||
bh_assert(ret == BH_LIST_SUCCESS);
|
||||
os_mutex_unlock(&shared_memory_list_lock);
|
||||
|
||||
(void)ret;
|
||||
return node;
|
||||
bh_assert(memory != NULL);
|
||||
os_mutex_unlock(&_shared_memory_lock);
|
||||
}
|
||||
|
||||
/* Atomics wait && notify APIs */
|
||||
@ -307,7 +281,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
|
||||
AtomicWaitInfo *wait_info;
|
||||
AtomicWaitNode *wait_node;
|
||||
WASMSharedMemNode *node;
|
||||
korp_mutex *lock;
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
WASMExecEnv *exec_env;
|
||||
#endif
|
||||
@ -322,7 +296,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
}
|
||||
|
||||
/* Currently we have only one memory instance */
|
||||
if (!module_inst->memories[0]->is_shared) {
|
||||
if (!shared_memory_is_shared(module_inst->memories[0])) {
|
||||
wasm_runtime_set_exception(module, "expected shared memory");
|
||||
return -1;
|
||||
}
|
||||
@ -340,30 +314,29 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
bh_assert(exec_env);
|
||||
#endif
|
||||
|
||||
node = search_module((WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(node);
|
||||
lock = shared_memory_get_lock_pointer(module_inst->memories[0]);
|
||||
|
||||
/* Lock the shared_mem_lock for the whole atomic wait process,
|
||||
and use it to os_cond_reltimedwait */
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
os_mutex_lock(lock);
|
||||
|
||||
no_wait = (!wait64 && *(uint32 *)address != (uint32)expect)
|
||||
|| (wait64 && *(uint64 *)address != expect);
|
||||
|
||||
if (no_wait) {
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(wait_node = wasm_runtime_malloc(sizeof(AtomicWaitNode)))) {
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
wasm_runtime_set_exception(module, "failed to create wait node");
|
||||
return -1;
|
||||
}
|
||||
memset(wait_node, 0, sizeof(AtomicWaitNode));
|
||||
|
||||
if (0 != os_cond_init(&wait_node->wait_cond)) {
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
wasm_runtime_free(wait_node);
|
||||
wasm_runtime_set_exception(module, "failed to init wait cond");
|
||||
return -1;
|
||||
@ -375,7 +348,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
wait_info = acquire_wait_info(address, wait_node);
|
||||
|
||||
if (!wait_info) {
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
os_cond_destroy(&wait_node->wait_cond);
|
||||
wasm_runtime_free(wait_node);
|
||||
wasm_runtime_set_exception(module, "failed to acquire wait_info");
|
||||
@ -390,7 +363,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
if (timeout < 0) {
|
||||
/* wait forever until it is notified or terminatied
|
||||
here we keep waiting and checking every second */
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock,
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, lock,
|
||||
(uint64)timeout_1sec);
|
||||
if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
@ -404,8 +377,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
else {
|
||||
timeout_wait =
|
||||
timeout_left < timeout_1sec ? timeout_left : timeout_1sec;
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, &node->shared_mem_lock,
|
||||
timeout_wait);
|
||||
os_cond_reltimedwait(&wait_node->wait_cond, lock, timeout_wait);
|
||||
if (wait_node->status == S_NOTIFIED /* notified by atomic.notify */
|
||||
|| timeout_left <= timeout_wait /* time out */
|
||||
#if WASM_ENABLE_THREAD_MGR != 0
|
||||
@ -433,7 +405,7 @@ wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
/* Release wait info if no wait nodes are attached */
|
||||
map_try_release_wait_info(wait_map, wait_info, address);
|
||||
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
|
||||
return is_timeout ? 2 : 0;
|
||||
}
|
||||
@ -445,7 +417,7 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
|
||||
WASMModuleInstance *module_inst = (WASMModuleInstance *)module;
|
||||
uint32 notify_result;
|
||||
AtomicWaitInfo *wait_info;
|
||||
WASMSharedMemNode *node;
|
||||
korp_mutex *lock;
|
||||
bool out_of_bounds;
|
||||
|
||||
bh_assert(module->module_type == Wasm_Module_Bytecode
|
||||
@ -461,31 +433,30 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
|
||||
}
|
||||
|
||||
/* Currently we have only one memory instance */
|
||||
if (!module_inst->memories[0]->is_shared) {
|
||||
if (!shared_memory_is_shared(module_inst->memories[0])) {
|
||||
/* Always return 0 for ushared linear memory since there is
|
||||
no way to create a waiter on it */
|
||||
return 0;
|
||||
}
|
||||
|
||||
node = search_module((WASMModuleCommon *)module_inst->module);
|
||||
bh_assert(node);
|
||||
lock = shared_memory_get_lock_pointer(module_inst->memories[0]);
|
||||
|
||||
/* Lock the shared_mem_lock for the whole atomic notify process,
|
||||
and use it to os_cond_signal */
|
||||
os_mutex_lock(&node->shared_mem_lock);
|
||||
os_mutex_lock(lock);
|
||||
|
||||
wait_info = acquire_wait_info(address, NULL);
|
||||
|
||||
/* Nobody wait on this address */
|
||||
if (!wait_info) {
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Notify each wait node in the wait list */
|
||||
notify_result = notify_wait_list(wait_info->wait_list, count);
|
||||
|
||||
os_mutex_unlock(&node->shared_mem_lock);
|
||||
os_mutex_unlock(lock);
|
||||
|
||||
return notify_result;
|
||||
}
|
||||
|
||||
@ -7,53 +7,33 @@
|
||||
#define _WASM_SHARED_MEMORY_H
|
||||
|
||||
#include "bh_common.h"
|
||||
#if WASM_ENABLE_INTERP != 0
|
||||
#include "wasm_runtime.h"
|
||||
#endif
|
||||
#if WASM_ENABLE_AOT != 0
|
||||
#include "aot_runtime.h"
|
||||
#endif
|
||||
#include "../interpreter/wasm_runtime.h"
|
||||
#include "wasm_runtime_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct WASMSharedMemNode {
|
||||
bh_list_link l;
|
||||
/* Lock */
|
||||
korp_mutex lock;
|
||||
/* The module reference */
|
||||
WASMModuleCommon *module;
|
||||
/* The memory information */
|
||||
WASMMemoryInstanceCommon *memory_inst;
|
||||
/* Lock used for atomic operations */
|
||||
korp_mutex shared_mem_lock;
|
||||
|
||||
/* reference count */
|
||||
uint32 ref_count;
|
||||
} WASMSharedMemNode;
|
||||
|
||||
bool
|
||||
wasm_shared_memory_init();
|
||||
|
||||
void
|
||||
wasm_shared_memory_destroy();
|
||||
|
||||
WASMSharedMemNode *
|
||||
wasm_module_get_shared_memory(WASMModuleCommon *module);
|
||||
uint32
|
||||
shared_memory_inc_reference(WASMMemoryInstance *memory);
|
||||
|
||||
int32
|
||||
shared_memory_inc_reference(WASMModuleCommon *module);
|
||||
uint32
|
||||
shared_memory_dec_reference(WASMMemoryInstance *memory);
|
||||
|
||||
int32
|
||||
shared_memory_dec_reference(WASMModuleCommon *module);
|
||||
bool
|
||||
shared_memory_is_shared(WASMMemoryInstance *memory);
|
||||
|
||||
WASMMemoryInstanceCommon *
|
||||
shared_memory_get_memory_inst(WASMSharedMemNode *node);
|
||||
void
|
||||
shared_memory_lock(WASMMemoryInstance *memory);
|
||||
|
||||
WASMSharedMemNode *
|
||||
shared_memory_set_memory_inst(WASMModuleCommon *module,
|
||||
WASMMemoryInstanceCommon *memory);
|
||||
void
|
||||
shared_memory_unlock(WASMMemoryInstance *memory);
|
||||
|
||||
uint32
|
||||
wasm_runtime_atomic_wait(WASMModuleInstanceCommon *module, void *address,
|
||||
|
||||
48
core/iwasm/common/wasm_suspend_flags.h
Normal file
48
core/iwasm/common/wasm_suspend_flags.h
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Amazon Inc. All rights reserved.
|
||||
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
*/
|
||||
|
||||
#ifndef _WASM_SUSPEND_FLAGS_H
|
||||
#define _WASM_SUSPEND_FLAGS_H
|
||||
|
||||
#include "bh_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Need to terminate */
|
||||
#define WASM_SUSPEND_FLAG_TERMINATE 0x1
|
||||
/* Need to suspend */
|
||||
#define WASM_SUSPEND_FLAG_SUSPEND 0x2
|
||||
/* Need to go into breakpoint */
|
||||
#define WASM_SUSPEND_FLAG_BREAKPOINT 0x4
|
||||
/* Return from pthread_exit */
|
||||
#define WASM_SUSPEND_FLAG_EXIT 0x8
|
||||
|
||||
typedef union WASMSuspendFlags {
|
||||
bh_atomic_32_t flags;
|
||||
uintptr_t __padding__;
|
||||
} WASMSuspendFlags;
|
||||
|
||||
#define WASM_SUSPEND_FLAGS_IS_ATOMIC BH_ATOMIC_32_IS_ATOMIC
|
||||
#define WASM_SUSPEND_FLAGS_GET(s_flags) BH_ATOMIC_32_LOAD(s_flags.flags)
|
||||
#define WASM_SUSPEND_FLAGS_FETCH_OR(s_flags, val) \
|
||||
BH_ATOMIC_32_FETCH_OR(s_flags.flags, val)
|
||||
#define WASM_SUSPEND_FLAGS_FETCH_AND(s_flags, val) \
|
||||
BH_ATOMIC_32_FETCH_AND(s_flags.flags, val)
|
||||
|
||||
#if WASM_SUSPEND_FLAGS_IS_ATOMIC != 0
|
||||
#define WASM_SUSPEND_FLAGS_LOCK(lock) (void)0
|
||||
#define WASM_SUSPEND_FLAGS_UNLOCK(lock) (void)0
|
||||
#else /* else of WASM_SUSPEND_FLAGS_IS_ATOMIC */
|
||||
#define WASM_SUSPEND_FLAGS_LOCK(lock) os_mutex_lock(&lock)
|
||||
#define WASM_SUSPEND_FLAGS_UNLOCK(lock) os_mutex_unlock(&lock);
|
||||
#endif /* WASM_SUSPEND_FLAGS_IS_ATOMIC */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of _WASM_SUSPEND_FLAGS_H */
|
||||
Reference in New Issue
Block a user