diff --git a/core/shared/platform/windows/win_thread.c b/core/shared/platform/windows/win_thread.c index f37250fa4..438e16040 100644 --- a/core/shared/platform/windows/win_thread.c +++ b/core/shared/platform/windows/win_thread.c @@ -60,6 +60,63 @@ static DWORD thread_data_key; static void(WINAPI *GetCurrentThreadStackLimits_Kernel32)(PULONG_PTR, PULONG_PTR) = NULL; +static void +thread_data_list_add(os_thread_data *thread_data) +{ + os_mutex_lock(&thread_data_list_lock); + /* If already in list, just return */ + os_thread_data *p = &supervisor_thread_data; + while (p) { + if (p == thread_data) { + os_mutex_unlock(&thread_data_list_lock); + return; + } + p = p->next; + } + thread_data->next = supervisor_thread_data.next; + supervisor_thread_data.next = thread_data; + os_mutex_unlock(&thread_data_list_lock); +} + +static void +thread_data_list_remove(os_thread_data *thread_data) +{ + os_mutex_lock(&thread_data_list_lock); + /* Search and remove it from list */ + os_thread_data *p = &supervisor_thread_data; + while (p && p->next != thread_data) + p = p->next; + + if (p && p->next) { + bh_assert(p->next == thread_data); + p->next = p->next->next; + /* Release the resources in thread_data */ + os_cond_destroy(&thread_data->wait_cond); + os_mutex_destroy(&thread_data->wait_lock); + os_sem_destroy(&thread_data->wait_node.sem); + BH_FREE(thread_data); + } + os_mutex_unlock(&thread_data_list_lock); +} + +static os_thread_data * +thread_data_list_lookup(korp_tid tid) +{ + os_thread_data *thread_data = (os_thread_data *)tid; + os_mutex_lock(&thread_data_list_lock); + os_thread_data *p = supervisor_thread_data.next; + while (p) { + if (p == thread_data) { + /* Found */ + os_mutex_unlock(&thread_data_list_lock); + return p; + } + p = p->next; + } + os_mutex_unlock(&thread_data_list_lock); + return NULL; +} + int os_sem_init(korp_sem *sem); int @@ -254,10 +311,7 @@ os_thread_create_with_prio(korp_tid *p_tid, thread_start_routine_t start, } /* Add thread data into thread data list */ - os_mutex_lock(&thread_data_list_lock); - thread_data->next = supervisor_thread_data.next; - supervisor_thread_data.next = thread_data; - os_mutex_unlock(&thread_data_list_lock); + thread_data_list_add(thread_data); /* Wait for the thread routine to set thread_data's tid and add thread_data to thread data list */ @@ -302,8 +356,12 @@ os_thread_join(korp_tid thread, void **p_retval) curr_thread_data->wait_node.next = NULL; /* Get thread data of thread to join */ - thread_data = (os_thread_data *)thread; - bh_assert(thread_data); + thread_data = thread_data_list_lookup(thread); + + if (thread_data == NULL) { + os_printf("Can't join thread %p, it does not exist", thread); + return BHT_ERROR; + } os_mutex_lock(&thread_data->wait_lock); @@ -312,6 +370,7 @@ os_thread_join(korp_tid thread, void **p_retval) if (p_retval) *p_retval = thread_data->thread_retval; os_mutex_unlock(&thread_data->wait_lock); + thread_data_list_remove(thread_data); return BHT_OK; } @@ -332,6 +391,7 @@ os_thread_join(korp_tid thread, void **p_retval) os_sem_wait(&curr_thread_data->wait_node.sem); if (p_retval) *p_retval = curr_thread_data->wait_node.retval; + thread_data_list_remove(thread_data); return BHT_OK; } diff --git a/core/shared/platform/zephyr/zephyr_thread.c b/core/shared/platform/zephyr/zephyr_thread.c index 628a842d6..31aaad7a9 100644 --- a/core/shared/platform/zephyr/zephyr_thread.c +++ b/core/shared/platform/zephyr/zephyr_thread.c @@ -393,6 +393,16 @@ os_thread_join(korp_tid thread, void **value_ptr) os_thread_data *thread_data; os_thread_wait_node *node; + /* Get thread data */ + thread_data = thread_data_list_lookup(thread); + + if (thread_data == NULL) { + os_printf( + "Can't join thread %p, probably already exited or does not exist", + thread); + return BHT_OK; + } + /* Create wait node and append it to wait list */ if (!(node = BH_MALLOC(sizeof(os_thread_wait_node)))) return BHT_ERROR; @@ -400,10 +410,6 @@ os_thread_join(korp_tid thread, void **value_ptr) sem_init(&node->sem, 0, 1); node->next = NULL; - /* Get thread data */ - thread_data = thread_data_list_lookup(thread); - bh_assert(thread_data != NULL); - mutex_lock(&thread_data->wait_list_lock, K_FOREVER); if (!thread_data->thread_wait_list) thread_data->thread_wait_list = node; diff --git a/core/shared/utils/bh_atomic.h b/core/shared/utils/bh_atomic.h index 5148497f8..57cb4d1c9 100644 --- a/core/shared/utils/bh_atomic.h +++ b/core/shared/utils/bh_atomic.h @@ -114,7 +114,8 @@ typedef uint16 bh_atomic_16_t; #endif /* On some 32-bit platform, disable 64-bit atomic operations, otherwise - * undefined reference to `__atomic_load_8' */ + * undefined reference to `__atomic_load_8', if on Zephyr, can add board related + * macro in autoconf.h to control */ #ifndef WASM_UINT64_IS_ATOMIC #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \ && !defined(__OpenBSD__) && (defined(__riscv) || defined(__arm__)) \