From 58d8a3ac4d491c8cd962ac0839a56cd1a0e339f9 Mon Sep 17 00:00:00 2001 From: Dmytro Lytovchenko Date: Mon, 13 Jun 2016 12:05:55 +0200 Subject: Option to erlang:garbage_collect to request minor (generational) GC Note: Minor GC option is a hint, and GC may still decide to run fullsweep. Test case for major and minor gc on self Test case for major and minor gs on some other process + async gc test check docs fix --- erts/preloaded/src/erlang.erl | 35 ++++++++++++++++++++--------------- erts/preloaded/src/erts_internal.erl | 7 ++++++- 2 files changed, 26 insertions(+), 16 deletions(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl index edf79b8f75..dd1156f292 100644 --- a/erts/preloaded/src/erlang.erl +++ b/erts/preloaded/src/erlang.erl @@ -875,36 +875,39 @@ garbage_collect(Pid) -> error:Error -> erlang:error(Error, [Pid]) end. +-record(gcopt, { + async = sync :: sync | {async, _}, + type = major % default major, can also be minor + }). + %% garbage_collect/2 -spec garbage_collect(Pid, OptionList) -> GCResult | async when Pid :: pid(), RequestId :: term(), - Option :: {async, RequestId}, + Option :: {async, RequestId} | {type, 'major' | 'minor'}, OptionList :: [Option], GCResult :: boolean(). garbage_collect(Pid, OptionList) -> try - Async = get_gc_opts(OptionList, sync), - case Async of + GcOpts = get_gc_opts(OptionList, #gcopt{}), + case GcOpts#gcopt.async of {async, ReqId} -> {priority, Prio} = erlang:process_info(erlang:self(), priority), - erts_internal:request_system_task(Pid, - Prio, - {garbage_collect, ReqId}), + erts_internal:request_system_task( + Pid, Prio, {garbage_collect, ReqId, GcOpts#gcopt.type}), async; sync -> case Pid == erlang:self() of true -> - erlang:garbage_collect(); + erts_internal:garbage_collect(GcOpts#gcopt.type); false -> {priority, Prio} = erlang:process_info(erlang:self(), priority), ReqId = erlang:make_ref(), - erts_internal:request_system_task(Pid, - Prio, - {garbage_collect, - ReqId}), + erts_internal:request_system_task( + Pid, Prio, + {garbage_collect, ReqId, GcOpts#gcopt.type}), receive {garbage_collect, ReqId, GCResult} -> GCResult @@ -916,10 +919,12 @@ garbage_collect(Pid, OptionList) -> end. % gets async opt and verify valid option list -get_gc_opts([{async, _ReqId} = AsyncTuple | Options], _OldAsync) -> - get_gc_opts(Options, AsyncTuple); -get_gc_opts([], Async) -> - Async. +get_gc_opts([{async, _ReqId} = AsyncTuple | Options], GcOpt = #gcopt{}) -> + get_gc_opts(Options, GcOpt#gcopt{ async = AsyncTuple }); +get_gc_opts([{type, T} | Options], GcOpt = #gcopt{}) -> + get_gc_opts(Options, GcOpt#gcopt{ type = T }); +get_gc_opts([], GcOpt) -> + GcOpt. %% garbage_collect_message_area/0 -spec erlang:garbage_collect_message_area() -> boolean(). diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl index 2459ea2a2c..6f2e50d1db 100644 --- a/erts/preloaded/src/erts_internal.erl +++ b/erts/preloaded/src/erts_internal.erl @@ -38,7 +38,8 @@ -export([system_check/1, gather_system_check_result/1]). --export([request_system_task/3]). +-export([request_system_task/3, + garbage_collect/1]). -export([check_process_code/3]). -export([copy_literals/2]). @@ -210,6 +211,10 @@ port_info(_Result, _Item) -> request_system_task(_Pid, _Prio, _Request) -> erlang:nif_error(undefined). +-spec garbage_collect(Mode) -> 'true' when Mode :: 'major' | 'minor'. +garbage_collect(_Mode) -> + erlang:nif_error(undefined). + -define(ERTS_CPC_ALLOW_GC, (1 bsl 0)). -define(ERTS_CPC_COPY_LITERALS, (1 bsl 1)). -- cgit v1.2.3 From 99701ee7b52f5010da7c8540bbb35481bee053bf Mon Sep 17 00:00:00 2001 From: Lukas Larsson Date: Fri, 26 Aug 2016 15:12:33 +0200 Subject: erts: Fix req_system_task gc typespec --- erts/preloaded/src/erts_internal.erl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'erts/preloaded') diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl index 6f2e50d1db..43f8eee371 100644 --- a/erts/preloaded/src/erts_internal.erl +++ b/erts/preloaded/src/erts_internal.erl @@ -204,7 +204,8 @@ port_info(_Result, _Item) -> -spec request_system_task(Pid, Prio, Request) -> 'ok' when Prio :: 'max' | 'high' | 'normal' | 'low', - Request :: {'garbage_collect', term()} + Type :: 'major' | 'minor', + Request :: {'garbage_collect', term(), Type} | {'check_process_code', term(), module(), non_neg_integer()}, Pid :: pid(). -- cgit v1.2.3