aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/test')
-rw-r--r--erts/emulator/test/Makefile1
-rw-r--r--erts/emulator/test/alloc_SUITE.erl3
-rw-r--r--erts/emulator/test/call_trace_SUITE.erl2
-rw-r--r--erts/emulator/test/code_SUITE.erl26
-rw-r--r--erts/emulator/test/code_SUITE_data/literals.erl8
-rw-r--r--erts/emulator/test/driver_SUITE.erl19
-rw-r--r--erts/emulator/test/erts_debug_SUITE.erl31
-rw-r--r--erts/emulator/test/erts_test_utils.erl250
-rw-r--r--erts/emulator/test/fun_SUITE.erl16
-rw-r--r--erts/emulator/test/nif_SUITE.erl22
-rw-r--r--erts/emulator/test/node_container_SUITE.erl236
-rw-r--r--erts/emulator/test/process_SUITE.erl8
-rw-r--r--erts/emulator/test/smoke_test_SUITE.erl7
-rw-r--r--erts/emulator/test/system_info_SUITE.erl13
-rw-r--r--erts/emulator/test/timer_bif_SUITE.erl4
15 files changed, 378 insertions, 268 deletions
diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile
index 6a064ec8d4..b66cc1b2a3 100644
--- a/erts/emulator/test/Makefile
+++ b/erts/emulator/test/Makefile
@@ -130,6 +130,7 @@ MODULES= \
ignore_cores \
dgawd_handler \
random_iolist \
+ erts_test_utils \
crypto_reference
NO_OPT= bs_bincomp \
diff --git a/erts/emulator/test/alloc_SUITE.erl b/erts/emulator/test/alloc_SUITE.erl
index 343afe85e6..4e0243c1cd 100644
--- a/erts/emulator/test/alloc_SUITE.erl
+++ b/erts/emulator/test/alloc_SUITE.erl
@@ -71,7 +71,8 @@ migration(Cfg) ->
%% Disable driver_alloc to avoid recursive alloc_util calls
%% through enif_mutex_create() in my_creating_mbc().
drv_case(Cfg, concurrent, "+MZe true +MRe false"),
- drv_case(Cfg, concurrent, "+MZe true +MRe false +MZas ageffcbf").
+ drv_case(Cfg, concurrent, "+MZe true +MRe false +MZas ageffcbf"),
+ drv_case(Cfg, concurrent, "+MZe true +MRe false +MZas chaosff").
erts_mmap(Config) when is_list(Config) ->
case {os:type(), mmsc_flags()} of
diff --git a/erts/emulator/test/call_trace_SUITE.erl b/erts/emulator/test/call_trace_SUITE.erl
index d19f7f81ad..742592f88e 100644
--- a/erts/emulator/test/call_trace_SUITE.erl
+++ b/erts/emulator/test/call_trace_SUITE.erl
@@ -1395,7 +1395,7 @@ seq(M, N, R) when M =< N ->
seq(M, N-1, [N|R]);
seq(_, _, R) -> R.
-%% lists:reverse can not be called since it is traced
+%% lists:reverse cannot be called since it is traced
reverse(L) ->
reverse(L, []).
%%
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index 0444ba4f89..493c6ebe99 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -332,6 +332,7 @@ constant_pools(Config) when is_list(Config) ->
A = literals:a(),
B = literals:b(),
C = literals:huge_bignum(),
+ D = literals:funs(),
process_flag(trap_exit, true),
Self = self(),
@@ -345,7 +346,7 @@ constant_pools(Config) when is_list(Config) ->
true = erlang:purge_module(literals),
NoOldHeap ! done,
receive
- {'EXIT',NoOldHeap,{A,B,C}} ->
+ {'EXIT',NoOldHeap,{A,B,C,D}} ->
ok;
Other ->
ct:fail({unexpected,Other})
@@ -362,7 +363,7 @@ constant_pools(Config) when is_list(Config) ->
erlang:purge_module(literals),
OldHeap ! done,
receive
- {'EXIT',OldHeap,{A,B,C,[1,2,3|_]=Seq}} when length(Seq) =:= 16 ->
+ {'EXIT',OldHeap,{A,B,C,D,[1,2,3|_]=Seq}} when length(Seq) =:= 16 ->
ok
end,
@@ -390,7 +391,7 @@ constant_pools(Config) when is_list(Config) ->
{'DOWN', Mon, process, Hib, Reason} ->
{undef, [{no_module,
no_function,
- [{A,B,C,[1,2,3|_]=Seq}], _}]} = Reason,
+ [{A,B,C,D,[1,2,3|_]=Seq}], _}]} = Reason,
16 = length(Seq)
end,
HeapSz = TotHeapSz, %% Ensure restored to hibernated state...
@@ -400,7 +401,9 @@ constant_pools(Config) when is_list(Config) ->
no_old_heap(Parent) ->
A = literals:a(),
B = literals:b(),
- Res = {A,B,literals:huge_bignum()},
+ C = literals:huge_bignum(),
+ D = literals:funs(),
+ Res = {A,B,C,D},
Parent ! go,
receive
done ->
@@ -410,7 +413,9 @@ no_old_heap(Parent) ->
old_heap(Parent) ->
A = literals:a(),
B = literals:b(),
- Res = {A,B,literals:huge_bignum(),lists:seq(1, 16)},
+ C = literals:huge_bignum(),
+ D = literals:funs(),
+ Res = {A,B,C,D,lists:seq(1, 16)},
create_old_heap(),
Parent ! go,
receive
@@ -421,7 +426,9 @@ old_heap(Parent) ->
hibernated(Parent) ->
A = literals:a(),
B = literals:b(),
- Res = {A,B,literals:huge_bignum(),lists:seq(1, 16)},
+ C = literals:huge_bignum(),
+ D = literals:funs(),
+ Res = {A,B,C,D,lists:seq(1, 16)},
Parent ! go,
erlang:hibernate(no_module, no_function, [Res]).
@@ -755,7 +762,8 @@ t_copy_literals_frags(Config) when is_list(Config) ->
0, 1, 2, 3, 4, 5, 6, 7,
8, 9,10,11,12,13,14,15,
0, 1, 2, 3, 4, 5, 6, 7,
- 8, 9,10,11,12,13,14,15>>}]),
+ 8, 9,10,11,12,13,14,15>>},
+ {f, fun ?MODULE:all/0}]),
{module, ?mod} = erlang:load_module(?mod, Bin),
N = 6000,
@@ -796,6 +804,7 @@ literal_receiver() ->
C = ?mod:c(),
D = ?mod:d(),
E = ?mod:e(),
+ F = ?mod:f(),
literal_receiver();
{Pid, sender_confirm} ->
io:format("sender confirm ~w~n", [Pid]),
@@ -811,7 +820,8 @@ literal_sender(N, Recv) ->
?mod:b(),
?mod:c(),
?mod:d(),
- ?mod:e()]},
+ ?mod:e(),
+ ?mod:f()]},
literal_sender(N - 1, Recv).
literal_switcher() ->
diff --git a/erts/emulator/test/code_SUITE_data/literals.erl b/erts/emulator/test/code_SUITE_data/literals.erl
index 7c3b0ebe73..13c8b412b0 100644
--- a/erts/emulator/test/code_SUITE_data/literals.erl
+++ b/erts/emulator/test/code_SUITE_data/literals.erl
@@ -19,7 +19,8 @@
%%
-module(literals).
--export([a/0,b/0,huge_bignum/0,binary/0,unused_binaries/0,bits/0]).
+-export([a/0,b/0,huge_bignum/0,funs/0,
+ binary/0,unused_binaries/0,bits/0]).
-export([msg1/0,msg2/0,msg3/0,msg4/0,msg5/0]).
a() ->
@@ -108,3 +109,8 @@ msg2() -> {"hello","world"}.
msg3() -> <<"halloj">>.
msg4() -> #{ 1=> "hello", b => "world"}.
msg5() -> {1,2,3,4,5,6}.
+
+funs() ->
+ %% Literal funs (in a non-literal list).
+ [fun ?MODULE:a/0,
+ fun() -> ok end]. %No environment.
diff --git a/erts/emulator/test/driver_SUITE.erl b/erts/emulator/test/driver_SUITE.erl
index 6f5d639d04..9ffb484eb4 100644
--- a/erts/emulator/test/driver_SUITE.erl
+++ b/erts/emulator/test/driver_SUITE.erl
@@ -2645,24 +2645,7 @@ wait_deallocations() ->
driver_alloc_size() ->
wait_deallocations(),
- case erlang:system_info({allocator_sizes, driver_alloc}) of
- false ->
- undefined;
- MemInfo ->
- CS = lists:foldl(
- fun ({instance, _, L}, Acc) ->
- {value,{_,MBCS}} = lists:keysearch(mbcs, 1, L),
- {value,{_,SBCS}} = lists:keysearch(sbcs, 1, L),
- [MBCS,SBCS | Acc]
- end,
- [],
- MemInfo),
- lists:foldl(
- fun(L, Sz0) ->
- {value,{_,Sz,_,_}} = lists:keysearch(blocks_size, 1, L),
- Sz0+Sz
- end, 0, CS)
- end.
+ erts_debug:alloc_blocks_size(driver_alloc).
rpc(Config, Fun) ->
case proplists:get_value(node, Config) of
diff --git a/erts/emulator/test/erts_debug_SUITE.erl b/erts/emulator/test/erts_debug_SUITE.erl
index 6aa7a445b5..f39dbedd8f 100644
--- a/erts/emulator/test/erts_debug_SUITE.erl
+++ b/erts/emulator/test/erts_debug_SUITE.erl
@@ -22,8 +22,10 @@
-include_lib("common_test/include/ct.hrl").
-export([all/0, suite/0,
- test_size/1,flat_size_big/1,df/1,term_type/1,
- instructions/1, stack_check/1]).
+ test_size/1,flat_size_big/1,df/1,term_type/1,
+ instructions/1, stack_check/1, alloc_blocks_size/1]).
+
+-export([do_alloc_blocks_size/0]).
suite() ->
[{ct_hooks,[ts_install_cth]},
@@ -31,7 +33,7 @@ suite() ->
all() ->
[test_size, flat_size_big, df, instructions, term_type,
- stack_check].
+ stack_check, alloc_blocks_size].
test_size(Config) when is_list(Config) ->
ConsCell1 = id([a|b]),
@@ -210,5 +212,28 @@ instructions(Config) when is_list(Config) ->
_ = [list_to_atom(I) || I <- Is],
ok.
+alloc_blocks_size(Config) when is_list(Config) ->
+ F = fun(Args) ->
+ Node = start_slave(Args),
+ ok = rpc:call(Node, ?MODULE, do_alloc_blocks_size, []),
+ true = test_server:stop_node(Node)
+ end,
+ F("+Meamax"),
+ F("+Meamin"),
+ F(""),
+ ok.
+
+do_alloc_blocks_size() ->
+ _ = erts_debug:alloc_blocks_size(binary_alloc),
+ ok.
+
+start_slave(Args) ->
+ Name = ?MODULE_STRING ++ "_slave",
+ Pa = filename:dirname(code:which(?MODULE)),
+ {ok, Node} = test_server:start_node(list_to_atom(Name),
+ slave,
+ [{args, "-pa " ++ Pa ++ " " ++ Args}]),
+ Node.
+
id(I) ->
I.
diff --git a/erts/emulator/test/erts_test_utils.erl b/erts/emulator/test/erts_test_utils.erl
new file mode 100644
index 0000000000..ac2f2435be
--- /dev/null
+++ b/erts/emulator/test/erts_test_utils.erl
@@ -0,0 +1,250 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2002-2018. All Rights Reserved.
+%%
+%% Licensed under the Apache License, Version 2.0 (the "License");
+%% you may not use this file except in compliance with the License.
+%% You may obtain a copy of the License at
+%%
+%% http://www.apache.org/licenses/LICENSE-2.0
+%%
+%% Unless required by applicable law or agreed to in writing, software
+%% distributed under the License is distributed on an "AS IS" BASIS,
+%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+%% See the License for the specific language governing permissions and
+%% limitations under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(erts_test_utils).
+
+%%
+%% THIS MODULE IS ALSO USED BY *OTHER* APPLICATIONS TEST CODE
+%%
+
+-export([mk_ext_pid/3,
+ mk_ext_port/2,
+ mk_ext_ref/2,
+ check_node_dist/0, check_node_dist/1, check_node_dist/3]).
+
+
+
+-define(VERSION_MAGIC, 131).
+
+-define(ATOM_EXT, 100).
+-define(REFERENCE_EXT, 101).
+-define(PORT_EXT, 102).
+-define(PID_EXT, 103).
+-define(NEW_REFERENCE_EXT, 114).
+-define(NEW_PID_EXT, $X).
+-define(NEW_PORT_EXT, $Y).
+-define(NEWER_REFERENCE_EXT, $Z).
+
+uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 ->
+ [(Uint bsr 24) band 16#ff,
+ (Uint bsr 16) band 16#ff,
+ (Uint bsr 8) band 16#ff,
+ Uint band 16#ff];
+uint32_be(Uint) ->
+ exit({badarg, uint32_be, [Uint]}).
+
+
+uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 ->
+ [(Uint bsr 8) band 16#ff,
+ Uint band 16#ff];
+uint16_be(Uint) ->
+ exit({badarg, uint16_be, [Uint]}).
+
+uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 ->
+ Uint band 16#ff;
+uint8(Uint) ->
+ exit({badarg, uint8, [Uint]}).
+
+pid_tag(bad_creation) -> ?PID_EXT;
+pid_tag(Creation) when Creation =< 3 -> ?PID_EXT;
+pid_tag(_Creation) -> ?NEW_PID_EXT.
+
+enc_creation(bad_creation) -> uint8(4);
+enc_creation(Creation) when Creation =< 3 -> uint8(Creation);
+enc_creation(Creation) -> uint32_be(Creation).
+
+mk_ext_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) ->
+ mk_ext_pid({atom_to_list(NodeName), Creation}, Number, Serial);
+mk_ext_pid({NodeName, Creation}, Number, Serial) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ pid_tag(Creation),
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint32_be(Number),
+ uint32_be(Serial),
+ enc_creation(Creation)])) of
+ Pid when is_pid(Pid) ->
+ Pid;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
+port_tag(bad_creation) -> ?PORT_EXT;
+port_tag(Creation) when Creation =< 3 -> ?PORT_EXT;
+port_tag(_Creation) -> ?NEW_PORT_EXT.
+
+mk_ext_port({NodeName, Creation}, Number) when is_atom(NodeName) ->
+ mk_ext_port({atom_to_list(NodeName), Creation}, Number);
+mk_ext_port({NodeName, Creation}, Number) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ port_tag(Creation),
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint32_be(Number),
+ enc_creation(Creation)])) of
+ Port when is_port(Port) ->
+ Port;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_port, [{NodeName, Creation}, Number]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
+ref_tag(bad_creation) -> ?NEW_REFERENCE_EXT;
+ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT;
+ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT.
+
+mk_ext_ref({NodeName, Creation}, Numbers) when is_atom(NodeName),
+ is_list(Numbers) ->
+ mk_ext_ref({atom_to_list(NodeName), Creation}, Numbers);
+mk_ext_ref({NodeName, Creation}, [Number]) when is_list(NodeName),
+ Creation =< 3,
+ is_integer(Number) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ?REFERENCE_EXT,
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ uint32_be(Number),
+ uint8(Creation)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end;
+mk_ext_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
+ is_list(Numbers) ->
+ case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
+ ref_tag(Creation),
+ uint16_be(length(Numbers)),
+ ?ATOM_EXT,
+ uint16_be(length(NodeName)),
+ NodeName,
+ enc_creation(Creation),
+ lists:map(fun (N) ->
+ uint32_be(N)
+ end,
+ Numbers)])) of
+ Ref when is_reference(Ref) ->
+ Ref;
+ {'EXIT', {badarg, _}} ->
+ exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]});
+ Other ->
+ exit({unexpected_binary_to_term_result, Other})
+ end.
+
+
+
+%%
+%% Check reference counters for node- and dist entries.
+%%
+check_node_dist() ->
+ check_node_dist(fun(ErrMsg) ->
+ io:format("check_node_dist ERROR:\n~p\n", [ErrMsg]),
+ error
+ end).
+
+check_node_dist(Fail) ->
+ {{node_references, NodeRefs},
+ {dist_references, DistRefs}} =
+ erts_debug:get_internal_state(node_and_dist_references),
+ check_node_dist(Fail, NodeRefs, DistRefs).
+
+
+
+check_node_dist(Fail, NodeRefs, DistRefs) ->
+ check_nd_refc({node(),erlang:system_info(creation)},
+ NodeRefs, DistRefs, Fail).
+
+
+check_nd_refc({ThisNodeName, ThisCreation}, NodeRefs, DistRefs, Fail) ->
+ case catch begin
+ check_refc(ThisNodeName,ThisCreation,"node table",NodeRefs),
+ check_refc(ThisNodeName,ThisCreation,"dist table",DistRefs),
+ ok
+ end of
+ ok ->
+ ok;
+ {'EXIT', Reason} ->
+ {Y,Mo,D} = date(),
+ {H,Mi,S} = time(),
+ ErrMsg = io_lib:format("~n"
+ "*** Reference count check of node ~w "
+ "failed (~p) at ~w~w~w ~w:~w:~w~n"
+ "*** Node table references:~n ~p~n"
+ "*** Dist table references:~n ~p~n",
+ [node(), Reason, Y, Mo, D, H, Mi, S,
+ NodeRefs, DistRefs]),
+ Fail(lists:flatten(ErrMsg))
+ end.
+
+
+check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) ->
+ lists:foreach(
+ fun ({Entry, Refc, ReferrerList}) ->
+ {DelayedDeleteTimer,
+ FoundRefs} =
+ lists:foldl(
+ fun ({Referrer, ReferencesList}, {DDT, A1}) ->
+ {case Referrer of
+ {system,delayed_delete_timer} ->
+ true;
+ {system,thread_progress_delete_timer} ->
+ true;
+ _ ->
+ DDT
+ end,
+ A1 + lists:foldl(fun ({_T,Rs},A2) ->
+ A2+Rs
+ end,
+ 0,
+ ReferencesList)}
+ end,
+ {false, 0},
+ ReferrerList),
+
+ %% Reference count equals found references?
+ case {Refc, FoundRefs, DelayedDeleteTimer} of
+ {X, X, _} ->
+ ok;
+ {0, 1, true} ->
+ ok;
+ _ ->
+ exit({invalid_reference_count, Table, Entry})
+ end,
+
+ %% All entries in table referred to?
+ case {Entry, Refc} of
+ {ThisNodeName, 0} -> ok;
+ {{ThisNodeName, ThisCreation}, 0} -> ok;
+ {_, 0} when DelayedDeleteTimer == false ->
+ exit({not_referred_entry_in_table, Table, Entry});
+ {_, _} -> ok
+ end
+
+ end,
+ EntryList),
+ ok.
diff --git a/erts/emulator/test/fun_SUITE.erl b/erts/emulator/test/fun_SUITE.erl
index 73fe9b0d8f..f8a879182e 100644
--- a/erts/emulator/test/fun_SUITE.erl
+++ b/erts/emulator/test/fun_SUITE.erl
@@ -576,7 +576,7 @@ refc_dist(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Pid = spawn_link(Node, fun() -> receive
Fun when is_function(Fun) ->
- 2 = fun_refc(Fun),
+ 3 = fun_refc(Fun),
exit({normal,Fun}) end
end),
F = fun() -> 42 end,
@@ -598,7 +598,7 @@ refc_dist_send(Node, F) ->
Pid = spawn_link(Node, fun() -> receive
{To,Fun} when is_function(Fun) ->
wait_until(fun () ->
- 2 =:= fun_refc(Fun)
+ 3 =:= fun_refc(Fun)
end),
To ! Fun
end
@@ -626,7 +626,7 @@ refc_dist_reg_send(Node, F) ->
Me ! Ref,
receive
{Me,Fun} when is_function(Fun) ->
- 2 = fun_refc(Fun),
+ 3 = fun_refc(Fun),
Me ! Fun
end
end),
@@ -806,11 +806,13 @@ verify_not_undef(Fun, Tag) ->
ct:fail("tag ~w not defined in fun_info", [Tag]);
{Tag,_} -> ok
end.
-
+
id(X) ->
X.
spawn_call(Node, AFun) ->
+ Parent = self(),
+ Init = erlang:whereis(init),
Pid = spawn_link(Node,
fun() ->
receive
@@ -821,8 +823,10 @@ spawn_call(Node, AFun) ->
_ -> lists:seq(0, Arity-1)
end,
Res = apply(Fun, Args),
- {pid,Creator} = erlang:fun_info(Fun, pid),
- Creator ! {result,Res}
+ case erlang:fun_info(Fun, pid) of
+ {pid,Init} -> Parent ! {result,Res};
+ {pid,Creator} -> Creator ! {result,Res}
+ end
end
end),
Pid ! {AFun,AFun,AFun},
diff --git a/erts/emulator/test/nif_SUITE.erl b/erts/emulator/test/nif_SUITE.erl
index a2f3489943..edad62a9fb 100644
--- a/erts/emulator/test/nif_SUITE.erl
+++ b/erts/emulator/test/nif_SUITE.erl
@@ -485,12 +485,14 @@ 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_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),
@@ -516,7 +518,16 @@ select(Config) when is_list(Config) ->
end),
0 = select_nif(R,?ERL_NIF_SELECT_READ,R,Pid,Ref),
{Pid, done} = receive_any(1000),
+
+ %% Cancel read
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ bor ?ERL_NIF_SELECT_CANCEL,R,null,Ref),
<<"hej">> = read_nif(R, 3),
+ 0 = select_nif(R,?ERL_NIF_SELECT_READ,R,null,Ref),
+ ?ERL_NIF_SELECT_READ_CANCELLED =
+ select_nif(R,?ERL_NIF_SELECT_READ bor ?ERL_NIF_SELECT_CANCEL,R,null,Ref),
+ ok = write_nif(W, <<"hej again">>),
+ [] = flush(0),
+ <<"hej again">> = read_nif(R, 9),
%% Wait for write
Written = write_full(W, $a),
@@ -525,6 +536,15 @@ select(Config) when is_list(Config) ->
Written = read_nif(R,byte_size(Written)),
[{select, W, Ref, ready_output}] = flush(),
+ %% Cancel write
+ 0 = select_nif(W,?ERL_NIF_SELECT_WRITE bor ?ERL_NIF_SELECT_CANCEL,W,null,Ref),
+ Written2 = write_full(W, $b),
+ 0 = select_nif(W,?ERL_NIF_SELECT_WRITE,W,null,Ref),
+ ?ERL_NIF_SELECT_WRITE_CANCELLED =
+ select_nif(W,?ERL_NIF_SELECT_WRITE bor ?ERL_NIF_SELECT_CANCEL,W,null,Ref),
+ 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)),
diff --git a/erts/emulator/test/node_container_SUITE.erl b/erts/emulator/test/node_container_SUITE.erl
index 300b4ed036..b3d8f9584d 100644
--- a/erts/emulator/test/node_container_SUITE.erl
+++ b/erts/emulator/test/node_container_SUITE.erl
@@ -938,15 +938,11 @@ nc_refc_check(Node) when is_atom(Node) ->
io:format("Starting reference count check of node ~w~n", [Node]),
spawn_link(Node,
fun () ->
- {{node_references, NodeRefs},
- {dist_references, DistRefs}} = ?ND_REFS,
- check_nd_refc({node(), erlang:system_info(creation)},
- NodeRefs,
- DistRefs,
- fun (ErrMsg) ->
- Self ! {Ref, ErrMsg, failed},
- exit(normal)
- end),
+ erts_test_utils:check_node_dist(
+ fun (ErrMsg) ->
+ Self ! {Ref, ErrMsg, failed},
+ exit(normal)
+ end),
Self ! {Ref, succeded}
end),
receive
@@ -958,98 +954,26 @@ nc_refc_check(Node) when is_atom(Node) ->
ok
end.
-check_nd_refc({ThisNodeName, ThisCreation}, NodeRefs, DistRefs, Fail) ->
- case catch begin
- check_refc(ThisNodeName,ThisCreation,"node table",NodeRefs),
- check_refc(ThisNodeName,ThisCreation,"dist table",DistRefs),
- ok
- end of
- ok ->
- ok;
- {'EXIT', Reason} ->
- {Y,Mo,D} = date(),
- {H,Mi,S} = time(),
- ErrMsg = io_lib:format("~n"
- "*** Reference count check of node ~w "
- "failed (~p) at ~w~w~w ~w:~w:~w~n"
- "*** Node table references:~n ~p~n"
- "*** Dist table references:~n ~p~n",
- [node(), Reason, Y, Mo, D, H, Mi, S,
- NodeRefs, DistRefs]),
- Fail(lists:flatten(ErrMsg))
- end.
-
-
-check_refc(ThisNodeName,ThisCreation,Table,EntryList) when is_list(EntryList) ->
- lists:foreach(
- fun ({Entry, Refc, ReferrerList}) ->
- {DelayedDeleteTimer,
- FoundRefs} =
- lists:foldl(
- fun ({Referrer, ReferencesList}, {DDT, A1}) ->
- {case Referrer of
- {system,delayed_delete_timer} ->
- true;
- {system,thread_progress_delete_timer} ->
- true;
- _ ->
- DDT
- end,
- A1 + lists:foldl(fun ({_T,Rs},A2) ->
- A2+Rs
- end,
- 0,
- ReferencesList)}
- end,
- {false, 0},
- ReferrerList),
-
- %% Reference count equals found references?
- case {Refc, FoundRefs, DelayedDeleteTimer} of
- {X, X, _} ->
- ok;
- {0, 1, true} ->
- ok;
- _ ->
- exit({invalid_reference_count, Table, Entry})
- end,
-
- %% All entries in table referred to?
- case {Entry, Refc} of
- {ThisNodeName, 0} -> ok;
- {{ThisNodeName, ThisCreation}, 0} -> ok;
- {_, 0} when DelayedDeleteTimer == false ->
- exit({not_referred_entry_in_table, Table, Entry});
- {_, _} -> ok
- end
-
- end,
- EntryList),
- ok.
-
get_node_references({NodeName, Creation} = Node) when is_atom(NodeName),
is_integer(Creation) ->
{{node_references, NodeRefs},
{dist_references, DistRefs}} = ?ND_REFS,
- check_nd_refc({node(), erlang:system_info(creation)},
- NodeRefs,
- DistRefs,
- fun (ErrMsg) ->
- io:format("~s", [ErrMsg]),
- ct:fail(reference_count_check_failed)
- end),
+ erts_test_utils:check_node_dist(
+ fun (ErrMsg) ->
+ io:format("~s", [ErrMsg]),
+ ct:fail(reference_count_check_failed)
+ end,
+ NodeRefs, DistRefs),
find_references(Node, NodeRefs).
get_dist_references(NodeName) when is_atom(NodeName) ->
{{node_references, NodeRefs},
{dist_references, DistRefs}} = ?ND_REFS,
- check_nd_refc({node(), erlang:system_info(creation)},
- NodeRefs,
- DistRefs,
- fun (ErrMsg) ->
- io:format("~s", [ErrMsg]),
- ct:fail(reference_count_check_failed)
- end),
+ erts_test_utils:check_node_dist(fun (ErrMsg) ->
+ io:format("~s", [ErrMsg]),
+ ct:fail(reference_count_check_failed)
+ end,
+ NodeRefs, DistRefs),
find_references(NodeName, DistRefs).
find_references(N, NRefList) ->
@@ -1138,133 +1062,15 @@ get_nodename() ->
++ "@"
++ hostname()).
-
-
--define(VERSION_MAGIC, 131).
-
--define(ATOM_EXT, 100).
--define(REFERENCE_EXT, 101).
--define(PORT_EXT, 102).
--define(PID_EXT, 103).
--define(NEW_REFERENCE_EXT, 114).
--define(NEW_PID_EXT, $X).
--define(NEW_PORT_EXT, $Y).
--define(NEWER_REFERENCE_EXT, $Z).
-
-uint32_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 32 ->
- [(Uint bsr 24) band 16#ff,
- (Uint bsr 16) band 16#ff,
- (Uint bsr 8) band 16#ff,
- Uint band 16#ff];
-uint32_be(Uint) ->
- exit({badarg, uint32_be, [Uint]}).
-
-
-uint16_be(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 16 ->
- [(Uint bsr 8) band 16#ff,
- Uint band 16#ff];
-uint16_be(Uint) ->
- exit({badarg, uint16_be, [Uint]}).
-
-uint8(Uint) when is_integer(Uint), 0 =< Uint, Uint < 1 bsl 8 ->
- Uint band 16#ff;
-uint8(Uint) ->
- exit({badarg, uint8, [Uint]}).
-
-
-pid_tag(bad_creation) -> ?PID_EXT;
-pid_tag(Creation) when Creation =< 3 -> ?PID_EXT;
-pid_tag(_Creation) -> ?NEW_PID_EXT.
-
-enc_creation(bad_creation) -> uint8(4);
-enc_creation(Creation) when Creation =< 3 -> uint8(Creation);
-enc_creation(Creation) -> uint32_be(Creation).
-
-mk_pid({NodeName, Creation}, Number, Serial) when is_atom(NodeName) ->
- mk_pid({atom_to_list(NodeName), Creation}, Number, Serial);
mk_pid({NodeName, Creation}, Number, Serial) ->
- case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
- pid_tag(Creation),
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
- uint32_be(Number),
- uint32_be(Serial),
- enc_creation(Creation)])) of
- Pid when is_pid(Pid) ->
- Pid;
- {'EXIT', {badarg, _}} ->
- exit({badarg, mk_pid, [{NodeName, Creation}, Number, Serial]});
- Other ->
- exit({unexpected_binary_to_term_result, Other})
- end.
-
-port_tag(bad_creation) -> ?PORT_EXT;
-port_tag(Creation) when Creation =< 3 -> ?PORT_EXT;
-port_tag(_Creation) -> ?NEW_PORT_EXT.
+ erts_test_utils:mk_ext_pid({NodeName, Creation}, Number, Serial).
-mk_port({NodeName, Creation}, Number) when is_atom(NodeName) ->
- mk_port({atom_to_list(NodeName), Creation}, Number);
mk_port({NodeName, Creation}, Number) ->
- case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
- port_tag(Creation),
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
- uint32_be(Number),
- enc_creation(Creation)])) of
- Port when is_port(Port) ->
- Port;
- {'EXIT', {badarg, _}} ->
- exit({badarg, mk_port, [{NodeName, Creation}, Number]});
- Other ->
- exit({unexpected_binary_to_term_result, Other})
- end.
+ erts_test_utils:mk_ext_port({NodeName, Creation}, Number).
+
+mk_ref({NodeName, Creation}, Numbers) ->
+ erts_test_utils:mk_ext_ref({NodeName, Creation}, Numbers).
-ref_tag(bad_creation) -> ?NEW_REFERENCE_EXT;
-ref_tag(Creation) when Creation =< 3 -> ?NEW_REFERENCE_EXT;
-ref_tag(_Creation) -> ?NEWER_REFERENCE_EXT.
-
-mk_ref({NodeName, Creation}, Numbers) when is_atom(NodeName),
- is_list(Numbers) ->
- mk_ref({atom_to_list(NodeName), Creation}, Numbers);
-mk_ref({NodeName, Creation}, [Number]) when is_list(NodeName),
- Creation =< 3,
- is_integer(Number) ->
- case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
- ?REFERENCE_EXT,
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
- uint32_be(Number),
- uint8(Creation)])) of
- Ref when is_reference(Ref) ->
- Ref;
- {'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, [Number]]});
- Other ->
- exit({unexpected_binary_to_term_result, Other})
- end;
-mk_ref({NodeName, Creation}, Numbers) when is_list(NodeName),
- is_list(Numbers) ->
- case catch binary_to_term(list_to_binary([?VERSION_MAGIC,
- ref_tag(Creation),
- uint16_be(length(Numbers)),
- ?ATOM_EXT,
- uint16_be(length(NodeName)),
- NodeName,
- enc_creation(Creation),
- lists:map(fun (N) ->
- uint32_be(N)
- end,
- Numbers)])) of
- Ref when is_reference(Ref) ->
- Ref;
- {'EXIT', {badarg, _}} ->
- exit({badarg, mk_ref, [{NodeName, Creation}, Numbers]});
- Other ->
- exit({unexpected_binary_to_term_result, Other})
- end.
exec_loop() ->
receive
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 57eb082d64..f4b1d885fe 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -2233,8 +2233,8 @@ processes_term_proc_list(Config) when is_list(Config) ->
%% We have to run this test case with +S1 since instrument:allocations()
%% will report a free()'d block as present until it's actually deallocated
%% by its employer.
- Run("+MSe true +MSatags false +S1"),
- Run("+MSe true +MSatags true +S1"),
+ Run("+MSe true +Muatags false +S1"),
+ Run("+MSe true +Muatags true +S1"),
ok.
@@ -2242,10 +2242,12 @@ processes_term_proc_list(Config) when is_list(Config) ->
chk_term_proc_list(?LINE, MC, XB)).
chk_term_proc_list(Line, MustChk, ExpectBlks) ->
- Allocs = instrument:allocations(#{ allocator_types => [sl_alloc] }),
+ Allocs = instrument:allocations(),
case {MustChk, Allocs} of
{false, {error, not_enabled}} ->
not_enabled;
+ {false, {ok, {_Shift, _Unscanned, ByOrigin}}} when ByOrigin =:= #{} ->
+ not_enabled;
{_, {ok, {_Shift, _Unscanned, ByOrigin}}} ->
ByType = maps:get(system, ByOrigin, #{}),
Hist = maps:get(ptab_list_deleted_el, ByType, {}),
diff --git a/erts/emulator/test/smoke_test_SUITE.erl b/erts/emulator/test/smoke_test_SUITE.erl
index 26c610e3a8..5b46342127 100644
--- a/erts/emulator/test/smoke_test_SUITE.erl
+++ b/erts/emulator/test/smoke_test_SUITE.erl
@@ -56,7 +56,7 @@ end_per_testcase(_Case, Config) when is_list(Config) ->
%%%
boot_combo(Config) when is_list(Config) ->
- ZFlags = os:getenv("ERL_ZFLAGS"),
+ ZFlags = os:getenv("ERL_ZFLAGS", ""),
NOOP = fun () -> ok end,
A42 = fun () ->
case erlang:system_info(threads) of
@@ -87,10 +87,7 @@ boot_combo(Config) when is_list(Config) ->
%% A lot more combos could be implemented...
ok
after
- os:putenv("ERL_ZFLAGS", case ZFlags of
- false -> "";
- _ -> ZFlags
- end)
+ os:putenv("ERL_ZFLAGS", ZFlags)
end.
native_atomics(Config) when is_list(Config) ->
diff --git a/erts/emulator/test/system_info_SUITE.erl b/erts/emulator/test/system_info_SUITE.erl
index 21ab6b378a..8ea2d88ec4 100644
--- a/erts/emulator/test/system_info_SUITE.erl
+++ b/erts/emulator/test/system_info_SUITE.erl
@@ -457,11 +457,16 @@ cmp_memory(MWs, Str) ->
%% Total, processes, processes_used, and system will seldom
%% give us exactly the same result since the two readings
%% aren't taken atomically.
+ %%
+ %% Torerance is scaled according to the number of schedulers
+ %% to match spawn_mem_workers.
+
+ Tolerance = 1.05 + 0.01 * erlang:system_info(schedulers_online),
- cmp_memory(total, EM, EDM, 1.05),
- cmp_memory(processes, EM, EDM, 1.05),
- cmp_memory(processes_used, EM, EDM, 1.05),
- cmp_memory(system, EM, EDM, 1.05),
+ cmp_memory(total, EM, EDM, Tolerance),
+ cmp_memory(processes, EM, EDM, Tolerance),
+ cmp_memory(processes_used, EM, EDM, Tolerance),
+ cmp_memory(system, EM, EDM, Tolerance),
ok.
diff --git a/erts/emulator/test/timer_bif_SUITE.erl b/erts/emulator/test/timer_bif_SUITE.erl
index fc11a04a31..15fe13c8c0 100644
--- a/erts/emulator/test/timer_bif_SUITE.erl
+++ b/erts/emulator/test/timer_bif_SUITE.erl
@@ -361,7 +361,7 @@ evil_timers(Config) when is_list(Config) ->
%%
%% 1. A timer started with erlang:start_timer(Time, Receiver, Msg),
%% where Msg is a composite term, expires, and the receivers main
- %% lock *can not* be acquired immediately (typically when the
+ %% lock *cannot* be acquired immediately (typically when the
%% receiver *is* running).
%%
%% The wrap tuple ({timeout, TRef, Msg}) will in this case
@@ -372,7 +372,7 @@ evil_timers(Config) when is_list(Config) ->
RecvTimeOutMsgs0 = evil_recv_timeouts(200),
%% 2. A timer started with erlang:start_timer(Time, Receiver, Msg),
%% where Msg is an immediate term, expires, and the receivers main
- %% lock *can not* be acquired immediately (typically when the
+ %% lock *cannot* be acquired immediately (typically when the
%% receiver *is* running).
%%
%% The wrap tuple will in this case be allocated in a new