Matthew Garrett ([personal profile] mjg59) wrote2011-11-17 08:39 am
Entry tags:

Making timeouts work with suspend

A reasonably common design for applications that want to run code at a specific time is something like:

time_t wakeup_time = get_next_event_time();
time_t now = time(NULL);
sleep(wakeup_time-now);

This works absolutely fine, except that sleep() ignores time spent with a suspended system. If you sleep(3600) and then immediately suspend for 45 minutes you'll wake up after 105 minutes, not 60. Which probably isn't what you want. If you want a timer that'll expire at a specific time (or immediately after resume if that time passed during suspend), use the POSIX timer family (timer_create, timer_settime and friends) with CLOCK_REALTIME. It's a signal-driven interface rather than a blocking one, so implementation may be a little more complicated, but it has the advantage of actually working.
heliumbreath: (Default)

[personal profile] heliumbreath 2011-11-17 03:57 pm (UTC)(link)
Changes in system time were traditionally another thing that caused issues, though that was most infamously linked to X inactivity timeout triggering screenlock, which wouldn't have been sleep(). It might have been nice to have had a SIGTIMEWHOOPS that gets sent on return-from-suspend, clock changes, and other real-world botherations of the normal happy computer model.

Another thought is that one could explore changing the sleep() model in the kernel; good userspace code should handle an early return, so coming back per the other interpretation might cause less trouble.