File 6711-stdlib-Hibernate-static-supervisors.patch of Package erlang
From ccab562b41f5a1ab9c538f0d573c347247fd2584 Mon Sep 17 00:00:00 2001
From: Ingela Anderton Andin <ingela@erlang.org>
Date: Fri, 17 Feb 2023 16:27:34 +0100
Subject: [PATCH] stdlib: Hibernate static supervisors
Static supervisors are very idle processes after they have started
so they will now be hibernated after start to improve resource management.
---
lib/stdlib/src/supervisor.erl | 8 +++++++-
lib/stdlib/test/supervisor_SUITE.erl | 16 +++++++++++++---
2 files changed, 20 insertions(+), 4 deletions(-)
diff --git a/lib/stdlib/src/supervisor.erl b/lib/stdlib/src/supervisor.erl
index 58b943d874..de44ce55ee 100644
--- a/lib/stdlib/src/supervisor.erl
+++ b/lib/stdlib/src/supervisor.erl
@@ -349,7 +349,10 @@ init_children(State, StartSpec) ->
{ok, Children} ->
case start_children(Children, SupName) of
{ok, NChildren} ->
- {ok, State#state{children = NChildren}};
+ %% Static supervisor are not expected to
+ %% have much work to do so hibernate them
+ %% to improve memory handling.
+ {ok, State#state{children = NChildren}, hibernate};
{error, NChildren, Reason} ->
_ = terminate_children(NChildren, SupName),
{stop, {shutdown, Reason}}
@@ -361,6 +364,9 @@ init_children(State, StartSpec) ->
init_dynamic(State, [StartSpec]) ->
case check_startspec([StartSpec]) of
{ok, Children} ->
+ %% Simple one for one supervisors are expected to
+ %% have many children coming and going so do not
+ %% hibernate.
{ok, dyn_init(State#state{children = Children})};
Error ->
{stop, {start_spec, Error}}
diff --git a/lib/stdlib/test/supervisor_SUITE.erl b/lib/stdlib/test/supervisor_SUITE.erl
index 78d7e7d7bc..26422a8d2a 100644
--- a/lib/stdlib/test/supervisor_SUITE.erl
+++ b/lib/stdlib/test/supervisor_SUITE.erl
@@ -706,11 +706,15 @@ child_adm(Config) when is_list(Config) ->
process_flag(trap_exit, true),
Child = {child1, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
- {ok, _Pid} = start_link({ok, {{one_for_one, 2, 3600}, [Child]}}),
+ {ok, Pid} = start_link({ok, {{one_for_one, 2, 3600}, [Child]}}),
+
+ %% Test that supervisors of static nature are hibernated after start
+ {current_function, {erlang, hibernate, 3}} =
+ process_info(Pid, current_function),
+
[{child1, CPid, worker, []}] = supervisor:which_children(sup_test),
[1,1,0,1] = get_child_counts(sup_test),
link(CPid),
-
%% Start of an already runnig process
{error,{already_started, CPid}} =
supervisor:start_child(sup_test, Child),
@@ -771,7 +775,13 @@ child_adm(Config) when is_list(Config) ->
child_adm_simple(Config) when is_list(Config) ->
Child = {child, {supervisor_1, start_child, []}, permanent, 1000,
worker, []},
- {ok, _Pid} = start_link({ok, {{simple_one_for_one, 2, 3600}, [Child]}}),
+ {ok, Pid} = start_link({ok, {{simple_one_for_one, 2, 3600}, [Child]}}),
+
+ %% Test that supervisors of dynamic nature are not hibernated after start
+ {current_function, {_, Function, _}} =
+ process_info(Pid, current_function),
+ true = Function =/= hibernate,
+
%% In simple_one_for_one all children are added dynamically
[] = supervisor:which_children(sup_test),
[1,0,0,0] = get_child_counts(sup_test),
--
2.35.3