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@xxxxxxx> --- 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 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html