[erlang-questions] Minimum time for timer:sleep()?

Per Hedeland per@REDACTED
Mon Mar 19 01:26:40 CET 2007


"Bob Ippolito" <bob@REDACTED> wrote:
>
>On 3/18/07, James Hague <james.hague@REDACTED> wrote:
>> Here's some simple code to test timer:sleep/1:
>>
>> test(Milliseconds) ->
>>    T1 = now(),
>>    timer:sleep(Milliseconds),
>>    T2 = now(),
>>    io:fwrite("elapsed: ~w\n", [timer:now_diff(T2, T1)]).
>>
>> On the recent model MacBook I tested this on, test(5) prints "elapsed:
>> 10182".  In fact, any value less than 10 milliseconds sleeps for ~10
>> milliseconds.  Considering that a message send/receive pair is
>> measured in single-digit MICROseconds on the same machine, this is
>> curious to me.   Does anyone have any insight into this behavior?
>>
>> (FWIW, timer:sleep/1 is implemented as a single receive statement.)
>
>I have no idea what the Erlang VM does but I'd guess that this 10 msec
>granularity comes from the fact that multiplexing syscalls like
>select/poll or kqueue (at least on OS X) are about that accurate when
>you use them to sleep.

Yes, it's nothing Erlang-specific - pretty fundamental actually:
Timeouts can only happen on a system clock interrupt, and they obviously
happen with the frequency of your system clock, which is traditionally
100 Hz on Unix. You can crank it up on most Unixen if you care about
this - I believe some Linux kernel versions used 1000 Hz by default, but
they tended to lose clock interrupts then...

Actually there used to be some code in the Erlang VM to adjust the value
such that e.g. a 'receive ... after 5000 ...' wouldn't give up after 10
microseconds just because that's when the next clock interrupt happened
to arrive - i.e. you'd always get at least one clock period. Don't know
if it's still there, but something like it should be.

>If you wanted something more accurate you'd have to use a whole
>pthread and nanosleep or polling.. neither of those are terribly easy
>to pull off. You might get slightly different results depending on if
>you're using smp or async threads...

None of that helps, nanosleep despite its name is still limited by the
system clock frequency - it's just that when POSIX decided to specify
something that could let you sleep with better granularity than 1
second, they wanted to be future-proof.:-) The only way to get better
precision for a delay/timeout than what the system clock provides is by
busy-waiting.

--Per Hedeland



More information about the erlang-questions mailing list