ntdll: Stabilize CreateTimerQueueTimer callbacks over time.

Joerg-Cyril.Hoehle at t-systems.com Joerg-Cyril.Hoehle at t-systems.com
Fri Oct 26 03:13:32 CDT 2012


Hi,

This fixes bug #30071.  It's my original patch from March.  IIRC my flaky
tests (originally part 3 of the series) hindered inclusion. You choose
whether to commit it without tests.

I've still not found a significant set of tests that simultaneously
 - proves the stabilisation in stress situations *and*
 - works reliably with testbot's vmware.
Stabilisation is perfectly demonstrated since Vista.  The problem are random
test failures in vmware systems when trying to be very strict about timing
thresholds.  I'd need several more sleepless nights.

Nevertheless, the patch is crucial for some systems.  It's a pity that
I hold it back so long.  Both winealsa and wineoss depend on the
quality of the time base.

E.g. for whatever reason, my Linux box seems unable to invoke the
callbacks on anything else than 4ms boundaries.  So far, instead of
regular 10ms intervals, winealsa triggers every 12ms.  This causes
stuttering in mmdevapi/tests/render.c:test_worst_case and by
extension, any w7 app using XA2 for audio.

With the stabilisator patch, intervals are like 12-8-12-8-12 ms and
sound is mostly continuous.

Logs from several other systems show that they are not affected and
deliver events roughly every 10ms.  Yet their +tid logs also prove
that the rate is strictly >10ms as no correction ever occurs, i.e. their
average is more like 11ms than 10ms.

In either case, that's not the audio event rate that mmdevapi expects.

[original March message:]

This is one of the most important audio-enhancement patches.
It fixes #30071, #28856, allows to close #28723 and perhaps most bug reports
about occasional or continuous crackling sound from ALSA, e.g. #28622 comment #34 or #28282.

All w7 XAudio2 clients are affected. Winmm less so, because apps tend to write more than one period
at a time. DSound benefits too, also it's not cured yet as it does not use mmdevapi period sizes,
GetCurrentPadding and GetPosition like I believe it should.

The key part is
fire next = t->expire + t->period (like winmm:time functions)
instead of
fire next = now + t->period.
to provide a stable rate (on average) over time.

Googling CreateTimerQueuerTimer, you'll find a few posting where its stability is discussed,
although there's no master's voice. There's also A. Eikum's observation:
http://www.winehq.org/pipermail/wine-devel/2012-February/094457.html

Visit testbot job #17175 and other about CreateTimerQueue
https://testbot.winehq.org/JobDetails.pl?Key=17175
and you'll see that Vista/w2k8/w7 adapt the intervals to maintain the average too, unlike w2k/xp.

I've left
fire next < now ? now + t->period
such that when the system is overloaded, the current behaviour (now + period) is maintained.
This particular case is not backed by tests, it's simply what the old code always did.

Winmm:time* behave differently when overloaded: if late by 100ms when trying to deliver 10ms
events, it'll trigger 10 times in a row.  This may be ok for multimedia winmm timers issued from a
single timer thread, but I feel that's not ok for a mechanism backed by N worker threads which
would then run in parallel. That wouldn't help an already overloaded system.

Regards,
 Jörg Höhle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0002-ntdll-Stabilize-CreateTimerQueueTimer-callbacks-ove.patch
Type: application/octet-stream
Size: 1497 bytes
Desc: 0002-ntdll-Stabilize-CreateTimerQueueTimer-callbacks-ove.patch
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20121026/b90a11c0/attachment.obj>


More information about the wine-patches mailing list