diff options
author | Sverker Eriksson <[email protected]> | 2019-03-28 19:32:52 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2019-03-28 22:17:42 +0100 |
commit | 2c8e6848d3b1d13529e83d8cf76e0a2a458fea52 (patch) | |
tree | 62ff19f3d7b6203d5e03d3844b51448930cc4249 /erts/emulator/test | |
parent | bff3ef4e41c7637b0a9c1ca5a42a1c28efe242f5 (diff) | |
download | otp-2c8e6848d3b1d13529e83d8cf76e0a2a458fea52.tar.gz otp-2c8e6848d3b1d13529e83d8cf76e0a2a458fea52.tar.bz2 otp-2c8e6848d3b1d13529e83d8cf76e0a2a458fea52.zip |
erts: Fix bug in process_info(reductions)
returning incorrect result as
* current process might not be RUNNING in which case REDS_IN
is actually used as def_arg_reg[5]
* FCALLS might not have been swapped out
* the SAVED_CALLS case was wrong and returned number of reds left
Diffstat (limited to 'erts/emulator/test')
-rw-r--r-- | erts/emulator/test/process_SUITE.erl | 42 |
1 files changed, 42 insertions, 0 deletions
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl index 57eb082d64..545dd95bef 100644 --- a/erts/emulator/test/process_SUITE.erl +++ b/erts/emulator/test/process_SUITE.erl @@ -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, @@ -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, @@ -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(), |