aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/nif_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test/nif_SUITE.erl')
-rw-r--r--erts/emulator/test/nif_SUITE.erl269
1 files changed, 204 insertions, 65 deletions
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index ca5f90621f..b824daea67 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -28,6 +28,7 @@
-include_lib("stdlib/include/assert.hrl").
-export([all/0, suite/0, groups/0,
+ init_per_suite/1, end_per_suite/1,
init_per_group/2, end_per_group/2,
init_per_testcase/2, end_per_testcase/2,
basic/1, reload_error/1, upgrade/1, heap_frag/1,
@@ -64,7 +65,9 @@
nif_phash2/1,
nif_whereis/1, nif_whereis_parallel/1,
nif_whereis_threaded/1, nif_whereis_proxy/1,
- nif_ioq/1
+ nif_ioq/1,
+ pid/1,
+ nif_term_type/1
]).
-export([many_args_100/100]).
@@ -103,7 +106,17 @@ all() ->
nif_internal_hash_salted,
nif_phash2,
nif_whereis, nif_whereis_parallel, nif_whereis_threaded,
- nif_ioq].
+ nif_ioq,
+ pid,
+ nif_term_type].
+
+init_per_suite(Config) ->
+ erts_debug:set_internal_state(available_internal_state, true),
+ Config.
+
+end_per_suite(_Config) ->
+ catch erts_debug:set_internal_state(available_internal_state, false),
+ ok.
groups() ->
[{G, [], api_repeaters()} || G <- api_groups()]
@@ -114,7 +127,6 @@ groups() ->
monitor_process_d,
demonitor_process]}].
-
api_groups() -> [api_latest, api_2_4, api_2_0].
api_repeaters() -> [upgrade, resource_takeover, t_on_load].
@@ -485,91 +497,118 @@ t_on_load(Config) when is_list(Config) ->
-define(ERL_NIF_SELECT_READ, (1 bsl 0)).
-define(ERL_NIF_SELECT_WRITE, (1 bsl 1)).
-define(ERL_NIF_SELECT_STOP, (1 bsl 2)).
+-define(ERL_NIF_SELECT_CANCEL, (1 bsl 3)).
+-define(ERL_NIF_SELECT_CUSTOM_MSG, (1 bsl 4)).
-define(ERL_NIF_SELECT_STOP_CALLED, (1 bsl 0)).
-define(ERL_NIF_SELECT_STOP_SCHEDULED, (1 bsl 1)).
-define(ERL_NIF_SELECT_INVALID_EVENT, (1 bsl 2)).
-define(ERL_NIF_SELECT_FAILED, (1 bsl 3)).
-
+-define(ERL_NIF_SELECT_READ_CANCELLED, (1 bsl 4)).
+-define(ERL_NIF_SELECT_WRITE_CANCELLED, (1 bsl 5)).
select(Config) when is_list(Config) ->
ensure_lib_loaded(Config),
+ select_do(0, make_ref(), make_ref(), null),
+
+ RefBin = list_to_binary(lists:duplicate(100, $x)),
+ [select_do(?ERL_NIF_SELECT_CUSTOM_MSG,
+ small, {a, tuple, with, "some", RefBin}, MSG_ENV)
+ || MSG_ENV <- [null, alloc_env]],
+ ok.
+
+select_do(Flag, Ref, Ref2, MSG_ENV) ->
+ io:format("select_do(~p, ~p, ~p)\n", [Ref, Ref2, MSG_ENV]),
- Ref = make_ref(),
- Ref2 = make_ref(),
{{R, R_ptr}, {W, W_ptr}} = pipe_nif(),
ok = write_nif(W, <<"hej">>),
<<"hej">> = read_nif(R, 3),
%% Wait for read
eagain = read_nif(R, 3),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ bor Flag, R,null,Ref,MSG_ENV),
[] = flush(0),
ok = write_nif(W, <<"hej">>),
- [{select, R, Ref, ready_input}] = flush(),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
- [{select, R, Ref2, ready_input}] = flush(),
+ receive_ready(R, Ref, ready_input),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ bor Flag,R,self(),Ref2,MSG_ENV),
+ receive_ready(R, Ref2, ready_input),
Papa = self(),
Pid = spawn_link(fun() ->
- [{select, R, Ref, ready_input}] = flush(),
+ receive_ready(R, Ref, ready_input),
Papa ! {self(), done}
end),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Pid,Ref),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, Pid, Ref,MSG_ENV),
{Pid, done} = receive_any(1000),
+
+ %% Cancel read
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ bor ?ERL_NIF_SELECT_CANCEL,R,null,Ref,null),
<<"hej">> = read_nif(R, 3),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, null, Ref, MSG_ENV),
+ ?ERL_NIF_SELECT_READ_CANCELLED =
+ select_nif(R,?ERL_NIF_SELECT_READ bor ?ERL_NIF_SELECT_CANCEL,R,null,Ref,null),
+ ok = write_nif(W, <<"hej again">>),
+ [] = flush(0),
+ <<"hej again">> = read_nif(R, 9),
%% Wait for write
Written = write_full(W, $a),
- 0 = select_nif(W,?ERL_NIF_SELECT_WRITE,W,self(),Ref),
+ 0 = select_nif(W, ?ERL_NIF_SELECT_WRITE bor Flag, W, self(), Ref, MSG_ENV),
[] = flush(0),
Written = read_nif(R,byte_size(Written)),
- [{select, W, Ref, ready_output}] = flush(),
+ receive_ready(W, Ref, ready_output),
+
+ %% Cancel write
+ 0 = select_nif(W, ?ERL_NIF_SELECT_WRITE bor ?ERL_NIF_SELECT_CANCEL, W, null, Ref, null),
+ Written2 = write_full(W, $b),
+ 0 = select_nif(W, ?ERL_NIF_SELECT_WRITE bor Flag, W, null, Ref, MSG_ENV),
+ ?ERL_NIF_SELECT_WRITE_CANCELLED =
+ select_nif(W, ?ERL_NIF_SELECT_WRITE bor ?ERL_NIF_SELECT_CANCEL, W, null, Ref, null),
+ Written2 = read_nif(R,byte_size(Written2)),
+ [] = flush(0),
%% Close write and wait for EOF
eagain = read_nif(R, 1),
- check_stop_ret(select_nif(W,?ERL_NIF_SELECT_STOP,W,null,Ref)),
+ check_stop_ret(select_nif(W, ?ERL_NIF_SELECT_STOP, W, null, Ref, null)),
[{fd_resource_stop, W_ptr, _}] = flush(),
{1, {W_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(W),
[] = flush(0),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref),
- [{select, R, Ref, ready_input}] = flush(),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, self(), Ref, MSG_ENV),
+ receive_ready(R, Ref, ready_input),
eof = read_nif(R,1),
- check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref)),
+ check_stop_ret(select_nif(R, ?ERL_NIF_SELECT_STOP, R, null, Ref, null)),
[{fd_resource_stop, R_ptr, _}] = flush(),
{1, {R_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(R),
- select_2(Config).
+ select_2(Flag, Ref, Ref2, MSG_ENV).
-select_2(Config) ->
+select_2(Flag, Ref1, Ref2, MSG_ENV) ->
erlang:garbage_collect(),
{_,_,2} = last_resource_dtor_call(),
- Ref1 = make_ref(),
- Ref2 = make_ref(),
{{R, R_ptr}, {W, W_ptr}} = pipe_nif(),
%% Change ref
eagain = read_nif(R, 1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,self(),Ref2),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, null, Ref1, MSG_ENV),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, self(), Ref2, MSG_ENV),
[] = flush(0),
ok = write_nif(W, <<"hej">>),
- [{select, R, Ref2, ready_input}] = flush(),
+ receive_ready(R, Ref2, ready_input),
<<"hej">> = read_nif(R, 3),
%% Change pid
eagain = read_nif(R, 1),
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, null, Ref1, MSG_ENV),
Papa = self(),
spawn_link(fun() ->
- 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref1),
+ 0 = select_nif(R, ?ERL_NIF_SELECT_READ bor Flag, R, null, Ref1, MSG_ENV),
[] = flush(0),
Papa ! sync,
- [{select, R, Ref1, ready_input}] = flush(),
+ receive_ready(R, Ref1, ready_input),
<<"hej">> = read_nif(R, 3),
Papa ! done
end),
@@ -578,24 +617,30 @@ select_2(Config) ->
done = receive_any(),
[] = flush(0),
- check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref1)),
+ check_stop_ret(select_nif(R,?ERL_NIF_SELECT_STOP,R,null,Ref1, null)),
[{fd_resource_stop, R_ptr, _}] = flush(),
{1, {R_ptr,_}} = last_fd_stop_call(),
true = is_closed_nif(R),
%% Stop without previous read/write select
- ?ERL_NIF_SELECT_STOP_CALLED = select_nif(W,?ERL_NIF_SELECT_STOP,W,null,Ref1),
+ ?ERL_NIF_SELECT_STOP_CALLED = select_nif(W,?ERL_NIF_SELECT_STOP,W,null,Ref1,null),
[{fd_resource_stop, W_ptr, 1}] = flush(),
{1, {W_ptr,1}} = last_fd_stop_call(),
true = is_closed_nif(W),
- select_3(Config).
+ select_3().
-select_3(_Config) ->
+select_3() ->
erlang:garbage_collect(),
{_,_,2} = last_resource_dtor_call(),
ok.
+receive_ready(R, Ref, IOatom) when is_reference(Ref) ->
+ [{select, R, Ref, IOatom}] = flush();
+receive_ready(_, Msg, _) ->
+ [Got] = flush(),
+ {true,_,_} = {Got=:=Msg, Got, Msg}.
+
%% @doc The stealing child process for the select_steal test. Duplicates given
%% W/RFds and runs select on them to steal
select_steal_child_process(Parent, RFd) ->
@@ -604,7 +649,7 @@ select_steal_child_process(Parent, RFd) ->
Ref2 = make_ref(),
%% Try to select from the child pid (steal from parent)
- ?assertEqual(0, select_nif(R2Fd, ?ERL_NIF_SELECT_READ, R2Fd, null, Ref2)),
+ ?assertEqual(0, select_nif(R2Fd, ?ERL_NIF_SELECT_READ, R2Fd, null, Ref2, null)),
?assertEqual([], flush(0)),
?assertEqual(eagain, read_nif(R2Fd, 1)),
@@ -612,7 +657,7 @@ select_steal_child_process(Parent, RFd) ->
Parent ! {self(), stage1}, % signal parent to send the <<"stolen1">>
%% Receive <<"stolen1">> via enif_select
- ?assertEqual(0, select_nif(R2Fd, ?ERL_NIF_SELECT_READ, R2Fd, null, Ref2)),
+ ?assertEqual(0, select_nif(R2Fd, ?ERL_NIF_SELECT_READ, R2Fd, null, Ref2, null)),
?assertMatch([{select, R2Fd, Ref2, ready_input}], flush()),
?assertEqual(<<"stolen1">>, read_nif(R2Fd, 7)),
@@ -630,7 +675,7 @@ select_steal(Config) when is_list(Config) ->
{{RFd, RPtr}, {WFd, WPtr}} = pipe_nif(),
%% Bind the socket to current pid in enif_select
- ?assertEqual(0, select_nif(RFd, ?ERL_NIF_SELECT_READ, RFd, null, Ref)),
+ ?assertEqual(0, select_nif(RFd, ?ERL_NIF_SELECT_READ, RFd, null, Ref, null)),
?assertEqual([], flush(0)),
%% Spawn a process and do some stealing
@@ -644,15 +689,15 @@ select_steal(Config) when is_list(Config) ->
?assertMatch([{Pid, done}], flush(1)), % synchronize with the child
%% Try to select from the parent pid (steal back)
- ?assertEqual(0, select_nif(RFd, ?ERL_NIF_SELECT_READ, RFd, Pid, Ref)),
+ ?assertEqual(0, select_nif(RFd, ?ERL_NIF_SELECT_READ, RFd, Pid, Ref, null)),
%% Ensure that no data is hanging and close.
%% Rfd is stolen at this point.
- check_stop_ret(select_nif(WFd, ?ERL_NIF_SELECT_STOP, WFd, null, Ref)),
+ check_stop_ret(select_nif(WFd, ?ERL_NIF_SELECT_STOP, WFd, null, Ref, null)),
?assertMatch([{fd_resource_stop, WPtr, _}], flush()),
{1, {WPtr, 1}} = last_fd_stop_call(),
- check_stop_ret(select_nif(RFd, ?ERL_NIF_SELECT_STOP, RFd, null, Ref)),
+ check_stop_ret(select_nif(RFd, ?ERL_NIF_SELECT_STOP, RFd, null, Ref, null)),
?assertMatch([{fd_resource_stop, RPtr, _}], flush()),
{1, {RPtr, _DirectCall}} = last_fd_stop_call(),
@@ -789,8 +834,11 @@ demonitor_process(Config) ->
end),
R_ptr = alloc_monitor_resource_nif(),
{0,MonBin1} = monitor_process_nif(R_ptr, Pid, true, self()),
+ MonTerm1 = make_monitor_term_nif(MonBin1),
[R_ptr] = monitored_by(Pid),
{0,MonBin2} = monitor_process_nif(R_ptr, Pid, true, self()),
+ MonTerm2 = make_monitor_term_nif(MonBin2),
+ true = (MonTerm1 =/= MonTerm2),
[R_ptr, R_ptr] = monitored_by(Pid),
0 = demonitor_process_nif(R_ptr, MonBin1),
[R_ptr] = monitored_by(Pid),
@@ -804,6 +852,10 @@ demonitor_process(Config) ->
{R_ptr, _, 1} = last_resource_dtor_call(),
[] = monitored_by(Pid),
Pid ! return,
+
+ erlang:garbage_collect(),
+ true = (MonTerm1 =/= MonTerm2),
+ io:format("MonTerm1 = ~p\nMonTerm2 = ~p\n", [MonTerm1, MonTerm2]),
ok.
@@ -1179,7 +1231,7 @@ maps(Config) when is_list(Config) ->
repeat_while(fun({35,_}) -> false;
({K,Map}) ->
Map = maps_from_list_nif(maps:to_list(Map)),
- Map = maps:filter(fun(K,V) -> V =:= K*100 end, Map),
+ Map = maps:filter(fun(K2,V) -> V =:= K2*100 end, Map),
{K+1, maps:put(K,K*100,Map)}
end,
{1,#{}}),
@@ -1250,24 +1302,29 @@ resource_hugo_do(Type) ->
release_resource(HugoPtr),
erlang:garbage_collect(),
{HugoPtr,HugoBin} = get_resource(Type,Hugo),
- Pid = spawn_link(fun() ->
- receive {Pid, Type, Resource, Ptr, Bin} ->
- Pid ! {self(), got_it},
- receive {Pid, check_it} ->
- {Ptr,Bin} = get_resource(Type,Resource),
- Pid ! {self(), ok}
- end
- end
- end),
+ {Pid,_} =
+ spawn_monitor(fun() ->
+ receive {Pid, Type, Resource, Ptr, Bin} ->
+ Pid ! {self(), got_it},
+ receive {Pid, check_it} ->
+ {Ptr,Bin} = get_resource(Type,Resource)
+ end
+ end,
+ gc_and_exit(ok)
+ end),
Pid ! {self(), Type, Hugo, HugoPtr, HugoBin},
{Pid, got_it} = receive_any(),
erlang:garbage_collect(), % just to make our ProcBin move in memory
Pid ! {self(), check_it},
- {Pid, ok} = receive_any(),
+ {'DOWN', _, process, Pid, ok} = receive_any(),
[] = last_resource_dtor_call(),
{HugoPtr,HugoBin} = get_resource(Type,Hugo),
{HugoPtr, HugoBin, 1}.
+gc_and_exit(Reason) ->
+ erlang:garbage_collect(),
+ exit(Reason).
+
resource_otto(Type) ->
{OttoPtr, OttoBin} = resource_otto_do(Type),
erlang:garbage_collect(),
@@ -1344,14 +1401,14 @@ resource_binary_do() ->
ResInfo = {Ptr,_} = get_resource(binary_resource_type,ResBin1),
Papa = self(),
- Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ {Forwarder,_} = spawn_monitor(fun() -> forwarder(Papa) end),
io:format("sending to forwarder pid=~p\n",[Forwarder]),
Forwarder ! ResBin1,
ResBin2 = receive_any(),
ResBin2 = ResBin1,
ResInfo = get_resource(binary_resource_type,ResBin2),
Forwarder ! terminate,
- {Forwarder, 1} = receive_any(),
+ {'DOWN', _, process, Forwarder, 1} = receive_any(),
erlang:garbage_collect(),
ResInfo = get_resource(binary_resource_type,ResBin1),
ResInfo = get_resource(binary_resource_type,ResBin2),
@@ -1711,6 +1768,7 @@ read_resource(Type, {Holder,Id}) ->
forget_resource({Holder,Id}) ->
Holder ! {self(), forget, Id},
{Holder, forget_ok, Id} = receive_any(),
+ erts_debug:set_internal_state(wait, aux_work),
ok.
@@ -1871,11 +1929,11 @@ send2_do1(SendBlobF) ->
send2_do2(SendBlobF, self()),
Papa = self(),
- Forwarder = spawn_link(fun() -> forwarder(Papa) end),
+ {Forwarder,_} = spawn_monitor(fun() -> forwarder(Papa) end),
io:format("sending to forwarder pid=~p\n",[Forwarder]),
send2_do2(SendBlobF, Forwarder),
Forwarder ! terminate,
- {Forwarder, 4} = receive_any(),
+ {'DOWN', _, process, Forwarder, 4} = receive_any(),
ok.
send2_do2(SendBlobF, To) ->
@@ -1931,7 +1989,7 @@ forwarder(To) ->
forwarder(To, N) ->
case receive_any() of
terminate ->
- To ! {self(), N};
+ gc_and_exit(N);
Msg ->
To ! Msg,
forwarder(To, N+1)
@@ -3056,22 +3114,31 @@ nif_whereis_threaded(Config) when is_list(Config) ->
RegName = nif_whereis_test_threaded,
undefined = erlang:whereis(RegName),
- Ref = make_ref(),
- {Pid, Mon} = spawn_monitor(?MODULE, nif_whereis_proxy, [Ref]),
- true = register(RegName, Pid),
+ Self = self(),
+ true = register(RegName, Self),
- {ok, ProcThr} = whereis_thd_lookup(pid, RegName),
- {ok, Pid} = whereis_thd_result(ProcThr),
+ {ok, ProcThr} = whereis_thd_lookup(pid, RegName, "dtor to proc"),
+ {ok, Self} = whereis_thd_result(ProcThr),
- Pid ! {Ref, quit},
- ok = receive {'DOWN', Mon, process, Pid, normal} -> ok end,
+ nif_whereis_threaded_2(RegName).
+
+nif_whereis_threaded_2(RegName) ->
+ erlang:garbage_collect(),
+ "dtor to proc" = receive_any(1000),
+ true = unregister(RegName),
Port = open_port({spawn, echo_drv}, [eof]),
true = register(RegName, Port),
- {ok, PortThr} = whereis_thd_lookup(port, RegName),
+ {ok, PortThr} = whereis_thd_lookup(port, RegName, "dtor to port"),
{ok, Port} = whereis_thd_result(PortThr),
+ nif_whereis_threaded_3(Port).
+
+nif_whereis_threaded_3(Port) ->
+ erlang:garbage_collect(),
+ {Port, {data, "dtor to port"}} = receive_any(1000),
+
port_close(Port),
ok.
@@ -3327,6 +3394,69 @@ make_unaligned_binary(Bin0) ->
<<0:3,Bin:Size/binary,31:5>> = id(<<0:3,Bin0/binary,31:5>>),
Bin.
+pid(Config) ->
+ ensure_lib_loaded(Config),
+ Self = self(),
+ {true, ErlNifPid} = get_local_pid_nif(Self),
+ false = is_pid_undefined_nif(ErlNifPid),
+ Self = make_pid_nif(ErlNifPid),
+
+ UndefPid = set_pid_undefined_nif(),
+ true = is_pid_undefined_nif(UndefPid),
+ undefined = make_pid_nif(UndefPid),
+ 0 = send_term(UndefPid, message),
+
+ Other = spawn(fun() -> ok end),
+ {true,OtherNifPid} = get_local_pid_nif(Other),
+ Cmp = compare_pids_nif(ErlNifPid, OtherNifPid),
+ true = if Cmp < 0 -> Self < Other;
+ Cmp > 0 -> Self > Other
+ end,
+ 0 = compare_pids_nif(ErlNifPid, ErlNifPid),
+
+ {false, _} = get_local_pid_nif(undefined),
+ ok.
+
+nif_term_type(Config) ->
+ ensure_lib_loaded(Config),
+
+ atom = term_type_nif(atom),
+
+ bitstring = term_type_nif(<<1:1>>),
+ bitstring = term_type_nif(<<1:8>>),
+
+ float = term_type_nif(0.0),
+
+ 'fun' = term_type_nif(fun external:function/1),
+ 'fun' = term_type_nif(fun(A) -> A end),
+ 'fun' = term_type_nif(fun id/1),
+
+ integer = term_type_nif(1 bsl 1024), %Bignum.
+ integer = term_type_nif(1),
+
+ list = term_type_nif([list]),
+ list = term_type_nif([]),
+
+ LargeMap = maps:from_list([{N, N} || N <- lists:seq(1, 256)]),
+ map = term_type_nif(LargeMap),
+ map = term_type_nif(#{ small => map }),
+
+ pid = term_type_nif(self()),
+
+ Port = open_port({spawn,echo_drv},[eof]),
+ port = term_type_nif(Port),
+ port_close(Port),
+
+ reference = term_type_nif(make_ref()),
+
+ tuple = term_type_nif({}),
+
+ ok.
+
+last_resource_dtor_call() ->
+ erts_debug:set_internal_state(wait, aux_work),
+ last_resource_dtor_call_nif().
+
id(I) -> I.
%% The NIFs:
@@ -3354,7 +3484,7 @@ make_resource(_) -> ?nif_stub.
get_resource(_,_) -> ?nif_stub.
release_resource(_) -> ?nif_stub.
release_resource_from_thread(_) -> ?nif_stub.
-last_resource_dtor_call() -> ?nif_stub.
+last_resource_dtor_call_nif() -> ?nif_stub.
make_new_resource(_,_) -> ?nif_stub.
check_is(_,_,_,_,_,_,_,_,_,_,_) -> ?nif_stub.
check_is_exception() -> ?nif_stub.
@@ -3392,7 +3522,7 @@ term_to_binary_nif(_, _) -> ?nif_stub.
binary_to_term_nif(_, _, _) -> ?nif_stub.
port_command_nif(_, _) -> ?nif_stub.
format_term_nif(_,_) -> ?nif_stub.
-select_nif(_,_,_,_,_) -> ?nif_stub.
+select_nif(_,_,_,_,_,_) -> ?nif_stub.
dupe_resource_nif(_) -> ?nif_stub.
pipe_nif() -> ?nif_stub.
write_nif(_,_) -> ?nif_stub.
@@ -3404,6 +3534,7 @@ alloc_monitor_resource_nif() -> ?nif_stub.
monitor_process_nif(_,_,_,_) -> ?nif_stub.
demonitor_process_nif(_,_) -> ?nif_stub.
compare_monitors_nif(_,_) -> ?nif_stub.
+make_monitor_term_nif(_) -> ?nif_stub.
monitor_frenzy_nif(_,_,_,_) -> ?nif_stub.
ioq_nif(_) -> ?nif_stub.
ioq_nif(_,_) -> ?nif_stub.
@@ -3413,7 +3544,7 @@ ioq_nif(_,_,_,_) -> ?nif_stub.
%% whereis
whereis_send(_Type,_Name,_Msg) -> ?nif_stub.
whereis_term(_Type,_Name) -> ?nif_stub.
-whereis_thd_lookup(_Type,_Name) -> ?nif_stub.
+whereis_thd_lookup(_Type,_Name, _Msg) -> ?nif_stub.
whereis_thd_result(_Thd) -> ?nif_stub.
%% maps
@@ -3434,5 +3565,13 @@ convert_time_unit(_,_,_) -> ?nif_stub.
now_time() -> ?nif_stub.
cpu_time() -> ?nif_stub.
+get_local_pid_nif(_) -> ?nif_stub.
+make_pid_nif(_) -> ?nif_stub.
+set_pid_undefined_nif() -> ?nif_stub.
+is_pid_undefined_nif(_) -> ?nif_stub.
+compare_pids_nif(_, _) -> ?nif_stub.
+
+term_type_nif(_) -> ?nif_stub.
+
nif_stub_error(Line) ->
exit({nif_not_loaded,module,?MODULE,line,Line}).