[erlang-questions] mini-EEP: erlang:sleep()
Ulf Wiger
ulf.wiger@REDACTED
Thu May 20 10:02:42 CEST 2010
On 05/19/2010 10:15 PM, Tony Rogvall wrote:
> You see, it was not that hard to write beam asm code ;-)
> Way to go .... maybe it's time to get some bif's doing this properly ?
> No disrespect !
Indeed. Before going to sleep, I spotted the 'obvious' race condition,
so this solution is inadequate. :)
I think my implementation is still better than the existing one,
but it should probably only serve as a basis for discussion on
how to solve it properly.
BR,
Ulf W
>
>
> /Tony
>
> On 19 maj 2010, at 19.14, Ulf Wiger wrote:
>
>> 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
>>
>>
>> ________________________________________________________________
>> erlang-questions (at) erlang.org mailing list.
>> See http://www.erlang.org/faq.html
>> To unsubscribe; mailto:erlang-questions-unsubscribe@REDACTED
>>
>
---------------------------------------------------
---------------------------------------------------
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