hibernate and proc_lib

Ulf Wiger (AL/EAB) <>
Mon Jun 14 12:45:09 CEST 2004


There is a function called erlang:hibernate/3, which reduces the memory
footprint of a process as much as possible until it receives a message.
This function can be useful for applications that require a very large
number of processes, but run into problems with memory consumption.
Each time a process can be expected to idle for a while, one can call
erlang:hibernate(Mod,Function,Args), and the process will be shrunk
until it has reason to wake up, in which case apply(Mod,Function,Args)
is called, and execution continues from there.

One of the things hibernate/3 does is remove the stack, which also 
means that any 'catch' will also be removed. This is not a big problem, 
as long as you're aware of it.

For example, if one has a top-level catch for central error handling, 
this catch has to be re-inserted each time after hibernation. This 
is reasonably easy to do if a wrapper function is provided. 

As an example, consider proc_lib:spawn_link(M,F,A).
It is used e.g. by gen_servers and supervisors, and makes it possible to 
receive crash reports if the process dies. This is accomplished using a 
top-level catch in proc_lib:

init_p(Parent,Ancestors,M,F,A) ->
    put('$ancestors',[Parent|Ancestors]),
    put('$initial_call',{M,F,A}),
    Result = (catch apply(M,F,A)),
    exit_p(Result,{M,F,A}).

exit_p({'EXIT',Reason},StartF) ->
    crash_report(Reason,StartF),
    exit(Reason);
exit_p(Reason,_) ->
    Reason.

Doing hibernate on such a process would have the effect that
no crash report would be generated after a crash, unless one
provides a proc_lib:hibernate(M,F,A):

hibernate(M,F,A) ->
   erlang:hibernate(proc_lib, wake_up, [M,F,A]).

wake_up(M,F,A) ->
   Result = (catch apply(M,F,A)),
   exit_p(Result, {M,F,A}).

I propose that OTP add such a function to proc_lib.erl in order
to highlight the issue and demonstrate the workaround.

/Uffe



More information about the erlang-questions mailing list