Skip to content

Commit

Permalink
Try bypassing manual reset event locks in WaitForMultipleEvents
Browse files Browse the repository at this point in the history
Extending 8db9ebf, try to bypass
obtaining the mutex for manual reset events even in calls to
`WaitForMultipleEvents()`. See #18.
  • Loading branch information
mqudsi committed Jul 11, 2021
1 parent 8db9ebf commit 1209b1f
Showing 1 changed file with 27 additions and 13 deletions.
40 changes: 27 additions & 13 deletions src/pevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,21 +220,35 @@ namespace neosmart {
for (int i = 0; i < count; ++i) {
waitInfo.WaitIndex = i;

// Must not release lock until RegisteredWait is potentially added
tempResult = pthread_mutex_lock(&events[i]->Mutex);
assert(tempResult == 0);

// Before adding this wait to the list of registered waits, let's clean up old, expired
// waits while we have the event lock anyway
events[i]->RegisteredWaits.erase(std::remove_if(events[i]->RegisteredWaits.begin(),
events[i]->RegisteredWaits.end(),
RemoveExpiredWaitHelper),
events[i]->RegisteredWaits.end());

if (UnlockedWaitForEvent(events[i], 0) == 0) {
tempResult = pthread_mutex_unlock(&events[i]->Mutex);
// Skip obtaining the mutex for manual reset events. This requires a memory barrier to
// ensure correctness.
bool skipLock = false;
if (!events[i]->AutoReset) {
if (events[i]->State.load(std::memory_order_relaxed) &&
events[i]->State.load(std::memory_order_acquire)) {
skipLock = true;
}
}

if (!skipLock) {
// Must not release lock until RegisteredWait is potentially added
tempResult = pthread_mutex_lock(&events[i]->Mutex);
assert(tempResult == 0);

// Before adding this wait to the list of registered waits, let's clean up old,
// expired waits while we have the event lock anyway.
events[i]->RegisteredWaits.erase(std::remove_if(events[i]->RegisteredWaits.begin(),
events[i]->RegisteredWaits.end(),
RemoveExpiredWaitHelper),
events[i]->RegisteredWaits.end());
}

if (skipLock || UnlockedWaitForEvent(events[i], 0) == 0) {
if (!skipLock) {
tempResult = pthread_mutex_unlock(&events[i]->Mutex);
assert(tempResult == 0);
}

if (waitAll) {
++skipped_refs;
--wfmo->Status.EventsLeft;
Expand Down

0 comments on commit 1209b1f

Please sign in to comment.