[PATCH RFC 0/5] Timer Resolution
Arkadiusz Hiler
ahiler at codeweavers.com
Mon Aug 17 12:46:49 CDT 2020
TL;DR: Good learning experience, lead to a fix in winmm but IMO we are better
off defaulting to 1ms resolution and avoid all the extra complications.
The whole thing started because of miss-assigning blame for DOSBox regression
to mismatched GetTickCount() and Sleep() resolutions. Initial attempts at
fixing the issue just made Sleep() work in increments of 15.6ms.
Then, I have learned about timer resolution and I have started implementing
this series. As soon as I had working timeBeginPeriod() DOSBox regressed
again.
After some confusing debugging of "phantom" calls to GetTickCount() with
1-call stacktraces and building myself and unoptimized debug version of SDL
and DOSBox I have found out that, in Wine, timeGetTime() is an alias for
GetTickCount() and this has caused the problem.
More details here: https://www.winehq.org/pipermail/wine-devel/2020-August/171965.html
I have started questioning usefulness and feasibility of implementing
resolution support:
- introducing extra branching for each Sleep / Wait call
- multiple places to maintain (some wait calls use server_wait, other call server directly)
- a lot of Sleep(1) to assess across Wine's codebase
- per-process implementation may be not sufficient for some multi-process software
I did testing with popular software and a lot of things set resolution:
* Chrome and a lot of Electron-based apps - 1ms with multimedia content,
fluctuating otherwise
* Firefox - 8ms when downloading, 5ms when playing music/videos
* Visual Studio - 1ms all the time
* Discord - 1ms all the time while being on a voice chat
* Spotify - oscillating 1-5ms when playing music
* EGS - 1ms
* many many games
Resolution is global - if one process requests high resolution (i.e. low
update interval) the whole system gets it.
Conjecture: If having 1ms resolution all the time / by default would cause any
noticeable problems / performance issue with software, it would be seen on
Windows and loudly complained about.
I think it's worth abandoning the effort to implement proper resolution
setting, default to 1ms and implement more convincing stubs for
timeBeginPeriod() and NtSetTimerResolution() and friends.
Any thoughts?
Cc: Rémi Bernon <rbernon at codeweavers.com>
Cc: Paul Gofman <pgofman at codeweavers.com>
Arkadiusz Hiler (5):
ntdll: Implmement NtQueryTimerResolution and NtSetTimerResolution
ntdll: Make wait/delay calls respect the timer resolution
server: Set the worst case time for updating user_shared_data to 15ms
ntdll: Remove todo_wine from tick count vs sleep test
winmm: Implement timeBeginPeriod() and timeEndPeriod()
dlls/ntdll/tests/time.c | 187 ++++++++++++++++++++++++++++++++-
dlls/ntdll/unix/server.c | 16 ++-
dlls/ntdll/unix/sync.c | 84 +++++++++++++--
dlls/ntdll/unix/unix_private.h | 10 ++
dlls/winmm/tests/timer.c | 46 +++++++-
dlls/winmm/time.c | 76 +++++++++++---
server/fd.c | 2 +-
7 files changed, 396 insertions(+), 25 deletions(-)
--
2.28.0
More information about the wine-devel
mailing list