summaryrefslogtreecommitdiff
path: root/erts/preloaded/src/erts_literal_area_collector.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/preloaded/src/erts_literal_area_collector.erl')
-rw-r--r--erts/preloaded/src/erts_literal_area_collector.erl45
1 files changed, 26 insertions, 19 deletions
diff --git a/erts/preloaded/src/erts_literal_area_collector.erl b/erts/preloaded/src/erts_literal_area_collector.erl
index 8a73ed1685..bb2ad6b919 100644
--- a/erts/preloaded/src/erts_literal_area_collector.erl
+++ b/erts/preloaded/src/erts_literal_area_collector.erl
@@ -62,39 +62,46 @@ msg_loop(Area, {Ongoing, NeedIReq} = OReqInfo, GcOutstnd, NeedGC) ->
switch_area();
%% Process (_Pid) has completed the request...
- {copy_literals, {Area, _GcAllowed, _Pid}, ok} when Ongoing == 1,
- NeedIReq == [] ->
+ {copy_literals, {Area, _ReqType, _Pid}, ok} when Ongoing == 1,
+ NeedIReq == [] ->
switch_area(); %% Last process completed...
- {copy_literals, {Area, false, _Pid}, ok} ->
+ {copy_literals, {Area, init, _Pid}, ok} ->
msg_loop(Area, check_send_copy_req(Area, Ongoing-1, NeedIReq),
GcOutstnd, NeedGC);
- {copy_literals, {Area, true, _Pid}, ok} when NeedGC == [] ->
+ {copy_literals, {Area, ReqType, _Pid}, ok} when NeedGC == [],
+ ReqType /= init ->
msg_loop(Area, check_send_copy_req(Area, Ongoing-1, NeedIReq),
GcOutstnd-1, []);
- {copy_literals, {Area, true, _Pid}, ok} ->
- send_copy_req(hd(NeedGC), Area, true),
- msg_loop(Area, {Ongoing-1, NeedIReq}, GcOutstnd, tl(NeedGC));
+ {copy_literals, {Area, ReqType, _Pid}, ok} when ReqType /= init ->
+ [{GCPid,GCWork} | NewNeedGC] = NeedGC,
+ send_copy_req(GCPid, Area, GCWork),
+ msg_loop(Area, {Ongoing-1, NeedIReq}, GcOutstnd, NewNeedGC);
%% Process (Pid) failed to complete the request
%% since it needs to garbage collect in order to
%% complete the request...
- {copy_literals, {Area, false, Pid}, need_gc} when GcOutstnd < ?MAX_GC_OUTSTND ->
- send_copy_req(Pid, Area, true),
+ {copy_literals, {Area, init, Pid}, GCWork} when GcOutstnd
+ < ?MAX_GC_OUTSTND ->
+ send_copy_req(Pid, Area, GCWork),
msg_loop(Area, OReqInfo, GcOutstnd+1, NeedGC);
- {copy_literals, {Area, false, Pid}, need_gc} ->
+ {copy_literals, {Area, init, Pid}, GCWork} ->
msg_loop(Area, check_send_copy_req(Area, Ongoing, NeedIReq),
- GcOutstnd, [Pid|NeedGC]);
+ GcOutstnd, [{Pid,GCWork} | NeedGC]);
%% Not handled message regarding the area that we
%% currently are working with. Crash the VM so
%% we notice this bug...
- {copy_literals, {Area, _, _}, _} = Msg when erlang:is_reference(Area) ->
+ {copy_literals, {Area, _, _}, _} = Msg ->
exit({not_handled_message, Msg});
{change_prio, From, Ref, Prio} ->
change_prio(From, Ref, Prio),
msg_loop(Area, OReqInfo, GcOutstnd, NeedGC);
+ {get_status, Ref, From} when is_pid(From); is_reference(From) ->
+ From ! {Ref, if Ongoing == 0 -> idle; true -> working end},
+ msg_loop(Area, OReqInfo, GcOutstnd, NeedGC);
+
%% Unexpected garbage message. Get rid of it...
_Ignore ->
msg_loop(Area, OReqInfo, GcOutstnd, NeedGC)
@@ -126,7 +133,7 @@ switch_area() ->
check_send_copy_req(_Area, Ongoing, []) ->
{Ongoing, []};
check_send_copy_req(Area, Ongoing, [Pid|Pids]) ->
- send_copy_req(Pid, Area, false),
+ send_copy_req(Pid, Area, init),
{Ongoing+1, Pids}.
send_copy_reqs(Ps, Area, OReqLim) ->
@@ -137,23 +144,23 @@ send_copy_reqs([], _Area, _OReqLim, N) ->
send_copy_reqs(Ps, _Area, OReqLim, N) when N >= OReqLim ->
{N, Ps};
send_copy_reqs([P|Ps], Area, OReqLim, N) ->
- send_copy_req(P, Area, false),
+ send_copy_req(P, Area, init),
send_copy_reqs(Ps, Area, OReqLim, N+1).
-send_copy_req(P, Area, GC) ->
- erts_literal_area_collector:send_copy_request(P, Area, GC).
+send_copy_req(P, Area, How) ->
+ erts_literal_area_collector:send_copy_request(P, Area, How).
-spec release_area_switch() -> boolean().
release_area_switch() ->
erlang:nif_error(undef). %% Implemented in beam_bif_load.c
--spec send_copy_request(To, AreaId, GcAllowed) -> 'ok' when
+-spec send_copy_request(To, AreaId, How) -> 'ok' when
To :: pid(),
AreaId :: term(),
- GcAllowed :: boolean().
+ How :: 'init' | 'check_gc' | 'need_gc'.
-send_copy_request(_To, _AreaId, _GcAllowed) ->
+send_copy_request(_To, _AreaId, _How) ->
erlang:nif_error(undef). %% Implemented in beam_bif_load.c
change_prio(From, Ref, Prio) ->