wine CPU usage and CreateWaitableTimer

Sebastian Lackner sebastian at fds-team.de
Sun Jun 7 13:08:03 CDT 2015


Hello andrea,

good catch, its actually a bug in SystemClockAdviseThread. A patch like:

--- snip ---
diff --git a/dlls/quartz/systemclock.c b/dlls/quartz/systemclock.c
index 043299b..ac41a49 100644
--- a/dlls/quartz/systemclock.c
+++ b/dlls/quartz/systemclock.c
@@ -127,6 +127,7 @@ static DWORD WINAPI SystemClockAdviseThread(LPVOID lpParam) {
       it = nextit;
     }
     if (NULL != it) timeOut = (DWORD) ((it->rtBaseTime + it->rtIntervalTime) - curTime) / (REFERENCE_TIME)10000;
+    else timeOut = INFINITE;
 
     /** Now Periodics Advice: semi sorted list (sort cannot be used) */
     for (it = This->pPeriodicAdvise; NULL != it; it = it->next) {
--- snip ---

Seems to be sufficient to fix it. I will review the code for other errors one more time,
and then submit the patch.

Regarding your second question, the best timer (when using for events) is
CreateWaitableTimer in my opinion. All other timers need separate threads, and need an
additional wineserver call for event handling.

Regards,
Sebastian

On 06.06.2015 16:28, andrea wrote:
> On 01/06/15 20:43, andrea wrote:
>> Hi,
>>
>> I'm trying to understand why AppleWin uses 100% CPU when running in wine vs ~1% in Windows.
>>
>> my case is wine 1.7.43 vs Windows 7
>>
>> https://appdb.winehq.org/objectManager.php?sClass=version&iId=29403
>> https://bugs.winehq.org/show_bug.cgi?id=34945
>>
>> basically 97% time is spent in a WaitForSingleObject on a semaphore signalled by a DirectSound
>> IReferenceClock via AdvisePeriodic.
>> The timer period is set to 1 millisecond.
>>
>> I have tried an other Windows call to create the timer: CreateWaitableTimer
>> The latter uses about 50% CPU, so it is much better, but still not very good.
>>
>> This is true even on a simple app that does nothing other than waiting for this timer all the time.
>>
>> Does anybody know
>>
>> 1) is this normal? should these waits be almost free like they are in Windows?
>> 2) what is the best implemented timer in wine that can be used for a periodic event (~1ms)?
>>
>> Thanks
>>
>>
>>
>>
> 
> I've tried 4 different function to create a period timer
> 
> http://pastebin.com/wt4iTL78
> 
> you can compiler it as
> 
> // winegcc -g timers.cpp -lwinmm -lole32 -lstrmiids
> 
> and then run it as
> 
> ./a.out X Y
> 
> where X is the period of wait in ms, and Y the method
> it will wait till 10 seconds and print some statistics
> (you can use "time" to time it)
> 
> 1 - CreateWaitableTimer
> 2 - IReferenceClock->AdvisePeriodic
> 3 - CreateTimerQueueTimer
> 4 - timeSetEvent
> 
> if the wait is 1 ms each time I get the following system times (out of ~10 sec of execution, compute with "time")
> 
> 1 - 0.33s
> 2 - 4.05s
> 3 - 0.57s
> 4 - 0.54s
> 
> if I wait every 5 ms I get
> 
> 1 - 0.15s
> 2 - 3.95s
> 3 - 0.28s
> 4 - 0.20s
> 
> It feels like option 2 (IReferenceClock) is implemented as a sort of spin lock, its system time does not decrease with longer waits.
> 
> What do you think?
> 
> Andrea
> 
> 
> 
> 




More information about the wine-devel mailing list