mini-EEP: erlang:sleep()

Ulf Wiger ulf.wiger@REDACTED
Wed May 19 19:14:02 CEST 2010


After a brief discussion with Tony Rogvall about the currently
very unintuitive and (in our opinion) broken implementation of
selective receive in interpreted mode (erl_eval), I decided to
have a go at implementing a version that doesn't suck up the whole
message queue and re-send it.

I will confess that I failed horribly, since I only belatedly
recalled that hibernate is useless in this setting (it butchers
the call stack), and you need a way to sleep until the next message
comes in.

So here is how I made it work:

Some BEAM ASM code follows:

{module, mybif}.  %% version = 0

{exports, [{module_info,0},{module_info,1},{sleep,0}]}.

{attributes, []}.

{labels, 8}.


{function, sleep, 0, 2}.
  {label,1}.
    {func_info,{atom,mybif},{atom,sleep},0}.
  {label,2}.
    {wait,{f,3}}.
  {label,3}.
    {move,{atom,ok},{x,0}}.
    return.
...

(This was done by writing a very simple function, compiling it
and editing the generated .S file.)

When compiled, using compile:file("mybif.S", [from_asm]), this
becomes a function, mybif:sleep(), that suspends until a message
arrives, and then returns 'ok'. It captures the actually very cool
feature of hibernate/3, that you can be told when there is a new
message to look at, but without the nasty hangover from having the
call stack removed, all catches thrown away, etc.

With this function, I could emulate selective receive by using
process_info(self(), messages), evaluate the patterns over the
list of messages, and then, if a message matches, do a receive on
that exact message from the real queue. This way, messages remain
in the queue, and you get no nasty races from emptying the queue
and refilling it.

Message with a timeout is implemented by calling start_timer,
which has the needed property of including a unique reference
in the timeout message. This allows us to check for a timeout
by doing a regular selective receive on that timeout msg.

The one thing that couldn't be done through normal means was
the sleep() above. I cannot think of any bad side-effects of
the function.

I have not pushed anything to github, as the mybif.S file is more
than a little weird.

Thoughts, anyone?

BR,
Ulf W
---------------------------------------------------

---------------------------------------------------

WE'VE CHANGED NAMES!

Since January 1st 2010 Erlang Training and Consulting Ltd. has become ERLANG SOLUTIONS LTD.

www.erlang-solutions.com



More information about the erlang-questions mailing list