Piotr Caban : msvcrt: Optimize Concurrency::event implementation.

Alexandre Julliard julliard at winehq.org
Mon Mar 20 17:16:46 CDT 2017


Module: wine
Branch: master
Commit: 41dd0eb457c26ff956c247bcc8493dd4ad0fb34b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=41dd0eb457c26ff956c247bcc8493dd4ad0fb34b

Author: Piotr Caban <piotr at codeweavers.com>
Date:   Mon Mar 20 10:42:38 2017 +0100

msvcrt: Optimize Concurrency::event implementation.

Signed-off-by: Piotr Caban <piotr at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/msvcrt/lock.c | 60 +++++++++++++++++++++++++-----------------------------
 1 file changed, 28 insertions(+), 32 deletions(-)

diff --git a/dlls/msvcrt/lock.c b/dlls/msvcrt/lock.c
index 8ae9511..edfefdb 100644
--- a/dlls/msvcrt/lock.c
+++ b/dlls/msvcrt/lock.c
@@ -584,24 +584,19 @@ static inline PLARGE_INTEGER evt_timeout(PLARGE_INTEGER pTime, unsigned int time
 
 static void evt_add_queue(thread_wait_entry **head, thread_wait_entry *entry)
 {
-    if(*head) {
-        entry->next = *head;
-        entry->prev = (*head)->prev;
-        (*head)->prev->next = entry;
-        (*head)->prev = entry;
-    } else {
-        entry->next = entry;
-        entry->prev = entry;
-        *head = entry;
-    }
+    entry->next = *head;
+    entry->prev = NULL;
+    if(*head) (*head)->prev = entry;
+    *head = entry;
 }
 
-static void evt_remove(thread_wait_entry **head, thread_wait_entry *entry)
+static void evt_remove_queue(thread_wait_entry **head, thread_wait_entry *entry)
 {
-    entry->next->prev = entry->prev;
-    entry->prev->next = entry->next;
-    if(*head == entry)
-        *head = entry->next == entry ? NULL : entry->next;
+    if(entry == *head)
+        *head = entry->next;
+    else if(entry->prev)
+        entry->prev->next = entry->next;
+    if(entry->next) entry->next->prev = entry->prev;
 }
 
 static MSVCRT_size_t evt_end_wait(thread_wait *wait, event **events, int count)
@@ -611,7 +606,7 @@ static MSVCRT_size_t evt_end_wait(thread_wait *wait, event **events, int count)
     for(i = 0; i < count; i++) {
         critical_section_lock(&events[i]->cs);
         if(events[i] == wait->signaled) ret = i;
-        evt_remove(&events[i]->waiters, &wait->entries[i]);
+        evt_remove_queue(&events[i]->waiters, &wait->entries[i]);
         critical_section_unlock(&events[i]->cs);
     }
 
@@ -698,13 +693,8 @@ void __thiscall event_reset(event *this)
     critical_section_lock(&this->cs);
     if(this->signaled) {
         this->signaled = FALSE;
-        if(this->waiters) {
-            entry = this->waiters;
-            do {
-                InterlockedIncrement(&entry->wait->pending_waits);
-                entry = entry->next;
-            } while (entry != this->waiters);
-        }
+        for(entry=this->waiters; entry; entry = entry->next)
+            InterlockedIncrement(&entry->wait->pending_waits);
     }
     critical_section_unlock(&this->cs);
 }
@@ -714,25 +704,31 @@ void __thiscall event_reset(event *this)
 DEFINE_THISCALL_WRAPPER(event_set, 4)
 void __thiscall event_set(event *this)
 {
-    thread_wait_entry *entry;
+    thread_wait_entry *wakeup = NULL;
+    thread_wait_entry *entry, *next;
 
     TRACE("(%p)\n", this);
 
     critical_section_lock(&this->cs);
     if(!this->signaled) {
         this->signaled = TRUE;
-        if(this->waiters) {
-            entry = this->waiters;
-            do {
-                if(!InterlockedDecrement(&entry->wait->pending_waits)) {
-                    if(InterlockedExchangePointer(&entry->wait->signaled, this) == EVT_WAITING)
-                        NtReleaseKeyedEvent(keyed_event, entry->wait, 0, NULL);
+        for(entry=this->waiters; entry; entry=next) {
+            next = entry->next;
+            if(!InterlockedDecrement(&entry->wait->pending_waits)) {
+                if(InterlockedExchangePointer(&entry->wait->signaled, this) == EVT_WAITING) {
+                    evt_remove_queue(&this->waiters, entry);
+                    evt_add_queue(&wakeup, entry);
                 }
-                entry = entry->next;
-            } while (entry != this->waiters);
+            }
         }
     }
     critical_section_unlock(&this->cs);
+
+    for(entry=wakeup; entry; entry=next) {
+        next = entry->next;
+        entry->next = entry->prev = NULL;
+        NtReleaseKeyedEvent(keyed_event, entry->wait, 0, NULL);
+    }
 }
 
 /* ?wait at event@Concurrency@@QAEII at Z */




More information about the wine-cvs mailing list