@@ -37,6 +37,8 @@ typedef struct os_thread_data {
3737 korp_mutex wait_lock ;
3838 /* Waiting list of other threads who are joining this thread */
3939 os_thread_wait_list thread_wait_list ;
40+ /* End node of the waiting list */
41+ os_thread_wait_node * thread_wait_list_end ;
4042 /* Whether the thread has exited */
4143 bool thread_exited ;
4244 /* Thread return value */
@@ -174,7 +176,8 @@ os_thread_cleanup(void *retval)
174176 os_sem_signal (& head -> sem );
175177 head = next ;
176178 }
177- thread_data -> thread_wait_list = NULL ;
179+ thread_data -> thread_wait_list = thread_data -> thread_wait_list_end =
180+ NULL ;
178181 }
179182 /* Set thread status and thread return value */
180183 thread_data -> thread_exited = true;
@@ -313,14 +316,14 @@ os_thread_join(korp_tid thread, void **p_retval)
313316 }
314317
315318 /* Thread is running */
316- if (!thread_data -> thread_wait_list )
317- thread_data -> thread_wait_list = & curr_thread_data -> wait_node ;
318- else {
319+ if (!thread_data -> thread_wait_list ) { /* Waiting list is empty */
320+ thread_data -> thread_wait_list = thread_data -> thread_wait_list_end =
321+ & curr_thread_data -> wait_node ;
322+ }
323+ else { /* Waiting list isn't empty */
319324 /* Add to end of waiting list */
320- os_thread_wait_node * p = thread_data -> thread_wait_list ;
321- while (p -> next )
322- p = p -> next ;
323- p -> next = & curr_thread_data -> wait_node ;
325+ thread_data -> thread_wait_list_end -> next = & curr_thread_data -> wait_node ;
326+ thread_data -> thread_wait_list_end = & curr_thread_data -> wait_node ;
324327 }
325328
326329 os_mutex_unlock (& thread_data -> wait_lock );
@@ -545,7 +548,7 @@ os_cond_init(korp_cond *cond)
545548 if (os_mutex_init (& cond -> wait_list_lock ) != BHT_OK )
546549 return BHT_ERROR ;
547550
548- cond -> thread_wait_list = NULL ;
551+ cond -> thread_wait_list = cond -> thread_wait_list_end = NULL ;
549552 return BHT_OK ;
550553}
551554
@@ -568,14 +571,13 @@ os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, bool timed,
568571 bh_assert (cond );
569572 bh_assert (mutex );
570573 os_mutex_lock (& cond -> wait_list_lock );
571- if (!cond -> thread_wait_list )
572- cond -> thread_wait_list = node ;
573- else {
574+ if (!cond -> thread_wait_list ) { /* Waiting list is empty */
575+ cond -> thread_wait_list = cond -> thread_wait_list_end = node ;
576+ }
577+ else { /* Waiting list isn't empty */
574578 /* Add to end of wait list */
575- os_thread_wait_node * p = cond -> thread_wait_list ;
576- while (p -> next )
577- p = p -> next ;
578- p -> next = node ;
579+ cond -> thread_wait_list_end -> next = node ;
580+ cond -> thread_wait_list_end = node ;
579581 }
580582 os_mutex_unlock (& cond -> wait_list_lock );
581583
@@ -590,14 +592,24 @@ os_cond_wait_internal(korp_cond *cond, korp_mutex *mutex, bool timed,
590592
591593 /* Remove wait node from wait list */
592594 os_mutex_lock (& cond -> wait_list_lock );
593- if (cond -> thread_wait_list == node )
595+ if (cond -> thread_wait_list == node ) {
594596 cond -> thread_wait_list = node -> next ;
597+
598+ if (cond -> thread_wait_list_end == node ) {
599+ bh_assert (node -> next == NULL );
600+ cond -> thread_wait_list_end = NULL ;
601+ }
602+ }
595603 else {
596604 /* Remove from the wait list */
597605 os_thread_wait_node * p = cond -> thread_wait_list ;
598606 while (p -> next != node )
599607 p = p -> next ;
600608 p -> next = node -> next ;
609+
610+ if (cond -> thread_wait_list_end == node ) {
611+ cond -> thread_wait_list_end = p ;
612+ }
601613 }
602614 os_mutex_unlock (& cond -> wait_list_lock );
603615
0 commit comments