Should kqueue EVFILT_TIMER events be processed by wall clock time after sleep?
site_archiver@lists.apple.com Delivered-To: darwin-kernel@lists.apple.com Thanks, William Kucharski kucharsk@mac.com _______________________________________________ Do not post admin requests to the list. They will be ignored. Darwin-kernel mailing list (Darwin-kernel@lists.apple.com) Help/Unsubscribe/Update your Subscription: http://lists.apple.com/mailman/options/darwin-kernel/site_archiver%40lists.a... This email sent to site_archiver@lists.apple.com While investigating while launchd(8) events don't take time spent asleep into account, I've come upon a perplexing question that I can't answer without sitting down and attaching a debugger so I thought I would ask if anyone here knew what was going on first. By examination of timer_call_interrupt(), it appears that the first timer interrupt that occurs say after awakening from sleep should also fire all NOTE_ABSOLUTE timers that would have expired while the machine was asleep. However, if I write a simple test program that uses kqueue(2) to sleep for five minutes, if I let the routine run for about a minute, put the machine to sleep until after the time the timer should have expired, then wake the machine back up, the timer runs for another four minutes after awakening before the timer fires (meaning the routine needs to run for a NET five minutes.) This makes perfect sense, as the system timers are implemented using the PPC decrementer, which of course doesn't run while the system is asleep. I thought that perhaps there wasn't a queued event that was firing earlier to "collect" the expired timers, so I set one timer for five minutes and another for one, and repeated the test. The five minute timer still took a net five minutes to fire, not five absolute minutes. This explains why users are never seeing their "monthly" periodic scripts run; because you have to accumulate a month's worth of system runtime before the timer will fire. For users that don't reboot their systems, assuming 12 hours on and 12 hours asleep, those users would go around TWO months without the monthly periodic script being run. Reboots for system upgrades throw this all off further, as the timers are all reloaded with the time remaining until the periodic scripts should run, making the question of whether the timers will fire and when almost completely indeterministic. So the obvious question is whether this is by design or if the mechanism that should be triggering callbacks for multiple expired timers in timer_call_interrupt() is broken somehow. The sample code is attached, in case I'm making a stupid error, but it's based on the code I found in launchd.c from launchd-106.3... (By the way, the kqueue(2) man page says EVFILT_TIMER timers are unsupported, but since launchd(8) uses them...) ke.c
participants (1)
-
William Kucharski