diff --git a/core/shared/platform/windows/platform_internal.h b/core/shared/platform/windows/platform_internal.h index 1bce192e..1332afc2 100644 --- a/core/shared/platform/windows/platform_internal.h +++ b/core/shared/platform/windows/platform_internal.h @@ -72,6 +72,7 @@ typedef struct os_thread_wait_node *os_thread_wait_list; typedef struct korp_cond { korp_mutex wait_list_lock; os_thread_wait_list thread_wait_list; + struct os_thread_wait_node *thread_wait_list_end; } korp_cond; #define bh_socket_t SOCKET diff --git a/core/shared/platform/windows/win_thread.c b/core/shared/platform/windows/win_thread.c index a67b15e6..09cf0c63 100644 --- a/core/shared/platform/windows/win_thread.c +++ b/core/shared/platform/windows/win_thread.c @@ -37,6 +37,8 @@ typedef struct os_thread_data { korp_mutex wait_lock; /* Waiting list of other threads who are joining this thread */ os_thread_wait_list thread_wait_list; + /* End node of the waiting list */ + os_thread_wait_node *thread_wait_list_end; /* Whether the thread has exited */ bool thread_exited; /* Thread return value */ @@ -174,7 +176,8 @@ os_thread_cleanup(void *retval) os_sem_signal(&head->sem); head = next; } - thread_data->thread_wait_list = NULL; + thread_data->thread_wait_list = thread_data->thread_wait_list_end = + NULL; } /* Set thread status and thread return value */ thread_data->thread_exited = true; @@ -313,14 +316,14 @@ os_thread_join(korp_tid thread, void **p_retval) } /* Thread is running */ - if (!thread_data->thread_wait_list) - thread_data->thread_wait_list = &curr_thread_data->wait_node; - else { + if (!thread_data->thread_wait_list) { /* Waiting list is empty */ + thread_data->thread_wait_list = thread_data->thread_wait_list_end = + &curr_thread_data->wait_node; + } + else { /* Waiting list isn't empty */ /* Add to end of waiting list */ - os_thread_wait_node *p = thread_data->thread_wait_list; - while (p->next) - p = p->next; - p->next = &curr_thread_data->wait_node; + thread_data->thread_wait_list_end->next = &curr_thread_data->wait_node; + thread_data->thread_wait_list_end = &curr_thread_data->wait_node; } os_mutex_unlock(&thread_data->wait_lock); @@ -545,7 +548,7 @@ os_cond_init(korp_cond *cond) if (os_mutex_init(&cond->wait_list_lock) != BHT_OK) return BHT_ERROR; - cond->thread_wait_list = NULL; + cond->thread_wait_list = cond->thread_wait_list_end = NULL; return BHT_OK; } @@ -568,14 +571,13 @@ os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, bool timed, bh_assert(cond); bh_assert(mutex); os_mutex_lock(&cond->wait_list_lock); - if (!cond->thread_wait_list) - cond->thread_wait_list = node; - else { + if (!cond->thread_wait_list) { /* Waiting list is empty */ + cond->thread_wait_list = cond->thread_wait_list_end = node; + } + else { /* Waiting list isn't empty */ /* Add to end of wait list */ - os_thread_wait_node *p = cond->thread_wait_list; - while (p->next) - p = p->next; - p->next = node; + cond->thread_wait_list_end->next = node; + cond->thread_wait_list_end = node; } os_mutex_unlock(&cond->wait_list_lock); @@ -590,14 +592,24 @@ os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, bool timed, /* Remove wait node from wait list */ os_mutex_lock(&cond->wait_list_lock); - if (cond->thread_wait_list == node) + if (cond->thread_wait_list == node) { cond->thread_wait_list = node->next; + + if (cond->thread_wait_list_end == node) { + bh_assert(node->next == NULL); + cond->thread_wait_list_end = NULL; + } + } else { /* Remove from the wait list */ os_thread_wait_node *p = cond->thread_wait_list; while (p->next != node) p = p->next; p->next = node->next; + + if (cond->thread_wait_list_end == node) { + cond->thread_wait_list_end = p; + } } os_mutex_unlock(&cond->wait_list_lock);