aboutsummaryrefslogtreecommitdiffstats
path: root/lib/runtime_tools
diff options
context:
space:
mode:
Diffstat (limited to 'lib/runtime_tools')
-rw-r--r--lib/runtime_tools/src/erts_alloc_config.erl169
-rw-r--r--lib/runtime_tools/src/observer_backend.erl28
-rw-r--r--lib/runtime_tools/src/runtime_tools.appup.src10
-rw-r--r--lib/runtime_tools/test/runtime_tools_SUITE.erl6
4 files changed, 138 insertions, 75 deletions
diff --git a/lib/runtime_tools/src/erts_alloc_config.erl b/lib/runtime_tools/src/erts_alloc_config.erl
index 284e88d4a7..b9a26dc0dc 100644
--- a/lib/runtime_tools/src/erts_alloc_config.erl
+++ b/lib/runtime_tools/src/erts_alloc_config.erl
@@ -39,6 +39,8 @@
need_config_change,
alloc_util,
instances,
+ strategy,
+ acul,
low_mbc_blocks_size,
high_mbc_blocks_size,
sbct,
@@ -54,8 +56,6 @@
-define(SERVER, '__erts_alloc_config__').
--define(MAX_ALLOCATOR_INSTANCES, 16).
-
-define(KB, 1024).
-define(MB, 1048576).
@@ -99,23 +99,11 @@
{ets_alloc, 131072},
{fix_alloc, 131072},
{eheap_alloc, 524288},
- {ll_alloc, 2097152},
+ {ll_alloc, 131072},
{sl_alloc, 131072},
{temp_alloc, 131072},
{driver_alloc, 131072}]).
--define(MMMBC_DEFAULTS,
- [{binary_alloc, 10},
- {std_alloc, 10},
- {ets_alloc, 10},
- {fix_alloc, 10},
- {eheap_alloc, 10},
- {ll_alloc, 0},
- {sl_alloc, 10},
- {temp_alloc, 10},
- {driver_alloc, 10}]).
-
-
%%%
%%% Exported interface
%%%
@@ -230,20 +218,72 @@ server_loop(State) ->
end,
server_loop(NewState).
-allocator_instances(temp_alloc) ->
- erlang:system_info(schedulers) + 1;
-allocator_instances(ll_alloc) ->
+carrier_migration_support(aoff) ->
+ true;
+carrier_migration_support(aoffcbf) ->
+ true;
+carrier_migration_support(aoffcaobf) ->
+ true;
+carrier_migration_support(_) ->
+ false.
+
+allocator_instances(ll_alloc, Strategy) ->
+ case carrier_migration_support(Strategy) of
+ true -> erlang:system_info(schedulers);
+ false -> 1
+ end;
+allocator_instances(_A, undefined) ->
1;
-allocator_instances(_Allocator) ->
- case erlang:system_info(schedulers) of
- Schdlrs when Schdlrs =< ?MAX_ALLOCATOR_INSTANCES -> Schdlrs;
- _Schdlrs -> ?MAX_ALLOCATOR_INSTANCES
+allocator_instances(_A, _Strategy) ->
+ erlang:system_info(schedulers).
+
+strategy(temp_alloc, _AI) ->
+ af;
+strategy(A, AI) ->
+ try
+ {A, OptList} = lists:keyfind(A, 1, AI),
+ {as, S} = lists:keyfind(as, 1, OptList),
+ S
+ catch
+ _ : _ ->
+ undefined
+ end.
+
+strategy_str(af) ->
+ "A fit";
+strategy_str(gf) ->
+ "Good fit";
+strategy_str(bf) ->
+ "Best fit";
+strategy_str(aobf) ->
+ "Address order best fit";
+strategy_str(aoff) ->
+ "Address order first fit";
+strategy_str(aoffcbf) ->
+ "Address order first fit carrier best fit";
+strategy_str(aoffcaobf) ->
+ "Address order first fit carrier adress order best fit".
+
+default_acul(A, S) ->
+ case carrier_migration_support(S) of
+ false ->
+ 0;
+ true ->
+ case A of
+ ll_alloc -> 85;
+ eheap_alloc -> 45;
+ _ -> 60
+ end
end.
-
+
make_state() ->
+ {_, _, _, AI} = erlang:system_info(allocator),
#state{alloc = lists:map(fun (A) ->
+ S = strategy(A, AI),
#alloc{name = A,
- instances = allocator_instances(A)}
+ strategy = S,
+ acul = default_acul(A, S),
+ instances = allocator_instances(A, S)}
end,
?ALLOCATORS)}.
@@ -345,7 +385,7 @@ do_save_scenario(AlcList) ->
conf_size(Bytes) when is_integer(Bytes), Bytes < 0 ->
exit({bad_value, Bytes});
conf_size(Bytes) when is_integer(Bytes), Bytes < 1*?MB ->
- ?ROUNDUP(?B2KB(Bytes), 128);
+ ?ROUNDUP(?B2KB(Bytes), 256);
conf_size(Bytes) when is_integer(Bytes), Bytes < 10*?MB ->
?ROUNDUP(?B2KB(Bytes), ?B2KB(1*?MB));
conf_size(Bytes) when is_integer(Bytes), Bytes < 100*?MB ->
@@ -376,28 +416,25 @@ mmbcs(#conf{format_to = FTO},
temp_alloc -> BlocksSize;
_ -> BlocksSize div Insts
end,
- case BS > default_mmbcs(A, Insts) of
- true ->
+ DefMMBCS = default_mmbcs(A, Insts),
+ case {Insts, BS > DefMMBCS} of
+ {1, true} ->
MMBCS = conf_size(BS),
fc(FTO, "Main mbc size of ~p kilobytes.", [MMBCS]),
format(FTO, " +M~cmmbcs ~p~n", [alloc_char(A), MMBCS]);
- false ->
+ _ ->
+ MMBCS = ?B2KB(DefMMBCS),
+ fc(FTO, "Main mbc size of ~p kilobytes.", [MMBCS]),
+ format(FTO, " +M~cmmbcs ~p~n", [alloc_char(A), MMBCS]),
ok
end.
-smbcs_lmbcs_mmmbc(#conf{format_to = FTO},
- #alloc{name = A, instances = Insts, segments = Segments}) ->
- MMMBC = case {A, Insts} of
- {_, 1} -> Segments#segment.number;
- {temp_alloc, _} -> Segments#segment.number;
- _ -> (Segments#segment.number div Insts) + 1
- end,
+smbcs_lmbcs(#conf{format_to = FTO},
+ #alloc{name = A, segments = Segments}) ->
MBCS = Segments#segment.size,
AC = alloc_char(A),
fc(FTO, "Mseg mbc size of ~p kilobytes.", [MBCS]),
format(FTO, " +M~csmbcs ~p +M~clmbcs ~p~n", [AC, MBCS, AC, MBCS]),
- fc(FTO, "Max ~p mseg mbcs.", [MMMBC]),
- format(FTO, " +M~cmmmbc ~p~n", [AC, MMMBC]),
ok.
alloc_char(binary_alloc) -> $B;
@@ -462,6 +499,8 @@ au_conf_alloc(#conf{format_to = FTO} = Conf,
#alloc{name = A,
alloc_util = true,
instances = Insts,
+ acul = Acul,
+ strategy = Strategy,
low_mbc_blocks_size = Low,
high_mbc_blocks_size = High} = Alc) ->
fcp(FTO, "Usage of mbcs: ~p - ~p kilobytes", [?B2KB(Low), ?B2KB(High)]),
@@ -470,31 +509,49 @@ au_conf_alloc(#conf{format_to = FTO} = Conf,
fc(FTO, "One instance used."),
format(FTO, " +M~ct false~n", [alloc_char(A)]);
_ ->
- fc(FTO, "~p instances used.",
+ fc(FTO, "~p + 1 instances used.",
[Insts]),
- format(FTO, " +M~ct true~n", [alloc_char(A)])
- end,
+ format(FTO, " +M~ct true~n", [alloc_char(A)]),
+ case Strategy of
+ undefined ->
+ ok;
+ _ ->
+ fc(FTO, "Allocation strategy: ~s.",
+ [strategy_str(Strategy)]),
+ format(FTO, " +M~cas ~s~n", [alloc_char(A),
+ atom_to_list(Strategy)])
+ end,
+ case carrier_migration_support(Strategy) of
+ false ->
+ ok;
+ true ->
+ fc(FTO, "Abandon carrier utilization limit of ~p%.", [Acul]),
+ format(FTO, " +M~cacul ~p~n", [alloc_char(A), Acul])
+ end
+ end,
mmbcs(Conf, Alc),
- smbcs_lmbcs_mmmbc(Conf, Alc),
+ smbcs_lmbcs(Conf, Alc),
sbct(Conf, Alc).
-large_growth(Low, High) ->
- High - Low >= ?LARGE_GROWTH_ABS_LIMIT.
-
calc_seg_size(Growth, Segs) ->
conf_size(round(Growth*?FRAG_FACT*?GROWTH_SEG_FACT) div Segs).
calc_growth_segments(Conf, AlcList0) ->
- CalcSmall = fun (#alloc{name = ll_alloc} = Alc, Acc) ->
- {Alc#alloc{segments = #segment{size = 0,
+ CalcSmall = fun (#alloc{name = ll_alloc, instances = 1} = Alc, Acc) ->
+ {Alc#alloc{segments = #segment{size = conf_size(0),
number = 0}},
Acc};
(#alloc{alloc_util = true,
- low_mbc_blocks_size = Low,
+ instances = Insts,
+ low_mbc_blocks_size = LowMBC,
high_mbc_blocks_size = High} = Alc,
{SL, AL}) ->
+ Low = case Insts of
+ 1 -> LowMBC;
+ _ -> 0
+ end,
Growth = High - Low,
- case large_growth(Low, High) of
+ case Growth >= ?LARGE_GROWTH_ABS_LIMIT of
true ->
{Alc, {SL, AL+1}};
false ->
@@ -522,8 +579,13 @@ calc_growth_segments(Conf, AlcList0) ->
end,
CalcLarge = fun (#alloc{alloc_util = true,
segments = undefined,
- low_mbc_blocks_size = Low,
+ instances = Insts,
+ low_mbc_blocks_size = LowMBC,
high_mbc_blocks_size = High} = Alc) ->
+ Low = case Insts of
+ 1 -> LowMBC;
+ _ -> 0
+ end,
Growth = High - Low,
SegSize = calc_seg_size(Growth,
SegsPerAlloc),
@@ -560,15 +622,10 @@ format_header(FTO) ->
case erlang:system_info(schedulers) of
1 -> ok;
Schdlrs ->
- MinSchdlrs = case Schdlrs > ?MAX_ALLOCATOR_INSTANCES of
- true -> ?MAX_ALLOCATOR_INSTANCES;
- false -> Schdlrs
- end,
fcp(FTO,
"NOTE: This configuration was made for ~p schedulers. "
- "It is very important that at least ~p schedulers "
- "are used.",
- [Schdlrs, MinSchdlrs])
+ "It is very important that ~p schedulers are used.",
+ [Schdlrs, Schdlrs])
end,
fcp(FTO,
"This configuration is intended as a suggestion and "
diff --git a/lib/runtime_tools/src/observer_backend.erl b/lib/runtime_tools/src/observer_backend.erl
index 68ef04f20c..fea0854042 100644
--- a/lib/runtime_tools/src/observer_backend.erl
+++ b/lib/runtime_tools/src/observer_backend.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2002-2013. All Rights Reserved.
+%% Copyright Ericsson AB 2002-2014. 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
@@ -227,7 +227,9 @@ fetch_stats(Parent, Time) ->
fetch_stats_loop(Parent, Time) ->
erlang:system_flag(scheduler_wall_time, true),
receive
- _Msg -> erlang:system_flag(scheduler_wall_time, false)
+ _Msg ->
+ %% erlang:system_flag(scheduler_wall_time, false)
+ ok
after Time ->
_M = Parent ! {stats, 1,
erlang:statistics(scheduler_wall_time),
@@ -244,17 +246,6 @@ etop_collect(Collector) ->
%% utilization in etop). Next time the flag will be true and then
%% there will be a measurement.
SchedulerWallTime = erlang:statistics(scheduler_wall_time),
-
- %% Turn off the flag while collecting data per process etc.
- case erlang:system_flag(scheduler_wall_time,false) of
- false ->
- %% First time and the flag was false - start a monitoring
- %% process to set the flag back to false when etop is stopped.
- spawn(fun() -> flag_holder_proc(Collector) end);
- _ ->
- ok
- end,
-
ProcInfo = etop_collect(processes(), []),
Collector ! {self(),#etop_info{now = now(),
@@ -264,13 +255,22 @@ etop_collect(Collector) ->
memi = etop_memi(),
procinfo = ProcInfo
}},
+
+ case SchedulerWallTime of
+ undefined ->
+ spawn(fun() -> flag_holder_proc(Collector) end);
+ _ ->
+ ok
+ end,
+
erlang:system_flag(scheduler_wall_time,true).
flag_holder_proc(Collector) ->
Ref = erlang:monitor(process,Collector),
receive
{'DOWN',Ref,_,_,_} ->
- erlang:system_flag(scheduler_wall_time,false)
+ %% erlang:system_flag(scheduler_wall_time,false)
+ ok
end.
etop_memi() ->
diff --git a/lib/runtime_tools/src/runtime_tools.appup.src b/lib/runtime_tools/src/runtime_tools.appup.src
index 7a435e9b22..0c2bab316f 100644
--- a/lib/runtime_tools/src/runtime_tools.appup.src
+++ b/lib/runtime_tools/src/runtime_tools.appup.src
@@ -1,7 +1,7 @@
-%%
+%% -*- erlang -*-
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 2001-2009. All Rights Reserved.
+%% Copyright Ericsson AB 2001-2014. 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
@@ -15,5 +15,7 @@
%% under the License.
%%
%% %CopyrightEnd%
-%%
-{"%VSN%",[],[]}.
+{"%VSN%",
+ [{<<".*">>,[{restart_application, runtime_tools}]}],
+ [{<<".*">>,[{restart_application, runtime_tools}]}]
+}.
diff --git a/lib/runtime_tools/test/runtime_tools_SUITE.erl b/lib/runtime_tools/test/runtime_tools_SUITE.erl
index 62497ab527..48ed810918 100644
--- a/lib/runtime_tools/test/runtime_tools_SUITE.erl
+++ b/lib/runtime_tools/test/runtime_tools_SUITE.erl
@@ -25,7 +25,7 @@
-export([init_per_testcase/2, end_per_testcase/2]).
%% Test cases
--export([app_file/1, start_stop_app/1]).
+-export([app_file/1, appup_file/1, start_stop_app/1]).
%% Default timetrap timeout (set in init_per_testcase)
-define(default_timeout, ?t:minutes(1)).
@@ -43,6 +43,7 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
[app_file,
+ appup_file,
start_stop_app].
groups() ->
@@ -65,6 +66,9 @@ app_file(_Config) ->
?line ok = ?t:app_test(runtime_tools),
ok.
+appup_file(_Config) ->
+ ok = ?t:appup_test(runtime_tools).
+
start_stop_app(_Config) ->
ok = application:start(runtime_tools),
Sup = whereis(runtime_tools_sup),