mmdevapi: Avoid lock contention after SetEvent.

Joerg-Cyril.Hoehle at Joerg-Cyril.Hoehle at
Fri Dec 21 04:30:29 CST 2012

Andrew Eikum asked:
>Is it true that SetEvent() causes a context switch?

Looking at +tid log files, I've seen switches happen after SetEvent
often enough.  That motivated some changes to winmm notification in
the last years, i.e. call SetEvent after all local work is finished
and objects are in a sane state again.

Moreover, the semantics of SetEvent is that it puts any thread waiting
for the event into runnable state.  If it's runnable, the OS may as
well decide to run it.  And that's exactly what happens.

On a multi-core system, the signaled thread may start running
immediately on another core.  You don't want it to stop shortly later,
blocking on wineXYZ*.drv's sole critical section when invoking mmdevapi.

LeaveCriticalSection is another place where context switches happen,
both according to log files and by design (see RtlUnWaitCriticalSection).
So could moving SetEvent after LeaveCS disturb the dynamic behaviour
of winealsa.drv?  I argue that there's no harm, because mmdevapi's
design is such that the app has nearly one period time after receiving
the event to supply new samples.  Thus if an app manages to sneak in
a call unblocked by LeaveCS, e.g. GetPosition, before SetEvent, there
should still be enough time left afterwards.

In any case, lock contention by an app calling GetPosition during the
period callback is presumably rare, while lock contention by SetEvent
vs. GetCurrentPadding in the signaled thread, e.g. DSound is
systematic.  So let's avoid it.

(Please don't skip that patch waiting for the lock-less one which will
render it superfluous...).

	Jörg Höhle

More information about the wine-devel mailing list