CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 24
  1. #1
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    Waitable timer spotty precision

    I'm using a version of the following code in my actual production code. It sets a waitable timer for some time in the future and then has one worker thread waiting for it to fire:

    Code:
    //Create timer
    hWTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);
    
    //Number of minutes to wait
    int nMinutesToWait = 5;
    
    //Predict when it should fire
    COleDateTime dtWhen = COleDateTime::GetCurrentTime() + COleDateTimeSpan(0, 0, nMinutesToWait, 0);
    
    //Set timer
    SetWaitableTimerSecondsFromNow(hWTimer, nMinutesToWait * 60);
    
    //Waiting part
    if(::WaitForSingleObject(hWTimer, INFINITE) == WAIT_OBJECT_0)
    {
        //Timer has fired, compare when
        _TRACE(L"Time scheduled for: %s, time fired: %s", 
            dtWhen.Format(),
            COleDateTime::GetCurrentTime().Format());
    }
    
    BOOL SetWaitableTimerSecondsFromNow(HANDLE hWTimer, double fSecs2Wait)
    {
        //INFO: I'm setting the timer to a relative time to ensure that it
        //      doesn't fire in case the system clock is adjusted.
        LARGE_INTEGER li;
        li.QuadPart = -10000000LL * (LONGLONG)fSecs2Wait;   //Convert to 100 nanosecond intervals (MUST BE NEGATIVE)
        if(li.QuadPart >= 0)
            return FALSE;
    
        return ::SetWaitableTimer(hWTimer, &li, 0, NULL, NULL, FALSE);
    }
    It works well and in most circumstances the time when the timer needs to fire and when it actually fires is a 100% match. But very rarely, the timer fires 10-15 seconds earlier for just a 5 minute wait. It also seems like this issue mostly happens on Windows XP.

    Does anyone have any idea what's going on here and how to mitigate it?

  2. #2
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    But very rarely, the timer fires 10-15 seconds earlier for just a 5 minute wait. It also seems like this issue mostly happens on Windows XP.

    Does anyone have any idea what's going on here and how to mitigate it?
    that looks like a lot of time, much more than implied by the RTC accuracy. I never used COleDateTime, but a quick look at msdn shows that it stores a day counter ( starting from the year ~1900 ) in a double variable, possibly giving unaccurate results at the seconds accuracy level ( maybe, cancellation errors in COleDateTime::Format ? ). So, the first quick check I'd try is to compare the result by using a different API like GetTickCount ( that AFAIK, uses the same timing source as SetWaitableTimer, that is the 32khz RTC ) ...

  3. #3
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    Re: Waitable timer spotty precision

    Thanks, I thought about that too. But I don't think that a `double` variable precision would "err" in some rare instances like in my case here. It sounds more like a hardware timer occasional fault. I'm thinking now that maybe setting it for 5 minutes is too long of a time for it. Or maybe there's a way to re-calibrate it somehow?

  4. #4
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Waitable timer spotty precision

    What about using a multimedia timer? If not that, then how about rolling your own with a thread and gettickcount?

  5. #5
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    Re: Waitable timer spotty precision

    Quote Originally Posted by Arjay View Post
    What about using a multimedia timer? If not that, then how about rolling your own with a thread and gettickcount?
    Hmm. As for the multimedia timer, can I use synchronization/waiting API on it?

  6. #6
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    Hmm. As for the multimedia timer, can I use synchronization/waiting API on it?
    I don't know, but you could set an event when the timer triggers and wait on the event somewhere else.

  7. #7
    Join Date
    Oct 2008
    Posts
    1,456

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    Thanks, I thought about that too. But I don't think that a `double` variable precision would "err" in some rare instances like in my case here. It sounds more like a hardware timer occasional fault. I'm thinking now that maybe setting it for 5 minutes is too long of a time for it. Or maybe there's a way to re-calibrate it somehow?
    It's still worth checking if the problem lies in the wait function or in the way you measure time. Yes, given the way one "could" implement the Format function there should be no error of that magnitude given double precision, but we don't know the Format ( or the other ole date members ) implementation and no, floating point calculations can give erratic results manifesting themselves only on rare and apparently unpredicatble occasions due to unproper error analysis, rounding, etc.... Even ignoring the floating point issue, ole datetime could have other issues as well if based on absolute system time, quoting MSDN:

    Note that the system can periodically refresh the time by synchronizing with a time source. Because the system time can be adjusted either forward or backward, do not compare system time readings to determine elapsed time. Instead, use one of the methods described in Windows Time.
    so, I'd check it first ( simply use GetTickCount instead ).

    regarding the 5 minutes period being too long, I doubt so, AFAIK the RTC is much more accurate than that ...
    regarding the calibration issue, if you're awaking too early you can simply wait for the remaining expected time, provided the latter is not the actual source of the problem as discussed above ...

  8. #8
    Join Date
    Nov 2000
    Location
    Voronezh, Russia
    Posts
    6,620

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    very rarely, the timer fires 10-15 seconds earlier for just a 5 minute wait. It also seems like this issue mostly happens on Windows XP.
    Waitable timer is a kernel object. So it's driven by kernel dispatcher, and any variations in signalling must be due to dispatcher glitches. You should try to understand if there are any stable patterns in the effect you observe. Most probable suspects are: network operations or hard drive writes resulting in bad block relocations. Effects due to time syncs (NTP) are probable as well.
    Last edited by Igor Vartanov; November 28th, 2013 at 03:33 AM.
    Best regards,
    Igor

  9. #9
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Waitable timer spotty precision

    Waitable timers can get released earlier than you expected, for various reasons. Common reasons are related to completion objects and asynchronous IO. THey can also get released late because higher priority threads are preventing your code from getting a time-slice.

    If you are ok with "sort of" accurate timing, then simply handle the event early, or requeue a waitable timer. For a late event, there's nothing other than handling it later, there's no way to go back in time (just yet ).


    If you are expecting precision timing, then none of the regular timers are the means to get that.
    For precision timing, you will either need a multimedia timer (user mode), or a you will need to handle a kernel timer (kernel mode, so this'll need a driver). You also typically have to do this in a low-impact high-priority thread (and relay the timer event to a lower priority thread) depending on how critical the timing is, and how much work there is in response to the timer event firing.
    Last edited by OReubens; November 28th, 2013 at 07:41 AM.

  10. #10
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    Re: Waitable timer spotty precision

    Thank you, fellas. Appreciate it.

    @OReubens: What do you mean by "precision timing"? I'm sure you're referring to ms or even ns, and that's not what I'm after. What matters for me is that the timer doesn't deviate more than a second, maybe two. If so, I'd live with it.

    @Igor Vartanov: You're definitely on to something. Since I've never directly witnessed this behavior (all I have to work with are log entries) I cannot tell you what condition the workstation was in when that happened. Moreover when I try to max out the CPU "on demand" while running the tests, everything works fine. And, obviously I have no hopes of running a debugger through my threads to witness this.

    So what I implemented so far, is another periodic timer (that fires every 10 seconds) that reprograms this, let's call it, "main timer" by calling ::SetWaitableTimer() again and again. And so far, since adding this new "hack" I don't see any more misfiring. If I do see it I'll post back to this thread. In that case I'll try to use multimedia timers as was suggested by several people above.

  11. #11
    Arjay's Avatar
    Arjay is offline Moderator / EX MS MVP Power Poster
    Join Date
    Aug 2004
    Posts
    13,490

    Re: Waitable timer spotty precision

    You can simulate bad behavior by having a test app create a high priority thread that spins.

  12. #12
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    4,626

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    @OReubens: What do you mean by "precision timing"? I'm sure you're referring to ms or even ns, and that's not what I'm after. What matters for me is that the timer doesn't deviate more than a second, maybe two. If so, I'd live with it.
    Precision is precisely (pun intended) what I mean by it. the timer fires at precise moments in time according to expectation.

    ms/ns would be "timer resolution". Regular timers like a WM_TIMER or a waitable timer (which is basically the same) are neither precise, nor do they have a high resolution.

    A multimediatimer has a high resolution but doesn't have any actual precision, but you can provide your own precision because of the high resolution (typically a poll/check loop). THis is why I also said you needed a low-impact (not using a lot of CPU resources each time the timer fires) and high priority (to make sure the thread gets it's timeslice as early as possible) thread. If what you need to do is extensive (taking multiple timeslices), rather than doing that on the high priority thread you're better off relaying that to a lower priority thread.


    Kernel timers are both precise and high resolution.

  13. #13
    Join Date
    Aug 2000
    Location
    New York, NY, USA
    Posts
    5,656

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    I'm using a version of the following code in my actual production code.
    ...
    But very rarely, the timer fires 10-15 seconds earlier for just a 5 minute wait.
    I see now scenarios that can cause the timer to fire *EARLIER*. The precision is out of the question since we are talking about 15 seconds. No amount of CPU load can expedite the timer.
    Could it be that in your actual production code you set the timer first, *THEN* (after unknown delay) calculate the predictable time?
    Vlad - MS MVP [2007 - 2012] - www.FeinSoftware.com
    Convenience and productivity tools for Microsoft Visual Studio:
    FeinWindows - replacement windows manager for Visual Studio, and more...

  14. #14
    Join Date
    Nov 2003
    Location
    Portland, OR
    Posts
    894

    Re: Waitable timer spotty precision

    Quote Originally Posted by VladimirF View Post
    Could it be that in your actual production code you set the timer first, *THEN* (after unknown delay) calculate the predictable time?
    No, they're both set roughly at the same time (well obviously within a dozen CPU cycles apart) just like I showed in the code sample in my first post.

  15. #15
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,396

    Re: Waitable timer spotty precision

    Quote Originally Posted by dc_2000 View Post
    No, they're both set roughly at the same time (well obviously within a dozen CPU cycles apart) just like I showed in the code sample in my first post.
    The code you posted does not provide enough details. For ex., do you use some completion routine or not?
    Victor Nijegorodov

Page 1 of 2 12 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured