Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Alias cleanup fix #6953

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions erts/emulator/beam/erl_bif_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -4266,6 +4266,16 @@ BIF_RETTYPE erts_debug_get_internal_state_1(BIF_ALIST_1)
BIF_RET(am_ok);
}
#endif
else if (ERTS_IS_ATOM_STR("pid_ref_table_size", BIF_ARG_1)) {
Uint size = erts_pid_ref_table_size();
if (IS_SSMALL(size))
BIF_RET(make_small(size));
else {
Uint hsz = BIG_UWORD_HEAP_SIZE(size);
Eterm *hp = HAlloc(BIF_P, hsz);
BIF_RET(uword_to_big(size, hp));
}
}
}
else if (is_tuple(BIF_ARG_1)) {
Eterm* tp = tuple_val(BIF_ARG_1);
Expand Down
21 changes: 21 additions & 0 deletions erts/emulator/beam/erl_bif_unique.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,6 +701,27 @@ init_pid_ref_tables(void)
}
}


Uint
erts_pid_ref_table_size(void)
{
int i;
Uint sz = 0;

for (i = 0; i <= erts_no_schedulers; i++) {
HashInfo hi;
ErtsPidRefTable *tblp = &pid_ref_table[i].u.table;
erts_rwmtx_rlock(&tblp->rwmtx);
hash_get_info(&hi, &tblp->hash);
erts_rwmtx_runlock(&tblp->rwmtx);
sz += (Uint) hi.objs;
}

return sz;
}



/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Unique Integer *
\* */
Expand Down
2 changes: 1 addition & 1 deletion erts/emulator/beam/erl_bif_unique.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ void erts_magic_ref_save_bin__(Eterm ref);
ErtsMagicBinary *erts_magic_ref_lookup_bin__(Uint32 refn[ERTS_REF_NUMBERS]);
void erts_pid_ref_delete(Eterm ref);
Eterm erts_pid_ref_lookup__(Uint32 refn[ERTS_REF_NUMBERS]);

Uint erts_pid_ref_table_size(void);

/* strict monotonic counter */

Expand Down
10 changes: 10 additions & 0 deletions erts/emulator/beam/erl_monitor_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -1095,6 +1095,16 @@ erts_monitor_destroy__(ErtsMonitorData *mdp)
|| ((mdp->origin.flags & ERTS_ML_FLGS_SAME)
== (mdp->u.target.flags & ERTS_ML_FLGS_SAME)));

if (mdp->origin.flags & ERTS_ML_STATE_ALIAS_MASK) {
ASSERT(mdp->origin.type == ERTS_MON_TYPE_ALIAS
|| mdp->origin.type == ERTS_MON_TYPE_PROC
|| mdp->origin.type == ERTS_MON_TYPE_PORT
|| mdp->origin.type == ERTS_MON_TYPE_TIME_OFFSET
|| mdp->origin.type == ERTS_MON_TYPE_DIST_PROC
|| mdp->origin.type == ERTS_MON_TYPE_DIST_PORT);
erts_pid_ref_delete(mdp->ref);
}

switch (mdp->origin.type) {
case ERTS_MON_TYPE_ALIAS:
ERTS_ML_ASSERT(!(mdp->origin.flags & ERTS_ML_FLG_TAG));
Expand Down
49 changes: 48 additions & 1 deletion erts/emulator/test/process_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
alias_bif/1,
monitor_alias/1,
spawn_monitor_alias/1,
alias_process_exit/1,
monitor_tag/1]).

-export([prio_server/2, prio_client/2, init/1, handle_event/2]).
Expand Down Expand Up @@ -180,7 +181,7 @@ groups() ->
gc_request_when_gc_disabled, gc_request_blast_when_gc_disabled,
otp_16436, otp_16642]},
{alias, [],
[alias_bif, monitor_alias, spawn_monitor_alias]}].
[alias_bif, monitor_alias, spawn_monitor_alias, alias_process_exit]}].

init_per_suite(Config) ->
A0 = case application:start(sasl) of
Expand All @@ -199,9 +200,15 @@ end_per_suite(Config) ->
catch erts_debug:set_internal_state(available_internal_state, false),
Config.

init_per_group(alias, Config) ->
erts_debug:set_internal_state(available_internal_state, true),
Config;
init_per_group(_GroupName, Config) ->
Config.

end_per_group(alias, Config) ->
erts_debug:set_internal_state(available_internal_state, false),
Config;
end_per_group(_GroupName, Config) ->
Config.

Expand Down Expand Up @@ -4575,11 +4582,25 @@ otp_16642(Config) when is_list(Config) ->
false = is_process_alive(Pid),
ok.

pid_ref_table_size() ->
erts_debug:get_internal_state(pid_ref_table_size).

check_pid_ref_table_size(PRTSz) ->
receive after 500 -> ok end,
case pid_ref_table_size() of
PRTSz ->
ok;
NewPRTSz ->
ct:fail({port_ref_table_size_mismatch, PRTSz, NewPRTSz})
end.

alias_bif(Config) when is_list(Config) ->
PRTSz = pid_ref_table_size(),
alias_bif_test(node()),
{ok, Peer, Node} = ?CT_PEER(),
alias_bif_test(Node),
stop_node(Peer, Node),
check_pid_ref_table_size(PRTSz),
ok.

alias_bif_test(Node) ->
Expand Down Expand Up @@ -4624,10 +4645,12 @@ alias_bif_test(Node) ->


monitor_alias(Config) when is_list(Config) ->
PRTSz = pid_ref_table_size(),
monitor_alias_test(node()),
{ok, Peer, Node} = ?CT_PEER(),
monitor_alias_test(Node),
stop_node(Peer, Node),
check_pid_ref_table_size(PRTSz),
ok.

monitor_alias_test(Node) ->
Expand Down Expand Up @@ -4711,6 +4734,7 @@ monitor_alias_test(Node) ->
spawn_monitor_alias(Config) when is_list(Config) ->
%% Exit signals with immediate exit reasons are sent
%% in a different manner than compound exit reasons.
PRTSz = pid_ref_table_size(),
spawn_monitor_alias_test(undefined, node(), spawn_opt, normal),
spawn_monitor_alias_test(undefined, node(), spawn_opt, make_ref()),
spawn_monitor_alias_test(undefined, node(), spawn_request, normal),
Expand All @@ -4723,6 +4747,7 @@ spawn_monitor_alias(Config) when is_list(Config) ->
spawn_monitor_alias_test(Peer3, Node3, spawn_request, normal),
{ok, Peer4, Node4} = ?CT_PEER(),
spawn_monitor_alias_test(Peer4, Node4, spawn_request, make_ref()),
check_pid_ref_table_size(PRTSz),
ok.

spawn_monitor_alias_test(Peer, Node, SpawnType, ExitReason) ->
Expand Down Expand Up @@ -4863,6 +4888,28 @@ spawn_monitor_alias_test(Peer, Node, SpawnType, ExitReason) ->
ok
end.

alias_process_exit(Config) when is_list(Config) ->
Tester = self(),
CreatedAliases = make_ref(),
PRTSz = pid_ref_table_size(),
P = spawn_link(fun () ->
A0 = alias([explicit_unalias]),
A1 = alias([reply]),
A2 = monitor(process, Tester, [{alias, explicit_unalias}]),
A3 = monitor(process, Tester, [{alias, demonitor}]),
A4 = monitor(process, Tester, [{alias, reply_demonitor}]),
Tester ! CreatedAliases,
receive after infinity -> ok end,
some_module:some_function([A0, A1, A2, A3, A4])
end),
receive CreatedAliases -> ok end,
PRTSz = erts_debug:get_internal_state(pid_ref_table_size) - 5,
unlink(P),
exit(P, kill),
false = is_process_alive(P),
check_pid_ref_table_size(PRTSz),
ok.

monitor_tag(Config) when is_list(Config) ->
%% Exit signals with immediate exit reasons are sent
%% in a different manner than compound exit reasons, and
Expand Down