Refine Windows thread waiting list operations (#1853)

Add thread_wait_list_end node for thread data and cond for Windows platform
to speedup the thread join and cond wait operations: no need to traverse the
wait list to get the end node to append the wait node.
This commit is contained in:
Wenyong Huang 2023-01-06 14:51:07 +08:00 committed by GitHub
parent c5b7b9d8df
commit 0c4402293d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 30 additions and 17 deletions

View File

@ -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

View File

@ -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);