diff --git a/core/iwasm/common/wasm_shared_memory.c b/core/iwasm/common/wasm_shared_memory.c index 19b81f1b..6112b1ba 100644 --- a/core/iwasm/common/wasm_shared_memory.c +++ b/core/iwasm/common/wasm_shared_memory.c @@ -172,6 +172,7 @@ shared_memory_dec_reference(WASMModuleCommon *module) 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); } @@ -200,7 +201,14 @@ shared_memory_set_memory_inst(WASMModuleCommon *module, 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; } diff --git a/core/iwasm/common/wasm_shared_memory.h b/core/iwasm/common/wasm_shared_memory.h index 5cd6e0fc..98683f32 100644 --- a/core/iwasm/common/wasm_shared_memory.h +++ b/core/iwasm/common/wasm_shared_memory.h @@ -26,6 +26,8 @@ typedef struct WASMSharedMemNode { WASMModuleCommon *module; /* The memory information */ WASMMemoryInstanceCommon *memory_inst; + /* Lock used for atomic operations */ + korp_mutex shared_mem_lock; /* reference count */ uint32 ref_count; diff --git a/core/iwasm/interpreter/wasm.h b/core/iwasm/interpreter/wasm.h index c6aad29a..e6d02c3f 100644 --- a/core/iwasm/interpreter/wasm.h +++ b/core/iwasm/interpreter/wasm.h @@ -510,8 +510,8 @@ struct WASMModule { uint64 load_size; #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 \ - || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT \ +#if WASM_ENABLE_DEBUG_INTERP != 0 \ + || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ && WASM_ENABLE_LAZY_JIT != 0) /** * List of instances referred to this module. When source debugging diff --git a/core/iwasm/interpreter/wasm_interp_classic.c b/core/iwasm/interpreter/wasm_interp_classic.c index c8ef4f27..d8985713 100644 --- a/core/iwasm/interpreter/wasm_interp_classic.c +++ b/core/iwasm/interpreter/wasm_interp_classic.c @@ -696,28 +696,28 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min, CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint32)(*(uint8 *)maddr); \ *(uint8 *)maddr = (uint8)(readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint32)LOAD_U16(maddr); \ STORE_U16(maddr, (uint16)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = LOAD_I32(maddr); \ STORE_U32(maddr, readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ PUSH_I32(readv); \ break; \ @@ -736,39 +736,39 @@ trunc_f64_to_int(WASMModuleInstance *module, uint32 *frame_sp, float64 src_min, CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)(*(uint8 *)maddr); \ *(uint8 *)maddr = (uint8)(readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_U16(maddr); \ STORE_U16(maddr, (uint16)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_U32(maddr); \ STORE_U32(maddr, (uint32)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else { \ uint64 op_result; \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_I64(maddr); \ op_result = readv op sval; \ STORE_I64(maddr, op_result); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ PUSH_I64(readv); \ break; \ @@ -1151,6 +1151,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 cache_index, type_index, param_cell_num, cell_num; uint8 value_type; +#if WASM_ENABLE_SHARED_MEMORY != 0 + WASMSharedMemNode *node = + wasm_module_get_shared_memory((WASMModuleCommon *)module->module); +#endif + #if WASM_ENABLE_DEBUG_INTERP != 0 uint8 *frame_ip_orig = NULL; WASMDebugInstance *debug_instance = wasm_exec_env_get_instance(exec_env); @@ -3458,23 +3463,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)(*(uint8 *)maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)LOAD_U16(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I32(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I32(readv); @@ -3493,30 +3498,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)(*(uint8 *)maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U16(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U32(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I64(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); @@ -3535,23 +3540,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I32_STORE8) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); *(uint8 *)maddr = (uint8)sval; - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I32_STORE16) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U16(maddr, (uint16)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U32(maddr, frame_sp[1]); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } break; } @@ -3569,31 +3574,31 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I64_STORE8) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); *(uint8 *)maddr = (uint8)sval; - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_STORE16) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U16(maddr, (uint16)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_STORE32) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U32(maddr, (uint32)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); PUT_I64_TO_ADDR((uint32 *)maddr, GET_I64_FROM_ADDR(frame_sp + 1)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } break; } @@ -3613,32 +3618,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_ATOMIC_MEMORY_ACCESS(); expect = (uint8)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)(*(uint8 *)maddr); if (readv == expect) *(uint8 *)maddr = (uint8)(sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); expect = (uint16)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)LOAD_U16(maddr); if (readv == expect) STORE_U16(maddr, (uint16)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I32(maddr); if (readv == expect) STORE_U32(maddr, sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I32(readv); break; @@ -3659,44 +3664,44 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_ATOMIC_MEMORY_ACCESS(); expect = (uint8)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)(*(uint8 *)maddr); if (readv == expect) *(uint8 *)maddr = (uint8)(sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); expect = (uint16)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U16(maddr); if (readv == expect) STORE_U16(maddr, (uint16)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); expect = (uint32)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U32(maddr); if (readv == expect) STORE_U32(maddr, (uint32)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_I64(maddr); if (readv == expect) { STORE_I64(maddr, sval); } - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); break; diff --git a/core/iwasm/interpreter/wasm_interp_fast.c b/core/iwasm/interpreter/wasm_interp_fast.c index 7209f7bd..be924646 100644 --- a/core/iwasm/interpreter/wasm_interp_fast.c +++ b/core/iwasm/interpreter/wasm_interp_fast.c @@ -469,28 +469,28 @@ LOAD_PTR(void *addr) CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(1); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint32)(*(uint8 *)maddr); \ *(uint8 *)maddr = (uint8)(readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I32_##OP_NAME##16_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(2); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint32)LOAD_U16(maddr); \ STORE_U16(maddr, (uint16)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(4); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = LOAD_I32(maddr); \ STORE_U32(maddr, readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ PUSH_I32(readv); \ break; \ @@ -509,39 +509,39 @@ LOAD_PTR(void *addr) CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(1); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)(*(uint8 *)maddr); \ *(uint8 *)maddr = (uint8)(readv op sval); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##16_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(2); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_U16(maddr); \ STORE_U16(maddr, (uint16)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else if (opcode == WASM_OP_ATOMIC_RMW_I64_##OP_NAME##32_U) { \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(4); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_U32(maddr); \ STORE_U32(maddr, (uint32)(readv op sval)); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ else { \ uint64 op_result; \ CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); \ CHECK_ATOMIC_MEMORY_ACCESS(8); \ \ - os_mutex_lock(&module->e->mem_lock); \ + os_mutex_lock(&node->shared_mem_lock); \ readv = (uint64)LOAD_I64(maddr); \ op_result = readv op sval; \ STORE_I64(maddr, op_result); \ - os_mutex_unlock(&module->e->mem_lock); \ + os_mutex_unlock(&node->shared_mem_lock); \ } \ PUSH_I64(readv); \ break; \ @@ -1183,6 +1183,11 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, uint32 local_idx, local_offset, global_idx; uint8 opcode, local_type, *global_addr; +#if WASM_ENABLE_SHARED_MEMORY != 0 + WASMSharedMemNode *node = + wasm_module_get_shared_memory((WASMModuleCommon *)module->module); +#endif + #if WASM_ENABLE_LABELS_AS_VALUES != 0 #define HANDLE_OPCODE(op) &&HANDLE_##op DEFINE_GOTO_TABLE(const void *, handle_table); @@ -3296,23 +3301,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I32_LOAD8_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(1); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)(*(uint8 *)maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I32_LOAD16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)LOAD_U16(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I32(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I32(readv); @@ -3331,30 +3336,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I64_LOAD8_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(1); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)(*(uint8 *)maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_LOAD16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U16(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_LOAD32_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U32(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(8); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I64(maddr); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); @@ -3372,23 +3377,23 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I32_STORE8) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(1); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); *(uint8 *)maddr = (uint8)sval; - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I32_STORE16) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U16(maddr, (uint16)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U32(maddr, sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } break; } @@ -3406,30 +3411,30 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, if (opcode == WASM_OP_ATOMIC_I64_STORE8) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 1, maddr); CHECK_ATOMIC_MEMORY_ACCESS(1); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); *(uint8 *)maddr = (uint8)sval; - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_STORE16) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U16(maddr, (uint16)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_I64_STORE32) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_U32(maddr, (uint32)sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(8); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); STORE_I64(maddr, sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } break; } @@ -3449,32 +3454,32 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_ATOMIC_MEMORY_ACCESS(1); expect = (uint8)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)(*(uint8 *)maddr); if (readv == expect) *(uint8 *)maddr = (uint8)(sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I32_CMPXCHG16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); expect = (uint16)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint32)LOAD_U16(maddr); if (readv == expect) STORE_U16(maddr, (uint16)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = LOAD_I32(maddr); if (readv == expect) STORE_U32(maddr, sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I32(readv); break; @@ -3495,44 +3500,44 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module, CHECK_ATOMIC_MEMORY_ACCESS(1); expect = (uint8)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)(*(uint8 *)maddr); if (readv == expect) *(uint8 *)maddr = (uint8)(sval); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG16_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 2, maddr); CHECK_ATOMIC_MEMORY_ACCESS(2); expect = (uint16)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U16(maddr); if (readv == expect) STORE_U16(maddr, (uint16)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else if (opcode == WASM_OP_ATOMIC_RMW_I64_CMPXCHG32_U) { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 4, maddr); CHECK_ATOMIC_MEMORY_ACCESS(4); expect = (uint32)expect; - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_U32(maddr); if (readv == expect) STORE_U32(maddr, (uint32)(sval)); - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } else { CHECK_BULK_MEMORY_OVERFLOW(addr + offset, 8, maddr); CHECK_ATOMIC_MEMORY_ACCESS(8); - os_mutex_lock(&module->e->mem_lock); + os_mutex_lock(&node->shared_mem_lock); readv = (uint64)LOAD_I64(maddr); if (readv == expect) { STORE_I64(maddr, sval); } - os_mutex_unlock(&module->e->mem_lock); + os_mutex_unlock(&node->shared_mem_lock); } PUSH_I64(readv); break; diff --git a/core/iwasm/interpreter/wasm_loader.c b/core/iwasm/interpreter/wasm_loader.c index 5a9fcbfb..d69c0e07 100644 --- a/core/iwasm/interpreter/wasm_loader.c +++ b/core/iwasm/interpreter/wasm_loader.c @@ -3864,8 +3864,8 @@ create_module(char *error_buf, uint32 error_buf_size) bh_assert(ret == BH_LIST_SUCCESS); #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 \ - || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT \ +#if WASM_ENABLE_DEBUG_INTERP != 0 \ + || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ && WASM_ENABLE_LAZY_JIT != 0) if (os_mutex_init(&module->instance_list_lock) != 0) { set_error_buf(error_buf, error_buf_size, @@ -4253,7 +4253,8 @@ wasm_loader_unload(WASMModule *module) if (!module) return; -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 module->orcjit_stop_compiling = true; if (module->llvm_jit_init_thread) os_thread_join(module->llvm_jit_init_thread, NULL); @@ -4274,7 +4275,8 @@ wasm_loader_unload(WASMModule *module) aot_destroy_comp_data(module->comp_data); #endif -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 if (module->tierup_wait_lock_inited) { os_mutex_destroy(&module->tierup_wait_lock); os_cond_destroy(&module->tierup_wait_cond); @@ -4403,8 +4405,8 @@ wasm_loader_unload(WASMModule *module) } #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 \ - || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT \ +#if WASM_ENABLE_DEBUG_INTERP != 0 \ + || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ && WASM_ENABLE_LAZY_JIT != 0) os_mutex_destroy(&module->instance_list_lock); #endif diff --git a/core/iwasm/interpreter/wasm_mini_loader.c b/core/iwasm/interpreter/wasm_mini_loader.c index 6a5d83ad..92be851f 100644 --- a/core/iwasm/interpreter/wasm_mini_loader.c +++ b/core/iwasm/interpreter/wasm_mini_loader.c @@ -2725,7 +2725,8 @@ create_module(char *error_buf, uint32 error_buf_size) bh_assert(ret == BH_LIST_SUCCESS); #endif -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 if (os_mutex_init(&module->instance_list_lock) != 0) { set_error_buf(error_buf, error_buf_size, "init instance list lock failed"); @@ -2946,7 +2947,8 @@ wasm_loader_unload(WASMModule *module) if (!module) return; -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 module->orcjit_stop_compiling = true; if (module->llvm_jit_init_thread) os_thread_join(module->llvm_jit_init_thread, NULL); @@ -2967,7 +2969,8 @@ wasm_loader_unload(WASMModule *module) aot_destroy_comp_data(module->comp_data); #endif -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 if (module->tierup_wait_lock_inited) { os_mutex_destroy(&module->tierup_wait_lock); os_cond_destroy(&module->tierup_wait_cond); @@ -3063,7 +3066,8 @@ wasm_loader_unload(WASMModule *module) } #endif -#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT && WASM_ENABLE_LAZY_JIT != 0 +#if WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ + && WASM_ENABLE_LAZY_JIT != 0 os_mutex_destroy(&module->instance_list_lock); #endif diff --git a/core/iwasm/interpreter/wasm_runtime.c b/core/iwasm/interpreter/wasm_runtime.c index eabdea68..31b0d1ff 100644 --- a/core/iwasm/interpreter/wasm_runtime.c +++ b/core/iwasm/interpreter/wasm_runtime.c @@ -1587,15 +1587,6 @@ wasm_instantiate(WASMModule *module, bool is_sub_inst, uint32 stack_size, module_inst->e = (WASMModuleInstanceExtra *)((uint8 *)module_inst + extra_info_offset); -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (os_mutex_init(&module_inst->e->mem_lock) != 0) { - set_error_buf(error_buf, error_buf_size, - "create shared memory lock failed"); - goto fail; - } - module_inst->e->mem_lock_inited = true; -#endif - #if WASM_ENABLE_MULTI_MODULE != 0 module_inst->e->sub_module_inst_list = &module_inst->e->sub_module_inst_list_head; @@ -2159,11 +2150,6 @@ wasm_deinstantiate(WASMModuleInstance *module_inst, bool is_sub_inst) } #endif -#if WASM_ENABLE_SHARED_MEMORY != 0 - if (module_inst->e->mem_lock_inited) - os_mutex_destroy(&module_inst->e->mem_lock); -#endif - if (module_inst->e->c_api_func_imports) wasm_runtime_free(module_inst->e->c_api_func_imports); diff --git a/core/iwasm/interpreter/wasm_runtime.h b/core/iwasm/interpreter/wasm_runtime.h index 38d2cc4b..bf231ad6 100644 --- a/core/iwasm/interpreter/wasm_runtime.h +++ b/core/iwasm/interpreter/wasm_runtime.h @@ -223,12 +223,6 @@ typedef struct WASMModuleInstanceExtra { CApiFuncImport *c_api_func_imports; RunningMode running_mode; -#if WASM_ENABLE_SHARED_MEMORY != 0 - /* lock for shared memory atomic operations */ - korp_mutex mem_lock; - bool mem_lock_inited; -#endif - #if WASM_ENABLE_MULTI_MODULE != 0 bh_list sub_module_inst_list_head; bh_list *sub_module_inst_list; @@ -240,8 +234,8 @@ typedef struct WASMModuleInstanceExtra { uint32 max_aux_stack_used; #endif -#if WASM_ENABLE_DEBUG_INTERP != 0 \ - || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT \ +#if WASM_ENABLE_DEBUG_INTERP != 0 \ + || (WASM_ENABLE_FAST_JIT != 0 && WASM_ENABLE_JIT != 0 \ && WASM_ENABLE_LAZY_JIT != 0) WASMModuleInstance *next; #endif diff --git a/samples/multi-thread/wasm-apps/CMakeLists.txt b/samples/multi-thread/wasm-apps/CMakeLists.txt index ec8f7eef..d7352e42 100644 --- a/samples/multi-thread/wasm-apps/CMakeLists.txt +++ b/samples/multi-thread/wasm-apps/CMakeLists.txt @@ -41,3 +41,6 @@ target_link_libraries(test.wasm) add_executable(main_thread_exception.wasm main_thread_exception.c) target_link_libraries(main_thread_exception.wasm) + +add_executable(main_global_atomic.wasm main_global_atomic.c) +target_link_libraries(main_global_atomic.wasm) \ No newline at end of file diff --git a/samples/multi-thread/wasm-apps/main_global_atomic.c b/samples/multi-thread/wasm-apps/main_global_atomic.c new file mode 100644 index 00000000..dafbea88 --- /dev/null +++ b/samples/multi-thread/wasm-apps/main_global_atomic.c @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2023 Amazon.com Inc. or its affiliates. All rights reserved. + * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception + */ + +#include +#include + +#define MAX_NUM_THREADS 4 +#define NUM_ITER 1000 + +int g_count = 0; + +static void * +thread(void *arg) +{ + for (int i = 0; i < NUM_ITER; i++) { + __atomic_fetch_add(&g_count, 1, __ATOMIC_SEQ_CST); + } + + return NULL; +} + +int +main(int argc, char **argv) +{ + pthread_t tids[MAX_NUM_THREADS]; + + for (int i = 0; i < MAX_NUM_THREADS; i++) { + if (pthread_create(&tids[i], NULL, thread, NULL) != 0) { + printf("Thread creation failed\n"); + } + } + + for (int i = 0; i < MAX_NUM_THREADS; i++) { + if (pthread_join(tids[i], NULL) != 0) { + printf("Thread join failed\n"); + } + } + + printf("Value of counter after update: %d (expected=%d)\n", g_count, + MAX_NUM_THREADS * NUM_ITER); + if (g_count != MAX_NUM_THREADS * NUM_ITER) { + __builtin_trap(); + } + + return -1; +} \ No newline at end of file