Skip to content

Commit

Permalink
Merge branch 'sverker/process_info-reductions-fix/OTP-15709' into mai…
Browse files Browse the repository at this point in the history
…nt-21

* sverker/process_info-reductions-fix/OTP-15709:
  erts: Fix bug in process_info(reductions)
  erts: Use ptr_val for pointer in gc msg copy
  • Loading branch information
Erlang/OTP committed Mar 29, 2019
2 parents 370f7dc + 2c8e684 commit 78b55ab
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
15 changes: 9 additions & 6 deletions erts/emulator/beam/beam_emu.c
Original file line number Diff line number Diff line change
Expand Up @@ -3261,20 +3261,23 @@ erts_is_builtin(Eterm Mod, Eterm Name, int arity)


/*
* Return the current number of reductions for the given process.
* Return the current number of reductions consumed by the given process.
* To get the total number of reductions, p->reds must be added.
*/

Uint
erts_current_reductions(Process *current, Process *p)
erts_current_reductions(Process *c_p, Process *p)
{
if (current != p) {
Sint reds_left;
if (c_p != p || !(erts_atomic32_read_nob(&c_p->state)
& ERTS_PSFLG_RUNNING)) {
return 0;
} else if (current->fcalls < 0 && ERTS_PROC_GET_SAVED_CALLS_BUF(current)) {
return current->fcalls + CONTEXT_REDS;
} else if (c_p->fcalls < 0 && ERTS_PROC_GET_SAVED_CALLS_BUF(c_p)) {
reds_left = c_p->fcalls + CONTEXT_REDS;
} else {
return REDS_IN(current) - current->fcalls;
reds_left = c_p->fcalls;
}
return REDS_IN(c_p) - reds_left;
}

int
Expand Down
1 change: 1 addition & 0 deletions erts/emulator/beam/msg_instrs.tab
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ i_loop_rec(Dest) {
$SET_CP_I_ABS(I);
c_p->arity = 0;
c_p->current = NULL;
c_p->fcalls = FCALLS;
FCALLS -= erts_proc_sig_receive_helper(c_p, FCALLS, neg_o_reds,
&msgp, &get_out);
SWAPIN;
Expand Down
42 changes: 42 additions & 0 deletions erts/emulator/test/process_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
process_info_garbage_collection/1,
process_info_smoke_all/1,
process_info_status_handled_signal/1,
process_info_reductions/1,
bump_reductions/1, low_prio/1, binary_owner/1, yield/1, yield2/1,
otp_4725/1, bad_register/1, garbage_collect/1, otp_6237/1,
process_info_messages/1, process_flag_badarg/1, process_flag_heap_size/1,
Expand Down Expand Up @@ -84,6 +85,7 @@ all() ->
process_info_garbage_collection,
process_info_smoke_all,
process_info_status_handled_signal,
process_info_reductions,
bump_reductions, low_prio, yield, yield2, otp_4725,
bad_register, garbage_collect, process_info_messages,
process_flag_badarg, process_flag_heap_size,
Expand Down Expand Up @@ -1084,6 +1086,46 @@ process_info_status_handled_signal(Config) when is_list(Config) ->
false = erlang:is_process_alive(P),
ok.

%% OTP-15709
%% Provoke a bug where process_info(reductions) returned wrong result
%% because REDS_IN (def_arg_reg[5]) is read when the process in not running.
process_info_reductions(Config) when is_list(Config) ->
pi_reductions_tester(spawn_link(fun() -> pi_reductions_spinnloop() end)),
pi_reductions_tester(spawn_link(fun() -> pi_reductions_recvloop() end)),
ok.

pi_reductions_tester(Pid) ->
{_, DiffList} =
lists:foldl(fun(_, {Prev, Acc}) ->
%% Add another item that force sending the request
%% as a signal, like 'current_function'.
PI = process_info(Pid, [reductions, current_function]),
[{reductions,Reds}, {current_function,_}] = PI,
Diff = Reds - Prev,
{Diff, true} = {Diff, (Diff >= 0)},
{Diff, true} = {Diff, (Diff =< 1000*1000)},
{Reds, [Diff | Acc]}
end,
{0, []},
lists:seq(1,10)),
unlink(Pid),
exit(Pid,kill),
io:format("Reduction diffs: ~p\n", [DiffList]),
ok.

pi_reductions_spinnloop() ->
%% 6 args to make use of def_arg_reg[5] which is also used as REDS_IN
pi_reductions_spinnloop(1, atom, "hej", self(), make_ref(), 3.14).

pi_reductions_spinnloop(A,B,C,D,E,F) ->
pi_reductions_spinnloop(B,C,D,E,F,A).

pi_reductions_recvloop() ->
receive
"a free lunch" -> false
end.


%% Tests erlang:bump_reductions/1.
bump_reductions(Config) when is_list(Config) ->
erlang:garbage_collect(),
Expand Down

0 comments on commit 78b55ab

Please sign in to comment.