[RFT PATCH 2/2] win32: optimize pthread_cond_broadcast
- From
Paolo Bonzini <bonzini@gnu.org>
- Date
- Jun 7, 2010, 13:38 UTC
- Message-ID
- <1275917892-16437-3-git-send-email-bonzini@gnu.org>
- In-Reply-To
- <1275917892-16437-1-git-send-email-bonzini@gnu.org>
If there is a single waiting thread, pthread_cond_signal is the same as pthread_cond_broadcast and no extra synchronization is necessary.
Signed-off-by: Paolo Bonzini <bonzini@gnu.org> --- compat/win32/pthread.c | 19 ++++++++++--------- 1 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c index 1a38981..d46a51c 100644 --- a/compat/win32/pthread.c +++ b/compat/win32/pthread.c @@ -172,9 +172,10 @@ int pthread_cond_broadcast(pthread_cond_t *cond) * As in pthread_cond_signal, access to cond->waiters and * cond->was_broadcast is locked via the external mutex. */ - - if ((cond->was_broadcast = cond->waiters > 0)) { + if (cond->waiters > 0) { BOOLEAN result; + cond->was_broadcast = cond->waiters > 1; + /* wake up all waiters */ result = ReleaseSemaphore(cond->sema, cond->waiters, NULL); if (!result) @@ -187,14 +188,14 @@ int pthread_cond_broadcast(pthread_cond_t *cond) * yet. For this reason, we can be sure that no thread gets * a chance to eat *more* than one slice. OTOH, it means * that the last waiter must send us a wake-up. + * + * As an optimization, when there was exactly one waiter + * broadcast is the same as signal and we can skip this step. */ - WaitForSingleObject(cond->continue_broadcast, INFINITE); - /* - * Since the external mutex is held, no thread can enter - * cond_wait, and, hence, it is safe to reset this flag - * without cond->waiters_lock held. - */ - cond->was_broadcast = 0; + if (cond->was_broadcast) { + WaitForSingleObject(cond->continue_broadcast, INFINITE); + cond->was_broadcast = 0; + } } return 0; }
-- 1.7.0.1