Making timeouts work with suspend
Nov. 17th, 2011 08:39 am![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
A reasonably common design for applications that want to run code at a specific time is something like:
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.
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.
no subject
Date: 2011-11-17 02:17 pm (UTC)Different purposes ?
Date: 2011-11-17 02:36 pm (UTC)no subject
Date: 2011-11-17 02:48 pm (UTC)no subject
Date: 2011-11-17 06:40 pm (UTC)no subject
Date: 2011-11-17 06:55 pm (UTC)no subject
Date: 2011-11-18 04:19 am (UTC)I would think that 'realtime' in the spec says real time, not computer experienced time.
no subject
Date: 2011-11-17 10:02 pm (UTC)What do most people actually expect when they schedule a timeout or call sleep()? Any guesses?
no subject
Date: 2011-11-19 02:21 am (UTC)I am not claiming that the current behaviour is against the spec, but come on, let common sense kick in and fix this madness.
Using something else than sleep() is not an option because select/poll/etc. have the same unexpected behaviour.
no subject
Date: 2011-11-20 12:28 am (UTC)(However wrong sleep() is for the formulation that I have written here, that's just because I can't clean up the formulation to make sleep() sensible.)
Now he tells me.
Date: 2011-11-17 02:43 pm (UTC):-)
timerfd
Date: 2011-11-17 03:09 pm (UTC)no subject
Date: 2011-11-17 03:57 pm (UTC)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.
no subject
Date: 2011-11-17 04:00 pm (UTC)no subject
Date: 2011-11-17 04:34 pm (UTC)no subject
Date: 2011-11-17 04:39 pm (UTC)no subject
Date: 2011-11-17 04:40 pm (UTC)I like the idea of a signal that gets raised whenever the computer resumes so that these mechanisms can be notified that they may need to re-evaluate the passage of time.
no subject
Date: 2011-11-18 11:16 pm (UTC)no subject
Date: 2011-11-18 12:37 am (UTC)no subject
Date: 2011-11-18 12:41 am (UTC)