Skip to content

Commit

Permalink
Skip mutex for a 0ms wait on single manual reset event
Browse files Browse the repository at this point in the history
This requires a memory barrier to ensure correctness (avoiding false
positive caused by stale read) but should still be cheaper than a
syscall and only happens if we expect it to be available (based off the
initial relaxed read).

See #18
  • Loading branch information
mqudsi committed Jul 11, 2021
1 parent 9c22e4e commit 8db9ebf
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions src/pevents.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,22 @@ namespace neosmart {
// value here, and preferable to synchronizing CPU caches to get a more accurate result.
if (milliseconds == 0 && !event->State.load(std::memory_order_relaxed)) {
return WAIT_TIMEOUT;
} else {
int result = pthread_mutex_lock(&event->Mutex);
assert(result == 0);
}
// Optimization: early return in case of success for manual reset events only.
if (!event->AutoReset && event->State.load(std::memory_order_relaxed)) {
// A memory barrier is required here. This is still cheaper than a syscall.
// See https://github.com/neosmart/pevents/issues/18
if (event->State.load(std::memory_order_acquire)) {
return 0;
}
}

int tempResult = pthread_mutex_lock(&event->Mutex);
assert(tempResult == 0);

int result = UnlockedWaitForEvent(event, milliseconds);

int tempResult = pthread_mutex_unlock(&event->Mutex);
tempResult = pthread_mutex_unlock(&event->Mutex);
assert(tempResult == 0);

return result;
Expand Down

0 comments on commit 8db9ebf

Please sign in to comment.