• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Synchronize timer with internal clock
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Synchronize timer with internal clock


  • Subject: Re: Synchronize timer with internal clock
  • From: Chris Kane <email@hidden>
  • Date: Sun, 16 Mar 2003 13:03:21 -0800

On Friday, March 14, 2003, at 15:53, John Timmer wrote:

While on the subject of timers vs. the internal clock:

How accurate are timers expected to be? I had coded something where, in
order to keep a clock display reasonably close to accurate, I was firing a
timer every 5 seconds. This seemed wasteful and inelegant, so I decided to
synchronize with the minute and fire the timer every 60 seconds. Doing so
revealed a steady downward creep when I logged the firing of the timer (see
below). I kept going, hoping that eventually it would tick up to
compensate, but instead it eventually wrapped around the minute, leaving my
clock 59.998 seconds off.

Is there any way around this, or should I be checking the accuracy of the
timer every time through and invalidating it when necessary?

John


Note the steady reduction in when the timer fired:

2003-03-14 18:31:00.453 Weather View[7155] updating time
2003-03-14 18:32:00.409 Weather View[7155] updating time
2003-03-14 18:33:00.401 Weather View[7155] updating time
2003-03-14 18:34:00.393 Weather View[7155] updating time
2003-03-14 18:35:00.385 Weather View[7155] updating time
2003-03-14 18:36:00.377 Weather View[7155] updating time
2003-03-14 18:37:00.369 Weather View[7155] updating time
2003-03-14 18:38:00.361 Weather View[7155] updating time
2003-03-14 18:39:00.353 Weather View[7155] updating time
2003-03-14 18:40:00.349 Weather View[7155] updating time


This depends in large part on the OS's estimate of the clock rate of the system clock, which varies in "goodness" by OS release and hardware. I wrote a little test and got this (on a 500 MHz DP):

2003-03-16 12:52:22.001 a.out[11586] 69540742.000053
2003-03-16 12:52:23.001 a.out[11586] 69540743.000065
2003-03-16 12:52:24.001 a.out[11586] 69540744.000055
2003-03-16 12:52:25.001 a.out[11586] 69540745.000050
2003-03-16 12:52:26.001 a.out[11586] 69540746.000058
2003-03-16 12:52:27.001 a.out[11586] 69540747.000060
2003-03-16 12:52:28.001 a.out[11586] 69540748.000056
2003-03-16 12:52:29.001 a.out[11586] 69540749.000062
2003-03-16 12:52:30.001 a.out[11586] 69540750.000063
2003-03-16 12:52:31.001 a.out[11586] 69540751.000056
2003-03-16 12:52:32.001 a.out[11586] 69540752.000066

Your tenth of a second in 10 seconds (1 part in 100) seems quite bad; I don't think I've seen something that bad since the old PowerMac 8500.

Of course, there are other effects too. The NTP daemon will drive your calendar clock (what NSLog() and CFAbsoluteTime() are showing) faster or slower than "true" while it is trying to synchronize your clock to the actual time off the Internet (rather than do a step adjustment, which it only does in extreme cases). For example, the calendar clock might only advance 950 milliseconds every second during adjustment. Usually, if you're connected to the Internet, NTP is able to get things in line within an hour with small adjustments. But even then, if you system clock is wildly different from "true", the calendar clock may advance at a different apparent rate than the system clock. Timers are fundamentally based off the system clock for their timing, even though the API is in terms of the calendar clock.

Try the test program below and see what you get.


Chris Kane
Cocoa Frameworks, Apple


#import <Foundation/Foundation.h>

@interface TEST : NSObject @end
@implementation TEST
- (void)timer:(id)x { NSLog(@"%f", CFAbsoluteTimeGetCurrent()); }
@end

#define INTERVAL 1.0

#define roundUpTime(T, I) (floor((T) / (I)) * (I) + (I))
#define dateForNextInterval(I) [[NSDate alloc] initWithTimeIntervalSinceReferenceDate: roundUpTime( [NSDate timeIntervalSinceReferenceDate], (I))]

int main() {
NSTimer *myTimer = [[NSTimer alloc] initWithFireDate:dateForNextInterval(INTERVAL)
interval:INTERVAL target:[TEST new] selector:@selector(timer:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:myTimer forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] run];
exit(0);
}
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
  • Follow-Ups:
    • Re-establishing networking on wake from sleep
      • From: John Timmer <email@hidden>
References: 
 >Re: Synchronize timer with internal clock (From: John Timmer <email@hidden>)

  • Prev by Date: Interface builder : detecting text truncations in dialogs automatically - just a dream?
  • Next by Date: Re: cocoa-dev digest, Vol 2 #2075 - 16 msgs
  • Previous by thread: Re: Synchronize timer with internal clock
  • Next by thread: Re-establishing networking on wake from sleep
  • Index(es):
    • Date
    • Thread