aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2016-11-30 14:21:29 +0100
committerSverker Eriksson <[email protected]>2016-11-30 14:21:29 +0100
commitd4701119d50f16dce30ff0a736c7a926e1bbaa04 (patch)
treeca7f9d9d705fdb0a80460b5eaa790e5b74caa0b9
parent938a49966c4e3da4d2859ef9ad36de4458fb5c11 (diff)
parent20eea6a99b25b99db728fcae5b8303739e5c1cc8 (diff)
downloadotp-d4701119d50f16dce30ff0a736c7a926e1bbaa04.tar.gz
otp-d4701119d50f16dce30ff0a736c7a926e1bbaa04.tar.bz2
otp-d4701119d50f16dce30ff0a736c7a926e1bbaa04.zip
Merge branch 'sverker/cuddle-hipe-fun-purge-test'
* sverker/cuddle-hipe-fun-purge-test: erts: Fix race in code_SUITE:call_purged_fun_* erts: Refactor test code erts: Add ?line macro for some hipe testing
-rw-r--r--erts/emulator/test/code_SUITE.erl2
-rw-r--r--erts/emulator/test/code_SUITE_data/call_purged_fun_tester.erl167
2 files changed, 94 insertions, 75 deletions
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..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
@@ -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,25 +30,27 @@ 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()}),
- spawn(fun () ->
- [{my_fun2,F2}] = ets:lookup(T, my_fun2),
- F2(fun () ->
- receive after infinity -> ok end
- end,
- fun () -> ok end),
- exit(completed)
- end),
-
- PurgeType = case Type of
+ 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 ->
ok = file:delete(Code++".beam"),
true;
@@ -38,98 +60,95 @@ do(Priv, Data, Type, Opts) ->
false
end,
- true = erlang:delete_module(my_code_test2),
+ ?line true = erlang:delete_module(my_code_test2),
+
+ ?line ok = receive {P0, "going to sleep"} -> ok
+ after 1000 -> timeout
+ end,
- 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 {P1, M1} = 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(P1, 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 {P2, M2} = 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 {P3, M3} = 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(P2, status)
+ end),
+ ?line ok = wait_until(fun () ->
+ {status, suspended}
+ == process_info(P3, status)
+ end),
- {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),
+ ?line {current_function,
+ {erts_code_purger,
+ pending_purge_lambda,
+ 3}} = process_info(P3, current_function),
case Type of
code_there ->
- false = complete_purge(Purge);
+ ?line false = complete_purge(Purge),
+ P0 ! {self(), "wake up"},
+ ?line completed = wait_for_down(P0,M0);
_ ->
- {true, true} = complete_purge(Purge)
+ ?line {true, true} = complete_purge(Purge),
+ ?line killed = wait_for_down(P0,M0)
end,
case Type of
code_gone ->
- receive
- {'DOWN', M0, process, P0, Reason0} ->
- {undef, _} = Reason0
- end,
- receive
- {'DOWN', M1, process, P1, Reason1} ->
- {undef, _} = Reason1
- end,
- receive
- {'DOWN', M2, process, P2, Reason2} ->
- {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} ->
- completed = Reason0
- end,
- receive
- {'DOWN', M1, process, P1, Reason1} ->
- completed = Reason1
- end,
- receive
- {'DOWN', M2, process, P2, Reason2} ->
- 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) ->
- ok = wait_until(Fun, 20).
+ wait_until(Fun, 20).
wait_until(Fun, N) ->
case {Fun(),N} of