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:
parent
c5b7b9d8df
commit
0c4402293d
@ -72,6 +72,7 @@ typedef struct os_thread_wait_node *os_thread_wait_list;
|
|||||||
typedef struct korp_cond {
|
typedef struct korp_cond {
|
||||||
korp_mutex wait_list_lock;
|
korp_mutex wait_list_lock;
|
||||||
os_thread_wait_list thread_wait_list;
|
os_thread_wait_list thread_wait_list;
|
||||||
|
struct os_thread_wait_node *thread_wait_list_end;
|
||||||
} korp_cond;
|
} korp_cond;
|
||||||
|
|
||||||
#define bh_socket_t SOCKET
|
#define bh_socket_t SOCKET
|
||||||
|
@ -37,6 +37,8 @@ typedef struct os_thread_data {
|
|||||||
korp_mutex wait_lock;
|
korp_mutex wait_lock;
|
||||||
/* Waiting list of other threads who are joining this thread */
|
/* Waiting list of other threads who are joining this thread */
|
||||||
os_thread_wait_list thread_wait_list;
|
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 */
|
/* Whether the thread has exited */
|
||||||
bool thread_exited;
|
bool thread_exited;
|
||||||
/* Thread return value */
|
/* Thread return value */
|
||||||
@ -174,7 +176,8 @@ os_thread_cleanup(void *retval)
|
|||||||
os_sem_signal(&head->sem);
|
os_sem_signal(&head->sem);
|
||||||
head = next;
|
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 */
|
/* Set thread status and thread return value */
|
||||||
thread_data->thread_exited = true;
|
thread_data->thread_exited = true;
|
||||||
@ -313,14 +316,14 @@ os_thread_join(korp_tid thread, void **p_retval)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Thread is running */
|
/* Thread is running */
|
||||||
if (!thread_data->thread_wait_list)
|
if (!thread_data->thread_wait_list) { /* Waiting list is empty */
|
||||||
thread_data->thread_wait_list = &curr_thread_data->wait_node;
|
thread_data->thread_wait_list = thread_data->thread_wait_list_end =
|
||||||
else {
|
&curr_thread_data->wait_node;
|
||||||
|
}
|
||||||
|
else { /* Waiting list isn't empty */
|
||||||
/* Add to end of waiting list */
|
/* Add to end of waiting list */
|
||||||
os_thread_wait_node *p = thread_data->thread_wait_list;
|
thread_data->thread_wait_list_end->next = &curr_thread_data->wait_node;
|
||||||
while (p->next)
|
thread_data->thread_wait_list_end = &curr_thread_data->wait_node;
|
||||||
p = p->next;
|
|
||||||
p->next = &curr_thread_data->wait_node;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
os_mutex_unlock(&thread_data->wait_lock);
|
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)
|
if (os_mutex_init(&cond->wait_list_lock) != BHT_OK)
|
||||||
return BHT_ERROR;
|
return BHT_ERROR;
|
||||||
|
|
||||||
cond->thread_wait_list = NULL;
|
cond->thread_wait_list = cond->thread_wait_list_end = NULL;
|
||||||
return BHT_OK;
|
return BHT_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -568,14 +571,13 @@ os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, bool timed,
|
|||||||
bh_assert(cond);
|
bh_assert(cond);
|
||||||
bh_assert(mutex);
|
bh_assert(mutex);
|
||||||
os_mutex_lock(&cond->wait_list_lock);
|
os_mutex_lock(&cond->wait_list_lock);
|
||||||
if (!cond->thread_wait_list)
|
if (!cond->thread_wait_list) { /* Waiting list is empty */
|
||||||
cond->thread_wait_list = node;
|
cond->thread_wait_list = cond->thread_wait_list_end = node;
|
||||||
else {
|
}
|
||||||
|
else { /* Waiting list isn't empty */
|
||||||
/* Add to end of wait list */
|
/* Add to end of wait list */
|
||||||
os_thread_wait_node *p = cond->thread_wait_list;
|
cond->thread_wait_list_end->next = node;
|
||||||
while (p->next)
|
cond->thread_wait_list_end = node;
|
||||||
p = p->next;
|
|
||||||
p->next = node;
|
|
||||||
}
|
}
|
||||||
os_mutex_unlock(&cond->wait_list_lock);
|
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 */
|
/* Remove wait node from wait list */
|
||||||
os_mutex_lock(&cond->wait_list_lock);
|
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;
|
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 {
|
else {
|
||||||
/* Remove from the wait list */
|
/* Remove from the wait list */
|
||||||
os_thread_wait_node *p = cond->thread_wait_list;
|
os_thread_wait_node *p = cond->thread_wait_list;
|
||||||
while (p->next != node)
|
while (p->next != node)
|
||||||
p = p->next;
|
p = p->next;
|
||||||
p->next = node->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);
|
os_mutex_unlock(&cond->wait_list_lock);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user