Subject: Re: bug#12248: sleep is not arware of suspend mode

From: Pádraig Brady <[email-masked]>
Date: Wed, 22 Aug 2012 01:15:31 +0100

On 08/21/2012 10:03 PM, Eric Blake wrote:
> On 08/21/2012 02:50 PM, Paul Eggert wrote:
>> On 08/21/2012 09:58 AM, Bob Proulx wrote:
>>> That is the expected behavior.
>>
>> It's not the behavior *I* expect.  I expect
>> 'sleep' to use realtime seconds, not seconds
>> of some arbitrary clock that's way far from
>> real time.
> 
> In fact, I think both modes have their use, and that we probably ought
> to provide an option to choose between absolute wall clock deadline
> (stable realtime sleep even if the processor time jumps forwards or
> backwards or has gaps due to suspend) vs. elapsed relative processor
> time (where changing the processor clock can lengthen or shorten the
> sleep duration).  If we do add code to support multiple flavors of sleep
> durations, I'd probably lean towards absolute wall time as the default.

I agree that either behavior could be required.
The default though should probably stay as is.
I.E. when the system suspends, the timeout suspends too.
Changing to "wall clock time" would require an option,
as that can jump around due to suspend, ntp, ...

We had this discussion recently also, in relation to timeout(1).

timeout(1) currently uses timer_create(CLOCK_REALTIME).
According to docs¹, that should jump due to settime()/settimeofday()/resume
though I can't reproduce here with a resume, or even when pushing the
updated system clock down to the hardware:

# timeout 3 sh -c 'date --set=$(LC_ALL=C date -d 10\ sec +@%s); hwclock -w; sleep 1'
# echo $?
0

Here is some pertinent info from nanosleep(2) (used by sleep(1)):
   POSIX.1  specifies  that  nanosleep()  should  measure time against the
   CLOCK_REALTIME clock.  However,  Linux  measures  the  time  using  the
   CLOCK_MONOTONIC  clock.   This  probably  does  not  matter,  since the
   POSIX.1 specification  for  clock_settime(2)  says  that  discontinuous
   changes in CLOCK_REALTIME should not affect nanosleep():
        Setting  the  value  of  the CLOCK_REALTIME clock via clock_set‐
        time(2) shall have no effect on threads that are blocked waiting
        for a relative time service based upon this clock, including the
        nanosleep() function; ...   Consequently,  these  time  services
        shall expire when the requested relative interval elapses, inde‐
        pendently of the new or old value of the clock.
Maybe the kernel is incorrectly implementing this POSIX clause
for our interval timer. Perhaps we need to specify TIMER_ABSTIME
to timer_settime to avoid that? I need to look into that further.

Anyway to explicitly select with an option, a "running time" rather than
"wall time" we could use CLOCK_MONOTONIC (or CLOCK_MONOTONIC_RAW on newer kernels).
That's not always available though, so then we'd have to look at/document
the inconsistency on systems without CLOCK_MONOTONIC.

Note also that timeout currently doesn't handle a SIGSTOP or SIGTSTP specially,
as I was thinking it should count down system running time rather
than job running time, as that is dependent on many factors.

cheers,
Pádraig.

¹ http://juliusdavies.ca/posix_clocks/clock_realtime_linux_faq.html