gen_fsm:send_after | start_timer

Ulf Wiger etxuwig@REDACTED
Tue Jul 10 15:19:10 CEST 2001


On Mon, 9 Jul 2001, Francesco Cesarini wrote:

>Hi,

>I do not have a decent work environment to do any tests right,
>but I believe that an attempt at cleaning up the timer module
>has been made. The design rule in the AXD is from 1996, and a
>lot has changed since then. I do not think the ban is in the
>updated design rules.

The design rule is still there, and the rule is to use the AXD
301 sysTimer.erl module for all timers. Whenever there is an
efficient OTP method to execute the corresponding timer, we
rewrite the sysTimer.erl module to use that function. That was
done when erlang:start_timer/3 was introduced.

timer:apply_after/4 still does all sorts of things that we don't
want:

- a gen_server:call(), which in itself is more expensive than
  erlang:start_timer/3.

- a call to timer:system_time(), which essentially creates a
  bignum out of the system time, and adds the ordered time
  interval (which is never a bignum). Bignum arithmetics are 
  expensive.

- performs a sorted insert.

Apart from this, it will land in a receive ... after once per
timer, which is unavoidable, and then spawns a process to
execute {M,F,A}, which is desireable.

sysTimer:apply_after/4 does this:

apply_after(Time, M, F, A) when integer(Time) ->
    spawn_link(sysTimer, do_apply_after, 
               [Time, M, F, A, self()]);
apply_after(Name, M, F, A) ->
    spawn_link(sysTimer, do_apply_after, 
               [get_value(Name), M, F, A, self()]).

do_apply_after(Time, M, F, A, LinkedPid) ->
    put(arguments, [Time, M, F, A, LinkedPid]),
    sleep(Time),
    apply(M, F, A),
    unlink(LinkedPid).


The call to put(arguments, ...) is to facilitate debugging,
and this version of apply_after/4 also supports named timers,
which is very useful for protocol programming, as the standard
timers must often be customizable.

I will not present sleep(), because I just found that it has been
inefficiently (re-)implemented since the last time I looked.  ):
Its efficient implementation is trivial.

The method of timer.erl to use a sorted list in order to offload
the timer wheel in the emulator is a sub-optimization. We've
verified that the timer wheel (timeout queue) in BEAM shows
hardly no degradation at all even with 20,000 concurrent timers.

An erlang implementation simply cannot compete with the built-in
timeout support, and apply_after should basically only do the
required extra of spawning a process to give the function an
execution context. Everything else is just garnish.

sysTimer.erl does have some of that, for example repeating timers
which compensate for the drift in time, and specified timers that
work around the 32-bit limitation of the timeout queue, as well
as handle daylight savings time.

/Uffe

>> degenerate way if there are more than a small number of timers running. I
>> remember reading that use of timer module is banned in AXD for this reason.
>>
>> - Sean
>>
>> NOTICE AND DISCLAIMER:
>> This email (including attachments) is confidential.  If you have received
>> this email in error please notify the sender immediately and delete this
>> email from your system without copying or disseminating it or placing any
>> reliance upon its contents.  We cannot accept liability for any breaches of
>> confidence arising through use of email.  Any opinions expressed in this
>> email (including attachments) are those of the author and do not necessarily
>> reflect our opinions.  We will not accept responsibility for any commitments
>> made by our employees outside the scope of our business.  We do not warrant
>> the accuracy or completeness of such information.
>

-- 
Ulf Wiger                                    tfn: +46  8 719 81 95
Senior System Architect                      mob: +46 70 519 81 95
Strategic Product & System Management    ATM Multiservice Networks
Data Backbone & Optical Services Division      Ericsson Telecom AB




More information about the erlang-questions mailing list