msvcrt: Optimize Concurrency::event implementation.

Signed-off-by: Piotr Caban <piotr@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
oldstable
Piotr Caban 2017-03-20 10:42:38 +01:00 committed by Alexandre Julliard
parent eba6bf44b3
commit 41dd0eb457
1 changed files with 28 additions and 32 deletions

View File

@ -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) static void evt_add_queue(thread_wait_entry **head, thread_wait_entry *entry)
{ {
if(*head) { entry->next = *head;
entry->next = *head; entry->prev = NULL;
entry->prev = (*head)->prev; if(*head) (*head)->prev = entry;
(*head)->prev->next = entry; *head = entry;
(*head)->prev = entry;
} else {
entry->next = entry;
entry->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; if(entry == *head)
entry->prev->next = entry->next; *head = entry->next;
if(*head == entry) else if(entry->prev)
*head = entry->next == entry ? NULL : entry->next; 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) 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++) { for(i = 0; i < count; i++) {
critical_section_lock(&events[i]->cs); critical_section_lock(&events[i]->cs);
if(events[i] == wait->signaled) ret = i; 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); critical_section_unlock(&events[i]->cs);
} }
@ -698,13 +693,8 @@ void __thiscall event_reset(event *this)
critical_section_lock(&this->cs); critical_section_lock(&this->cs);
if(this->signaled) { if(this->signaled) {
this->signaled = FALSE; this->signaled = FALSE;
if(this->waiters) { for(entry=this->waiters; entry; entry = entry->next)
entry = this->waiters; InterlockedIncrement(&entry->wait->pending_waits);
do {
InterlockedIncrement(&entry->wait->pending_waits);
entry = entry->next;
} while (entry != this->waiters);
}
} }
critical_section_unlock(&this->cs); critical_section_unlock(&this->cs);
} }
@ -714,25 +704,31 @@ void __thiscall event_reset(event *this)
DEFINE_THISCALL_WRAPPER(event_set, 4) DEFINE_THISCALL_WRAPPER(event_set, 4)
void __thiscall event_set(event *this) void __thiscall event_set(event *this)
{ {
thread_wait_entry *entry; thread_wait_entry *wakeup = NULL;
thread_wait_entry *entry, *next;
TRACE("(%p)\n", this); TRACE("(%p)\n", this);
critical_section_lock(&this->cs); critical_section_lock(&this->cs);
if(!this->signaled) { if(!this->signaled) {
this->signaled = TRUE; this->signaled = TRUE;
if(this->waiters) { for(entry=this->waiters; entry; entry=next) {
entry = this->waiters; next = entry->next;
do { if(!InterlockedDecrement(&entry->wait->pending_waits)) {
if(!InterlockedDecrement(&entry->wait->pending_waits)) { if(InterlockedExchangePointer(&entry->wait->signaled, this) == EVT_WAITING) {
if(InterlockedExchangePointer(&entry->wait->signaled, this) == EVT_WAITING) evt_remove_queue(&this->waiters, entry);
NtReleaseKeyedEvent(keyed_event, entry->wait, 0, NULL); evt_add_queue(&wakeup, entry);
} }
entry = entry->next; }
} while (entry != this->waiters);
} }
} }
critical_section_unlock(&this->cs); 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@event@Concurrency@@QAEII@Z */ /* ?wait@event@Concurrency@@QAEII@Z */