From b3441cbd116fede332e1e4cfee4d48331be1fa62 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Tue, 22 Nov 2016 13:39:24 +0100 Subject: erts: Add ?line macro for some hipe testing --- erts/emulator/test/code_SUITE.erl | 2 +- .../code_SUITE_data/call_purged_fun_tester.erl | 108 ++++++++++++--------- 2 files changed, 65 insertions(+), 45 deletions(-) (limited to 'erts') diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl index 774461c525..0742b77a52 100644 --- a/erts/emulator/test/code_SUITE.erl +++ b/erts/emulator/test/code_SUITE.erl @@ -155,7 +155,7 @@ call_purged_fun_code_there(Config) when is_list(Config) -> call_purged_fun_test(Priv, Data, Type) -> OptsList = case erlang:system_info(hipe_architecture) of undefined -> [[]]; - _ -> [[], [native]] + _ -> [[], [native,{d,hipe}]] end, [call_purged_fun_test_do(Priv, Data, Type, CO, FO) || CO <- OptsList, FO <- OptsList]. diff --git a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl index 5e031abca8..16dbbcec37 100644 --- a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl +++ b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl @@ -2,7 +2,27 @@ -export([do/4]). +%% Resurrect line macro when hipe compiled +-ifdef(hipe). +-define(line, put(the_line,?LINE),). do(Priv, Data, Type, Opts) -> + try do_it(Priv, Data, Type, Opts) + catch + C:E -> + ST = erlang:get_stacktrace(), + io:format("Caught exception from line ~p:\n~p\n", + [get(the_line), ST]), + io:format("Message queue: ~p\n", [process_info(self(), messages)]), + erlang:raise(C, E, ST) + end. +-else. +-define(line,). +do(P,D,T,O) -> + do_it(P,D,T,O). +-endif. + + +do_it(Priv, Data, Type, Opts) -> File = filename:join(Data, "my_code_test2"), Code = filename:join(Priv, "my_code_test2"), @@ -10,12 +30,12 @@ do(Priv, Data, Type, Opts) -> catch erlang:delete_module(my_code_test2), catch erlang:purge_module(my_code_test2), - {ok,my_code_test2} = c:c(File, [{outdir,Priv} | Opts]), + ?line {ok,my_code_test2} = c:c(File, [{outdir,Priv} | Opts]), - IsNative = lists:member(native,Opts), - IsNative = code:is_module_native(my_code_test2), + ?line IsNative = lists:member(native,Opts), + ?line IsNative = code:is_module_native(my_code_test2), - T = ets:new(my_code_test2_fun_table, []), + ?line T = ets:new(my_code_test2_fun_table, []), ets:insert(T, {my_fun,my_code_test2:make_fun(4711)}), ets:insert(T, {my_fun2,my_code_test2:make_fun2()}), @@ -28,7 +48,7 @@ do(Priv, Data, Type, Opts) -> exit(completed) end), - PurgeType = case Type of + ?line PurgeType = case Type of code_gone -> ok = file:delete(Code++".beam"), true; @@ -38,89 +58,89 @@ do(Priv, Data, Type, Opts) -> false end, - true = erlang:delete_module(my_code_test2), + ?line true = erlang:delete_module(my_code_test2), - Purge = start_purge(my_code_test2, PurgeType), + ?line Purge = start_purge(my_code_test2, PurgeType), - {P0, M0} = spawn_monitor(fun () -> - [{my_fun,F}] = ets:lookup(T, my_fun), - 4712 = F(1), - exit(completed) + ?line {P0, M0} = spawn_monitor(fun () -> + ?line [{my_fun,F}] = ets:lookup(T, my_fun), + ?line 4712 = F(1), + exit(completed) end), - wait_until(fun () -> - {status, suspended} - == process_info(P0, status) - end), + ?line ok = wait_until(fun () -> + {status, suspended} + == process_info(P0, status) + end), - ok = continue_purge(Purge), + ?line ok = continue_purge(Purge), - {P1, M1} = spawn_monitor(fun () -> - [{my_fun,F}] = ets:lookup(T, my_fun), - 4713 = F(2), - exit(completed) + ?line {P1, M1} = spawn_monitor(fun () -> + ?line [{my_fun,F}] = ets:lookup(T, my_fun), + ?line 4713 = F(2), + exit(completed) end), - {P2, M2} = spawn_monitor(fun () -> - [{my_fun,F}] = ets:lookup(T, my_fun), - 4714 = F(3), - exit(completed) + ?line {P2, M2} = spawn_monitor(fun () -> + ?line [{my_fun,F}] = ets:lookup(T, my_fun), + ?line 4714 = F(3), + exit(completed) end), - wait_until(fun () -> - {status, suspended} - == process_info(P1, status) - end), - wait_until(fun () -> - {status, suspended} - == process_info(P2, status) - end), + ?line ok = wait_until(fun () -> + {status, suspended} + == process_info(P1, status) + end), + ?line ok = wait_until(fun () -> + {status, suspended} + == process_info(P2, status) + end), - {current_function, + ?line {current_function, {erts_code_purger, pending_purge_lambda, 3}} = process_info(P0, current_function), - {current_function, + ?line {current_function, {erts_code_purger, pending_purge_lambda, 3}} = process_info(P1, current_function), - {current_function, + ?line {current_function, {erts_code_purger, pending_purge_lambda, 3}} = process_info(P2, current_function), case Type of code_there -> - false = complete_purge(Purge); + ?line false = complete_purge(Purge); _ -> - {true, true} = complete_purge(Purge) + ?line {true, true} = complete_purge(Purge) end, case Type of code_gone -> receive {'DOWN', M0, process, P0, Reason0} -> - {undef, _} = Reason0 + ?line {undef, _} = Reason0 end, receive {'DOWN', M1, process, P1, Reason1} -> - {undef, _} = Reason1 + ?line {undef, _} = Reason1 end, receive {'DOWN', M2, process, P2, Reason2} -> - {undef, _} = Reason2 + ?line {undef, _} = Reason2 end; _ -> receive {'DOWN', M0, process, P0, Reason0} -> - completed = Reason0 + ?line completed = Reason0 end, receive {'DOWN', M1, process, P1, Reason1} -> - completed = Reason1 + ?line completed = Reason1 end, receive {'DOWN', M2, process, P2, Reason2} -> - completed = Reason2 + ?line completed = Reason2 end, catch erlang:purge_module(my_code_test2), catch erlang:delete_module(my_code_test2), @@ -129,7 +149,7 @@ do(Priv, Data, Type, Opts) -> ok. wait_until(Fun) -> - ok = wait_until(Fun, 20). + wait_until(Fun, 20). wait_until(Fun, N) -> case {Fun(),N} of -- cgit v1.2.3 From 15789e168811d6e6bed082ea7c64db93e1d968e8 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 17 Nov 2016 14:39:04 +0100 Subject: erts: Refactor test code --- .../code_SUITE_data/call_purged_fun_tester.erl | 58 +++++++++------------- 1 file changed, 24 insertions(+), 34 deletions(-) (limited to 'erts') diff --git a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl index 16dbbcec37..10d00b7d2a 100644 --- a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl +++ b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl @@ -62,25 +62,25 @@ do_it(Priv, Data, Type, Opts) -> ?line Purge = start_purge(my_code_test2, PurgeType), - ?line {P0, M0} = spawn_monitor(fun () -> + ?line {P1, M1} = spawn_monitor(fun () -> ?line [{my_fun,F}] = ets:lookup(T, my_fun), ?line 4712 = F(1), exit(completed) end), - ?line ok = wait_until(fun () -> + ?line ok = wait_until(fun () -> {status, suspended} - == process_info(P0, status) + == process_info(P1, status) end), ?line ok = continue_purge(Purge), - ?line {P1, M1} = spawn_monitor(fun () -> + ?line {P2, M2} = spawn_monitor(fun () -> ?line [{my_fun,F}] = ets:lookup(T, my_fun), ?line 4713 = F(2), exit(completed) end), - ?line {P2, M2} = spawn_monitor(fun () -> + ?line {P3, M3} = spawn_monitor(fun () -> ?line [{my_fun,F}] = ets:lookup(T, my_fun), ?line 4714 = F(3), exit(completed) @@ -88,25 +88,25 @@ do_it(Priv, Data, Type, Opts) -> ?line ok = wait_until(fun () -> {status, suspended} - == process_info(P1, status) + == process_info(P2, status) end), ?line ok = wait_until(fun () -> {status, suspended} - == process_info(P2, status) + == process_info(P3, status) end), ?line {current_function, {erts_code_purger, pending_purge_lambda, - 3}} = process_info(P0, current_function), + 3}} = process_info(P1, current_function), ?line {current_function, {erts_code_purger, pending_purge_lambda, - 3}} = process_info(P1, current_function), + 3}} = process_info(P2, current_function), ?line {current_function, {erts_code_purger, pending_purge_lambda, - 3}} = process_info(P2, current_function), + 3}} = process_info(P3, current_function), case Type of code_there -> @@ -117,37 +117,27 @@ do_it(Priv, Data, Type, Opts) -> case Type of code_gone -> - receive - {'DOWN', M0, process, P0, Reason0} -> - ?line {undef, _} = Reason0 - end, - receive - {'DOWN', M1, process, P1, Reason1} -> - ?line {undef, _} = Reason1 - end, - receive - {'DOWN', M2, process, P2, Reason2} -> - ?line {undef, _} = Reason2 - end; + ?line {undef, _} = wait_for_down(P1,M1), + ?line {undef, _} = wait_for_down(P2,M2), + ?line {undef, _} = wait_for_down(P3,M3); _ -> - receive - {'DOWN', M0, process, P0, Reason0} -> - ?line completed = Reason0 - end, - receive - {'DOWN', M1, process, P1, Reason1} -> - ?line completed = Reason1 - end, - receive - {'DOWN', M2, process, P2, Reason2} -> - ?line completed = Reason2 - end, + ?line completed = wait_for_down(P1,M1), + ?line completed = wait_for_down(P2,M2), + ?line completed = wait_for_down(P3,M3), catch erlang:purge_module(my_code_test2), catch erlang:delete_module(my_code_test2), catch erlang:purge_module(my_code_test2) end, ok. +wait_for_down(P,M) -> + receive + {'DOWN', M, process, P, Reason} -> + Reason + after 1000 -> + timeout + end. + wait_until(Fun) -> wait_until(Fun, 20). -- cgit v1.2.3 From 20eea6a99b25b99db728fcae5b8303739e5c1cc8 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 17 Nov 2016 17:35:17 +0100 Subject: erts: Fix race in code_SUITE:call_purged_fun_* Must wait for process P0 to enter fun F2 before starting purge, to make sure it's not suspended. --- .../code_SUITE_data/call_purged_fun_tester.erl | 29 ++++++++++++++-------- 1 file changed, 19 insertions(+), 10 deletions(-) (limited to 'erts') diff --git a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl index 10d00b7d2a..699f0c1161 100644 --- a/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl +++ b/erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl @@ -39,14 +39,16 @@ do_it(Priv, Data, Type, Opts) -> ets:insert(T, {my_fun,my_code_test2:make_fun(4711)}), ets:insert(T, {my_fun2,my_code_test2:make_fun2()}), - spawn(fun () -> - [{my_fun2,F2}] = ets:lookup(T, my_fun2), - F2(fun () -> - receive after infinity -> ok end - end, - fun () -> ok end), - exit(completed) - end), + Papa = self(), + {P0,M0} = spawn_monitor(fun () -> + [{my_fun2,F2}] = ets:lookup(T, my_fun2), + F2(fun () -> + Papa ! {self(),"going to sleep"}, + receive {Papa,"wake up"} -> ok end + end, + fun () -> ok end), + exit(completed) + end), ?line PurgeType = case Type of code_gone -> @@ -60,6 +62,10 @@ do_it(Priv, Data, Type, Opts) -> ?line true = erlang:delete_module(my_code_test2), + ?line ok = receive {P0, "going to sleep"} -> ok + after 1000 -> timeout + end, + ?line Purge = start_purge(my_code_test2, PurgeType), ?line {P1, M1} = spawn_monitor(fun () -> @@ -110,9 +116,12 @@ do_it(Priv, Data, Type, Opts) -> case Type of code_there -> - ?line false = complete_purge(Purge); + ?line false = complete_purge(Purge), + P0 ! {self(), "wake up"}, + ?line completed = wait_for_down(P0,M0); _ -> - ?line {true, true} = complete_purge(Purge) + ?line {true, true} = complete_purge(Purge), + ?line killed = wait_for_down(P0,M0) end, case Type of -- cgit v1.2.3