Răsfoiți Sursa

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.
Wenyong Huang 3 ani în urmă
părinte
comite
0c4402293d

+ 1 - 0
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

+ 29 - 17
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);