aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/test/scheduler_SUITE.erl
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2010-01-22 13:47:23 +0000
committerErlang/OTP <[email protected]>2010-01-22 13:47:23 +0000
commite19d6e4463a9cc3b738fd32a46e0ce9282a70fd5 (patch)
treed4014c55c5cd8c4559c9227b25e187e0f457fc46 /erts/emulator/test/scheduler_SUITE.erl
parentc7187afaf4d672e0320a73708fe44d5ac5520b52 (diff)
downloadotp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.tar.gz
otp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.tar.bz2
otp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.zip
OTP-8386 Immediately repeated multi-scheduling block/unblock cycles using
erlang:system_flag(multi_scheduling, block | unblock) could deadlock the runtime system.
Diffstat (limited to 'erts/emulator/test/scheduler_SUITE.erl')
-rw-r--r--erts/emulator/test/scheduler_SUITE.erl110
1 files changed, 102 insertions, 8 deletions
diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl
index e644ad4dc8..c9101b77c2 100644
--- a/erts/emulator/test/scheduler_SUITE.erl
+++ b/erts/emulator/test/scheduler_SUITE.erl
@@ -1,19 +1,19 @@
%%
%% %CopyrightBegin%
-%%
-%% Copyright Ericsson AB 2008-2009. All Rights Reserved.
-%%
+%%
+%% Copyright Ericsson AB 2008-2010. All Rights Reserved.
+%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
%% compliance with the License. You should have received a copy of the
%% Erlang Public License along with this software. If not, it can be
%% retrieved online at http://www.erlang.org/.
-%%
+%%
%% Software distributed under the License is distributed on an "AS IS"
%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
%% the License for the specific language governing rights and limitations
%% under the License.
-%%
+%%
%% %CopyrightEnd%
%%
@@ -48,7 +48,8 @@
scheduler_bind_types/1,
cpu_topology/1,
sct_cmd/1,
- sbt_cmd/1]).
+ sbt_cmd/1,
+ scheduler_suspend/1]).
-define(DEFAULT_TIMEOUT, ?t:minutes(10)).
@@ -65,7 +66,8 @@ all(suite) ->
equal_with_high,
equal_with_high_max,
bound_process,
- scheduler_bind].
+ scheduler_bind,
+ scheduler_suspend].
init_per_testcase(Case, Config) when is_list(Config) ->
Dog = ?t:timetrap(?DEFAULT_TIMEOUT),
@@ -882,11 +884,103 @@ sbt_test(Config, CpuTCmd, ClBt, Bt, LP) ->
?line stop_node(Node),
?line ok.
+scheduler_suspend(Config) when is_list(Config) ->
+ ?line Dog = ?t:timetrap(?t:minutes(2)),
+ ?line lists:foreach(fun (S) -> scheduler_suspend_test(Config, S) end,
+ [64, 32, 16, default]),
+ ?line ?t:timetrap_cancel(Dog),
+ ?line ok.
+scheduler_suspend_test(Config, Schedulers) ->
+ ?line Cmd = case Schedulers of
+ default ->
+ "";
+ _ ->
+ S = integer_to_list(Schedulers),
+ "+S"++S++":"++S
+ end,
+ ?line {ok, Node} = start_node(Config, Cmd),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line {Sched, _, _} = SState,
+ ?line true = is_integer(Sched),
+ ?line [ok] = mcall(Node, [fun () -> sst0_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst1_loop(300) end]),
+ ?line [ok] = mcall(Node, [fun () -> sst2_loop(300) end]),
+ ?line [ok, ok, ok, ok, ok] = mcall(Node,
+ [fun () -> sst0_loop(200) end,
+ fun () -> sst1_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst2_loop(200) end,
+ fun () -> sst3_loop(Sched, 200) end]),
+ ?line [SState] = mcall(Node, [fun () ->
+ erlang:system_info(schedulers_state)
+ end]),
+ ?line stop_node(Node),
+ ?line ok.
+
+
+sst0_loop(0) ->
+ ok;
+sst0_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:yield(),
+ sst0_loop(N-1).
+
+sst1_loop(0) ->
+ ok;
+sst1_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst1_loop(N-1).
+
+sst2_loop(0) ->
+ ok;
+sst2_loop(N) ->
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, block),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ erlang:system_flag(multi_scheduling, unblock),
+ sst2_loop(N-1).
+
+sst3_loop(_S, 0) ->
+ ok;
+sst3_loop(S, N) ->
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, (S div 2)+1),
+ erlang:system_flag(schedulers_online, S),
+ erlang:system_flag(schedulers_online, 1),
+ erlang:system_flag(schedulers_online, S),
+ sst3_loop(S, N-1).
+
-%
+%%
%% Utils
%%
+mcall(Node, Funs) ->
+ Parent = self(),
+ Refs = lists:map(fun (Fun) ->
+ Ref = make_ref(),
+ spawn_link(Node,
+ fun () ->
+ Res = Fun(),
+ unlink(Parent),
+ Parent ! {Ref, Res}
+ end),
+ Ref
+ end, Funs),
+ lists:map(fun (Ref) ->
+ receive
+ {Ref, Res} ->
+ Res
+ end
+ end, Refs).
+
erl_rel_flag_var() ->
"ERL_"++erlang:system_info(otp_release)++"_FLAGS".