Improvements for platform thread APIs on Windows and Zephyr (#3941)

* improvements for os_thread_join on Windows and Zephyr
This commit is contained in:
TianlongLiang 2024-12-06 14:39:53 +08:00 committed by GitHub
parent 739efd78e9
commit aabe83074e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 78 additions and 11 deletions

View File

@ -60,6 +60,63 @@ static DWORD thread_data_key;
static void(WINAPI *GetCurrentThreadStackLimits_Kernel32)(PULONG_PTR, static void(WINAPI *GetCurrentThreadStackLimits_Kernel32)(PULONG_PTR,
PULONG_PTR) = NULL; 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 int
os_sem_init(korp_sem *sem); os_sem_init(korp_sem *sem);
int 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 */ /* Add thread data into thread data list */
os_mutex_lock(&thread_data_list_lock); thread_data_list_add(thread_data);
thread_data->next = supervisor_thread_data.next;
supervisor_thread_data.next = thread_data;
os_mutex_unlock(&thread_data_list_lock);
/* Wait for the thread routine to set thread_data's tid /* Wait for the thread routine to set thread_data's tid
and add thread_data to thread data list */ 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; curr_thread_data->wait_node.next = NULL;
/* Get thread data of thread to join */ /* Get thread data of thread to join */
thread_data = (os_thread_data *)thread; thread_data = thread_data_list_lookup(thread);
bh_assert(thread_data);
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); os_mutex_lock(&thread_data->wait_lock);
@ -312,6 +370,7 @@ os_thread_join(korp_tid thread, void **p_retval)
if (p_retval) if (p_retval)
*p_retval = thread_data->thread_retval; *p_retval = thread_data->thread_retval;
os_mutex_unlock(&thread_data->wait_lock); os_mutex_unlock(&thread_data->wait_lock);
thread_data_list_remove(thread_data);
return BHT_OK; 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); os_sem_wait(&curr_thread_data->wait_node.sem);
if (p_retval) if (p_retval)
*p_retval = curr_thread_data->wait_node.retval; *p_retval = curr_thread_data->wait_node.retval;
thread_data_list_remove(thread_data);
return BHT_OK; return BHT_OK;
} }

View File

@ -393,6 +393,16 @@ os_thread_join(korp_tid thread, void **value_ptr)
os_thread_data *thread_data; os_thread_data *thread_data;
os_thread_wait_node *node; 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 */ /* Create wait node and append it to wait list */
if (!(node = BH_MALLOC(sizeof(os_thread_wait_node)))) if (!(node = BH_MALLOC(sizeof(os_thread_wait_node))))
return BHT_ERROR; return BHT_ERROR;
@ -400,10 +410,6 @@ os_thread_join(korp_tid thread, void **value_ptr)
sem_init(&node->sem, 0, 1); sem_init(&node->sem, 0, 1);
node->next = NULL; 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); mutex_lock(&thread_data->wait_list_lock, K_FOREVER);
if (!thread_data->thread_wait_list) if (!thread_data->thread_wait_list)
thread_data->thread_wait_list = node; thread_data->thread_wait_list = node;

View File

@ -114,7 +114,8 @@ typedef uint16 bh_atomic_16_t;
#endif #endif
/* On some 32-bit platform, disable 64-bit atomic operations, otherwise /* 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 #ifndef WASM_UINT64_IS_ATOMIC
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) \
&& !defined(__OpenBSD__) && (defined(__riscv) || defined(__arm__)) \ && !defined(__OpenBSD__) && (defined(__riscv) || defined(__arm__)) \