Matthew Garrett ([personal profile] mjg59) wrote,
@ 2011-11-17 08:39 am UTC
Entry tags:advogato, fedora
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.


(Read 19 comments) - (Post a new comment)
(Flat) (Top-level comments only)


(Anonymous)
2011-11-17 02:17 pm UTC (link)
Just out of interest: Why did nobody fix sleep() instead?

(Reply to this)  (Thread


Different purposes ?


(Anonymous)
2011-11-17 02:36 pm UTC (link)
… because they serve different purposes ?

(Reply to this)  (Thread from start)  (Parent



[personal profile] mjg59
2011-11-17 02:48 pm UTC (link)
It's a good question. The Single UNIX Spec doesn't seem entirely clear on what the expected semantics of sleep() (and alarm()) are - the relevant description is limited to "The sleep() function shall cause the calling thread to be suspended from execution until either the number of realtime seconds specified by the argument seconds has elapsed or a signal is delivered to the calling thread". "Realtime seconds" doesn't appear to be defined. The section on POSIX timers talks about "real time" rather than "realtime". So really, who knows what the correct behaviour for sleep() should be?

(Reply to this)  (Thread from start)  (Parent)  (Thread



(Anonymous)
2011-11-17 06:40 pm UTC (link)
What is the argument that "realtime" should not just be the intuitive "real wall-clock time that normal people normally care about"?

(Reply to this)  (Thread from start)  (Parent)  (Thread



[personal profile] mjg59
2011-11-17 06:55 pm UTC (link)
What's the argument that it should be? It's a spec. You're supposed to have clearly defined terms. We can argue that Linux's current behaviour is in violation, but we can't clearly demonstrate that.

(Reply to this)  (Thread from start)  (Parent



(Anonymous)
2011-11-18 04:19 am UTC (link)

I would think that 'realtime' in the spec says real time, not computer experienced time.

(Reply to this)  (Thread from start)  (Parent



(Anonymous)
2011-11-17 10:02 pm UTC (link)
The reason why I asked is that we have a similar issue in glib with g_timeout_add(). And I've been wondering if the correct approach is to do what you did and then adding a g_call_me_when_this_clock_time_has_been_hit() callback for being woken up at a certain point in time. Or if it's better to do it the other way.

What do most people actually expect when they schedule a timeout or call sleep()? Any guesses?

(Reply to this)  (Thread from start)  (Parent



(Anonymous)
2011-11-19 02:21 am UTC (link)
With the line between a system being awake and a system being asleep getting blurrier and blurrier, it seems a very good idea to fix this behaviour before it is going to bite everyone when things like autosuspend become more common.

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.

(Reply to this)  (Thread from start)  (Parent)  (Thread



(Anonymous)
2011-11-20 12:28 am UTC (link)
Some people may expect sleep() to mean "I have 10 minutes of computation to do in another thread, so don't wake me up until that computation is over."

(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.)

(Reply to this)  (Thread from start)  (Parent



(Read 19 comments) - (Post a new comment)
(Flat) (Top-level comments only)