aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded
diff options
context:
space:
mode:
authorDmytro Lytovchenko <[email protected]>2016-06-13 12:05:55 +0200
committerLukas Larsson <[email protected]>2016-08-12 13:39:03 +0200
commit58d8a3ac4d491c8cd962ac0839a56cd1a0e339f9 (patch)
treeee73059b660ab09d55e3b8bc7d4dd4bf53bb07ae /erts/preloaded
parent451ca8e5ca10892342ee8627de7ea961a8f06df2 (diff)
downloadotp-58d8a3ac4d491c8cd962ac0839a56cd1a0e339f9.tar.gz
otp-58d8a3ac4d491c8cd962ac0839a56cd1a0e339f9.tar.bz2
otp-58d8a3ac4d491c8cd962ac0839a56cd1a0e339f9.zip
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
Diffstat (limited to 'erts/preloaded')
-rw-r--r--erts/preloaded/src/erlang.erl35
-rw-r--r--erts/preloaded/src/erts_internal.erl7
2 files changed, 26 insertions, 16 deletions
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)).