Should kqueue EVFILT_TIMER events be processed by wall clock time after sleep?
Should kqueue EVFILT_TIMER events be processed by wall clock time after sleep?
- Subject: Should kqueue EVFILT_TIMER events be processed by wall clock time after sleep?
- From: William Kucharski <email@hidden>
- Date: Fri, 18 Nov 2005 05:27:57 -0700
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...)
Thanks,
William Kucharski
email@hidden
Attachment:
ke.c
Description: Binary data
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Darwin-kernel mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden