Re: Repeating timer firing way to fast

Jon Gotow

Not knowing how your code is structured, this may be a dumb question, but just to check:

Are you certain that you're not creating multiple timers somehow? I've mistakenly done this when creating timers in response to an event and the event occurs in extra, unexpected circumstances.

- Jon

On May 22, 2018, at 5:15 AM, Jonathan Taylor <jonathan.taylor@...> wrote:

Hi all,

I’ve been trying to figure out what happened on an overnight run of the code that drives our scientific experiment, and I’m seeing logs that imply that a timer has been firing much more rapidly than intended. I’m hoping somebody can help me figure out why, and what I should be changing.

The calls that set up the timer can be condensed down to:

timerSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, DISPATCH_TIMER_STRICT, dispatch_get_main_queue());
dispatch_source_set_event_handler(timerSource, myHandler);
dispatch_source_set_timer(timerSource, dispatch_time(DISPATCH_TIME_NOW, repeatIntervalNs), repeatIntervalNs, flexibilityNs);

where repeatIntervalNs is 4*NSEC_PER_SEC and flexibilityNs is 2*NSEC_PER_SEC. The CPU is under fairly high load from multithreaded code all night, but normally the timer fires on average every 4 seconds. Note that I have specified DISPATCH_TIMER_STRICT in a perhaps-misguided attempt to protect against the fact that occasionally, under unusually high load I presume, the timer was not firing for 30 seconds or more at a time. However, the problem that I am seeing in practice is that (in this overnight run, at least) the timer was firing at a rate of up to 200 times per second! All I am trying to achieve with this periodic timer is to check in with the secondary process and provide it with a status update.

The perhaps-unusual thing here is that the timer callback makes a function call via an NSConnection to a secondary process. Sometimes that secondary process is busy (for seconds at a time) and therefore the timer callback blocks. My theory is that what is happening is that the OS is building up a “backlog” of timer callbacks that it wants to make - many more, indeed, than than it would make if it really was firing every ~4secs.

None of this is a huge problem (except that it’s led to an enormous log file!), but it makes me worry that I am going about all of this the wrong way. What do people think? Is this a terrible way to achieve what I want to achieve, for some reason? Does it seem plausible that the number of timer callbacks would be disproportionately high like this? Any suggestions most welcome!


Join to automatically receive all group messages.