Fix atomic wait not thread safe issue (#1146)

Add lock for acquire_wait_info and release_wait_info, and
remove release_wait_info in wasm_runtime_atomic_notify.
This commit is contained in:
Xu Jun 2022-05-06 12:52:17 +08:00 committed by GitHub
parent 07829b90d7
commit 16cfd4764d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -224,17 +224,22 @@ acquire_wait_info(void *address, bool create)
AtomicWaitInfo *wait_info = NULL;
bh_list_status ret;
os_mutex_lock(&shared_memory_list_lock);
if (address)
wait_info = (AtomicWaitInfo *)bh_hash_map_find(wait_map, address);
if (!create)
if (!create) {
os_mutex_unlock(&shared_memory_list_lock);
return wait_info;
}
/* No wait info on this address, create new info */
if (!wait_info) {
if (!(wait_info = (AtomicWaitInfo *)wasm_runtime_malloc(
sizeof(AtomicWaitInfo))))
return NULL;
sizeof(AtomicWaitInfo)))) {
goto fail1;
}
memset(wait_info, 0, sizeof(AtomicWaitInfo));
/* init wait list */
@ -244,20 +249,30 @@ acquire_wait_info(void *address, bool create)
/* init wait list lock */
if (0 != os_mutex_init(&wait_info->wait_list_lock)) {
wasm_runtime_free(wait_info);
return NULL;
goto fail2;
}
if (!bh_hash_map_insert(wait_map, address, (void *)wait_info)) {
os_mutex_destroy(&wait_info->wait_list_lock);
wasm_runtime_free(wait_info);
return NULL;
goto fail3;
}
}
os_mutex_unlock(&shared_memory_list_lock);
bh_assert(wait_info);
(void)ret;
return wait_info;
fail3:
os_mutex_destroy(&wait_info->wait_list_lock);
fail2:
wasm_runtime_free(wait_info);
fail1:
os_mutex_unlock(&shared_memory_list_lock);
return NULL;
}
static void
@ -285,10 +300,14 @@ destroy_wait_info(void *wait_info)
static void
release_wait_info(HashMap *wait_map_, AtomicWaitInfo *wait_info, void *address)
{
os_mutex_lock(&shared_memory_list_lock);
if (wait_info->wait_list->len == 0) {
bh_hash_map_remove(wait_map_, address, NULL, NULL);
destroy_wait_info(wait_info);
}
os_mutex_unlock(&shared_memory_list_lock);
}
uint32
@ -405,8 +424,9 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
uint32 notify_result;
AtomicWaitInfo *wait_info;
/* Nobody wait on this address */
wait_info = acquire_wait_info(address, false);
/* Nobody wait on this address */
if (!wait_info)
return 0;
@ -414,7 +434,5 @@ wasm_runtime_atomic_notify(WASMModuleInstanceCommon *module, void *address,
notify_result = notify_wait_list(wait_info->wait_list, count);
os_mutex_unlock(&wait_info->wait_list_lock);
release_wait_info(wait_map, wait_info, address);
return notify_result;
}