<div dir="ltr">The implementation of the timer module does rely on the same sleeping machinery as receive (gen_server timeout) but it doesn't suffer drift by using the technique that Darach suggested. It keeps track of timers in terms of absolute time, and when it wakes up it samples the clock to see which timers need to fire. Nothing special about the timer module, it just uses a better algorithm... although it is a single gen_server process per node, so having a lot of timers can be a bottleneck.<div><br></div><div><a href="https://github.com/erlang/otp/blob/maint/lib/stdlib/src/timer.erl#L345-L375">https://github.com/erlang/otp/blob/maint/lib/stdlib/src/timer.erl#L345-L375</a><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jan 13, 2015 at 8:28 PM, Roberto Ostinelli <span dir="ltr"><<a href="mailto:roberto@widetag.com" target="_blank">roberto@widetag.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">Thank you Imants.<div>Indeed, <font face="monospace, monospace">timer:apply_interval/4</font> actually works perfectly, no timer weirdness. I guess the implementation is not depending on the normal <font face="monospace, monospace">receive..after..end</font> loop.</div><div><br></div><div>For others interested, here's a working code example:</div><div><br></div><div><div><font face="monospace, monospace">-module(test).</font></div><div><font face="monospace, monospace">-export([call_periodical/2]).</font></div><div><font face="monospace, monospace">-export([periodical_fun/1]).</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">call_periodical(Num, IntervalMs) -></font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">    </span>Start = epoch_time_ms(),</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">  </span>{ok, TRef} = timer:apply_interval(IntervalMs, ?MODULE, periodical_fun, [self()]),</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap"> </span>wait(Num),</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">        </span>io:format("Finished in ~p microseconds.~n", [epoch_time_ms() - Start]),</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap"> </span>timer:cancel(TRef).</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">wait(0) -> ok;</font></div><div><font face="monospace, monospace">wait(Num) -></font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">   </span>receive</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">           </span>ok -> wait(Num - 1);</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">           </span>_ -> ok</font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">        </span>end.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">periodical_fun(Pid) -></font></div><div><font face="monospace, monospace"><span style="white-space:pre-wrap">       </span>Pid ! ok.</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">epoch_time_ms() -></font></div><div><font face="monospace, monospace">    {Mega, Sec, Micro} = os:timestamp(),</font></div><div><font face="monospace, monospace">    (Mega * 1000000 + Sec) * 1000 + round(Micro / 1000).</font></div></div><div><br></div><div><br></div><div>Running it:</div><div><br></div><div><span class=""><div><font face="monospace, monospace">Erlang/OTP 17 [erts-6.3] [source] [64-bit] [smp:8:8] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Eshell V6.3  (abort with ^G)</font></div><div><font face="monospace, monospace">1> c(test).</font></div><div><font face="monospace, monospace">{ok,test}</font></div></span><div><font face="monospace, monospace">2> test:call_periodical(1000, 10).</font></div><div><font face="monospace, monospace">Finished in 10004 microseconds.</font></div><div><font face="monospace, monospace">{ok,cancel}</font></div><div><font face="monospace, monospace">3> test:call_periodical(2000, 10).</font></div><div><font face="monospace, monospace">Finished in 20002 microseconds.</font></div><div><font face="monospace, monospace">{ok,cancel}</font></div><div><font face="monospace, monospace">4> test:call_periodical(10000, 1). </font></div><div><font face="monospace, monospace">Finished in 10002 microseconds.</font></div><div><font face="monospace, monospace">{ok,cancel}</font></div><div><font face="monospace, monospace">5> test:call_periodical(20000, 1).</font></div><div><font face="monospace, monospace">Finished in 20000 microseconds.</font></div><div><font face="monospace, monospace">{ok,cancel}</font></div><div><font face="monospace, monospace">6> test:call_periodical(1000, 1). </font></div><div><font face="monospace, monospace">Finished in 1002 microseconds.</font></div><div><font face="monospace, monospace">{ok,cancel}</font></div></div><div><br></div><div>Where everything works as expected.</div><div><br></div><div>Thank you everyone!</div><div><br></div><div>Best,</div><div>r.</div><div><br></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 12, 2015 at 6:14 PM, Imants Cekusins <span dir="ltr"><<a href="mailto:imantc@gmail.com" target="_blank">imantc@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">btw CPU looked ok: was spread across cores and did not max out.<br>
</blockquote></div><br></div>
</div></div><br>_______________________________________________<br>
erlang-questions mailing list<br>
<a href="mailto:erlang-questions@erlang.org">erlang-questions@erlang.org</a><br>
<a href="http://erlang.org/mailman/listinfo/erlang-questions" target="_blank">http://erlang.org/mailman/listinfo/erlang-questions</a><br>
<br></blockquote></div><br></div>