parapluu/Concuerror

erts_internal:map_next/3 not supported

Closed this issue · 7 comments

essen commented

Hello! Trying to use Concuerror with Ranch. Ranch uses maps. Running into this while trying to start a listener:

* Error: Concuerror does not support calls to built-in
erts_internal:map_next/3 (found in maps.erl line 278).
If you really need this functionality, contact the developers.

The following test case is a minimal example to reproduce the problem:

test() ->
    maps:fold(fun(_,_,Acc) → Acc end, ok, #{}),
    ok.
essen commented

If I understand correctly this just needs adding {erts_internal, map_next, 3} to is_unsafe and returning false in that case? Since there shouldn't be any side effects. If so I can open a PR later.

I tried to find some documentation about erts_internal:map_next/3 but could not locate it. So, I do not know its precise semantics. From a very quick look at its current implementation, it seems that this BIF cannot be interrupted and does not access any memory that can be modified by another process. So, most likely, the above that you suggest will suffice.

Since you probably have better test cases than the above, why don't you try your change and see what happens?

I am 99% certain that map_next should be a process-local and therefore safe operation. I am also 80% certain that @essen 's suggested fix for is_unsafe is all that is needed. 😄 Please go ahead and add it (and maybe add a test with a single process doing just this (and exiting) and a depth bound of 1, which should return normally == not needing more than 1 event (for exiting) == not treating the maps operation as a "noteworthy" one)!

essen commented

I've done the change in order to progress but this map:fold is occurring before process interactions so I'm not expecting failures to occur here anyway.

I'll double check if there's other map related BIFs and send a PR in a few days. Cheers.

I've done the change in order to progress but this map:fold is occurring before process interactions so I'm not expecting failures to occur here anyway.

FYI: It actually works the other way around. If you specify some BIF as unsafe = false, all that is at risk is that Concuerror will not be able to examine its concurrency non-determinism, so perhaps some concurrency errors will be missed. It's unlikely that you will see any failures.

essen commented

Yes of course but I meant based on my code I would be surprised if failure occurred at this point even if it was somehow an unsafe call. The call is made before anything interesting happens. You never know of course...

Merged #317 so closing this. Thanks @essen !