gen_fsm:send_after | start_timer

Sean Hinde <>
Tue Jul 10 15:53:51 CEST 2001


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

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

This sounds like a nice feature. I just implemented a bunch of callbacks to
be able to change the timer values in my protocol module..

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

In the latest stdlib I have access to (1.9.4) it is:

sleep(T) ->       
    receive       
    after T -> ok 
    end.

This looks reasonably 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.

Nice to know.

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

What about the performance difference between your apply_after and
erlang:start_timer?

Do you know if receive loops use the same timer wheel?

How about:

apply_after(T, M, F, A) ->
	erlang:start_timer(T, timer, {apply, M, F, A}).

%% Permanent loop registered as {local, timer}:

loop() ->
    receive
        {timeout, Ref, {apply, M, F, A}} ->
            spawn_link(?MODULE, do, [M, F, A, self()]),
            loop().

do(M, F, A, Pid) ->
	apply(M, F, A).
	unlink(Pid).

This avoids having lots of extra processes lying around (but the timer isn't
linked to the requesting process).

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




More information about the erlang-questions mailing list