aboutsummaryrefslogtreecommitdiffstats
path: root/erts/preloaded
diff options
context:
space:
mode:
Diffstat (limited to 'erts/preloaded')
-rw-r--r--erts/preloaded/ebin/erts_code_purger.beambin11168 -> 10140 bytes
-rw-r--r--erts/preloaded/ebin/erts_dirty_process_code_checker.beambin2144 -> 2132 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin11116 -> 10696 bytes
-rw-r--r--erts/preloaded/src/erts_code_purger.erl112
-rw-r--r--erts/preloaded/src/erts_dirty_process_code_checker.erl3
-rw-r--r--erts/preloaded/src/erts_internal.erl45
6 files changed, 51 insertions, 109 deletions
diff --git a/erts/preloaded/ebin/erts_code_purger.beam b/erts/preloaded/ebin/erts_code_purger.beam
index a1eb126098..2dfed3df93 100644
--- a/erts/preloaded/ebin/erts_code_purger.beam
+++ b/erts/preloaded/ebin/erts_code_purger.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_dirty_process_code_checker.beam b/erts/preloaded/ebin/erts_dirty_process_code_checker.beam
index a7ac116c05..df3bc9526b 100644
--- a/erts/preloaded/ebin/erts_dirty_process_code_checker.beam
+++ b/erts/preloaded/ebin/erts_dirty_process_code_checker.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index 22817be8f4..7f6a662f2e 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/src/erts_code_purger.erl b/erts/preloaded/src/erts_code_purger.erl
index ee4fcedd2d..ad51815229 100644
--- a/erts/preloaded/src/erts_code_purger.erl
+++ b/erts/preloaded/src/erts_code_purger.erl
@@ -140,24 +140,13 @@ do_soft_purge(Mod) ->
%% - false, and any processes refer 'Mod', false will
%% returned; otherwise, true.
%%
-%% Requests will be sent to all processes identified by
-%% Pids at once, but without allowing GC to be performed.
-%% Check process code operations that are aborted due to
-%% GC need, will be restarted allowing GC. However, only
-%% ?MAX_CPC_GC_PROCS outstanding operation allowing GC at
-%% a time will be allowed. This in order not to blow up
-%% memory wise.
-%%
-%% We also only allow ?MAX_CPC_NO_OUTSTANDING_KILLS
+%% We only allow ?MAX_CPC_NO_OUTSTANDING_KILLS
%% outstanding kills. This both in order to avoid flooding
%% our message queue with 'DOWN' messages and limiting the
%% amount of memory used to keep references to all
%% outstanding kills.
%%
-%% We maybe should allow more than two outstanding
-%% GC requests, but for now we play it safe...
--define(MAX_CPC_GC_PROCS, 2).
-define(MAX_CPC_NO_OUTSTANDING_KILLS, 10).
-record(cpc_static, {hard, module, tag}).
@@ -172,84 +161,54 @@ check_proc_code(Pids, Mod, Hard) ->
CpcS = #cpc_static{hard = Hard,
module = Mod,
tag = Tag},
- check_proc_code(CpcS, cpc_init(CpcS, Pids, 0), 0, [], #cpc_kill{}, true).
+ check_proc_code(CpcS, cpc_init(CpcS, Pids, 0), #cpc_kill{}, true).
-check_proc_code(#cpc_static{hard = true}, 0, 0, [],
+check_proc_code(#cpc_static{hard = true}, 0,
#cpc_kill{outstanding = [], waiting = [], killed = Killed},
true) ->
%% No outstanding requests. We did a hard check, so result is whether or
%% not we killed any processes...
Killed;
-check_proc_code(#cpc_static{hard = false}, 0, 0, [], _KillState, Success) ->
+check_proc_code(#cpc_static{hard = false}, 0, _KillState, Success) ->
%% No outstanding requests and we did a soft check...
Success;
-check_proc_code(#cpc_static{hard = false, tag = Tag} = CpcS, NoReq0, NoGcReq0,
- [], _KillState, false) ->
+check_proc_code(#cpc_static{hard = false, tag = Tag} = CpcS, NoReq, _KillState, false) ->
%% Failed soft check; just cleanup the remaining replies corresponding
%% to the requests we've sent...
- {NoReq1, NoGcReq1} = receive
- {check_process_code, {Tag, _P, GC}, _Res} ->
- case GC of
- false -> {NoReq0-1, NoGcReq0};
- true -> {NoReq0, NoGcReq0-1}
- end
- end,
- check_proc_code(CpcS, NoReq1, NoGcReq1, [], _KillState, false);
-check_proc_code(#cpc_static{tag = Tag} = CpcS, NoReq0, NoGcReq0, NeedGC0,
- KillState0, Success) ->
-
- %% Check if we should request a GC operation
- {NoGcReq1, NeedGC1} = case NoGcReq0 < ?MAX_CPC_GC_PROCS of
- GcOpAllowed when GcOpAllowed == false;
- NeedGC0 == [] ->
- {NoGcReq0, NeedGC0};
- _ ->
- {NoGcReq0+1, cpc_request_gc(CpcS,NeedGC0)}
- end,
+ receive {check_process_code, {Tag, _P}, _Res} -> ok end,
+ check_proc_code(CpcS, NoReq-1, _KillState, false);
+check_proc_code(#cpc_static{tag = Tag} = CpcS, NoReq0, KillState0, Success) ->
%% Wait for a cpc reply or 'DOWN' message
- {NoReq1, NoGcReq2, Pid, Result, KillState1} = cpc_recv(Tag,
- NoReq0,
- NoGcReq1,
- KillState0),
+ {NoReq1, Pid, Result, KillState1} = cpc_recv(Tag, NoReq0, KillState0),
%% Check the result of the reply
case Result of
- aborted ->
- %% Operation aborted due to the need to GC in order to
- %% determine if the process is referring the module.
- %% Schedule the operation for restart allowing GC...
- check_proc_code(CpcS, NoReq1, NoGcReq2, [Pid|NeedGC1], KillState1,
- Success);
false ->
%% Process not referring the module; done with this process...
- check_proc_code(CpcS, NoReq1, NoGcReq2, NeedGC1, KillState1,
- Success);
+ check_proc_code(CpcS, NoReq1, KillState1, Success);
true ->
%% Process referring the module...
case CpcS#cpc_static.hard of
false ->
%% ... and soft check. The whole operation failed so
%% no point continuing; clean up and fail...
- check_proc_code(CpcS, NoReq1, NoGcReq2, [], KillState1,
- false);
+ check_proc_code(CpcS, NoReq1, KillState1, false);
true ->
%% ... and hard check; schedule kill of it...
- check_proc_code(CpcS, NoReq1, NoGcReq2, NeedGC1,
- cpc_sched_kill(Pid, KillState1), Success)
+ check_proc_code(CpcS, NoReq1, cpc_sched_kill(Pid, KillState1), Success)
end;
'DOWN' ->
%% Handled 'DOWN' message
- check_proc_code(CpcS, NoReq1, NoGcReq2, NeedGC1,
- KillState1, Success)
+ check_proc_code(CpcS, NoReq1, KillState1, Success)
end.
-cpc_recv(Tag, NoReq, NoGcReq, #cpc_kill{outstanding = []} = KillState) ->
+cpc_recv(Tag, NoReq, #cpc_kill{outstanding = []} = KillState) ->
receive
- {check_process_code, {Tag, Pid, GC}, Res} ->
- cpc_handle_cpc(NoReq, NoGcReq, GC, Pid, Res, KillState)
+ {check_process_code, {Tag, Pid}, Res} ->
+ cpc_handle_cpc(NoReq, Pid, Res, KillState)
end;
-cpc_recv(Tag, NoReq, NoGcReq,
+cpc_recv(Tag, NoReq,
#cpc_kill{outstanding = [R0, R1, R2, R3, R4 | _]} = KillState) ->
receive
{'DOWN', R, process, _, _} when R == R0;
@@ -257,21 +216,21 @@ cpc_recv(Tag, NoReq, NoGcReq,
R == R2;
R == R3;
R == R4 ->
- cpc_handle_down(NoReq, NoGcReq, R, KillState);
- {check_process_code, {Tag, Pid, GC}, Res} ->
- cpc_handle_cpc(NoReq, NoGcReq, GC, Pid, Res, KillState)
+ cpc_handle_down(NoReq, R, KillState);
+ {check_process_code, {Tag, Pid}, Res} ->
+ cpc_handle_cpc(NoReq, Pid, Res, KillState)
end;
-cpc_recv(Tag, NoReq, NoGcReq, #cpc_kill{outstanding = [R|_]} = KillState) ->
+cpc_recv(Tag, NoReq, #cpc_kill{outstanding = [R|_]} = KillState) ->
receive
{'DOWN', R, process, _, _} ->
- cpc_handle_down(NoReq, NoGcReq, R, KillState);
- {check_process_code, {Tag, Pid, GC}, Res} ->
- cpc_handle_cpc(NoReq, NoGcReq, GC, Pid, Res, KillState)
+ cpc_handle_down(NoReq, R, KillState);
+ {check_process_code, {Tag, Pid}, Res} ->
+ cpc_handle_cpc(NoReq, Pid, Res, KillState)
end.
-cpc_handle_down(NoReq, NoGcReq, R, #cpc_kill{outstanding = Rs,
- no_outstanding = N} = KillState) ->
- {NoReq, NoGcReq, undefined, 'DOWN',
+cpc_handle_down(NoReq, R, #cpc_kill{outstanding = Rs,
+ no_outstanding = N} = KillState) ->
+ {NoReq, undefined, 'DOWN',
cpc_sched_kill_waiting(KillState#cpc_kill{outstanding = cpc_list_rm(R, Rs),
no_outstanding = N-1})}.
@@ -280,10 +239,8 @@ cpc_list_rm(R, [R|Rs]) ->
cpc_list_rm(R0, [R1|Rs]) ->
[R1|cpc_list_rm(R0, Rs)].
-cpc_handle_cpc(NoReq, NoGcReq, false, Pid, Res, KillState) ->
- {NoReq-1, NoGcReq, Pid, Res, KillState};
-cpc_handle_cpc(NoReq, NoGcReq, true, Pid, Res, KillState) ->
- {NoReq, NoGcReq-1, Pid, Res, KillState}.
+cpc_handle_cpc(NoReq, Pid, Res, KillState) ->
+ {NoReq-1, Pid, Res, KillState}.
cpc_sched_kill_waiting(#cpc_kill{waiting = []} = KillState) ->
KillState;
@@ -308,18 +265,13 @@ cpc_sched_kill(Pid,
no_outstanding = N+1,
killed = true}.
-cpc_request(#cpc_static{tag = Tag, module = Mod}, Pid, AllowGc) ->
- erts_internal:check_process_code(Pid, Mod, [{async, {Tag, Pid, AllowGc}},
- {allow_gc, AllowGc}]).
-
-cpc_request_gc(CpcS, [Pid|Pids]) ->
- cpc_request(CpcS, Pid, true),
- Pids.
+cpc_request(#cpc_static{tag = Tag, module = Mod}, Pid) ->
+ erts_internal:check_process_code(Pid, Mod, [{async, {Tag, Pid}}]).
cpc_init(_CpcS, [], NoReqs) ->
NoReqs;
cpc_init(CpcS, [Pid|Pids], NoReqs) ->
- cpc_request(CpcS, Pid, false),
+ cpc_request(CpcS, Pid),
cpc_init(CpcS, Pids, NoReqs+1).
% end of check_proc_code() implementation.
diff --git a/erts/preloaded/src/erts_dirty_process_code_checker.erl b/erts/preloaded/src/erts_dirty_process_code_checker.erl
index 911642082c..7d3fa264be 100644
--- a/erts/preloaded/src/erts_dirty_process_code_checker.erl
+++ b/erts/preloaded/src/erts_dirty_process_code_checker.erl
@@ -48,8 +48,7 @@ handle_request({Requester,
Prio,
{check_process_code,
ReqId,
- Module,
- _Flags} = Op}) ->
+ Module} = Op}) ->
%%
%% Target may have stopped executing dirty since the
%% initial request was made. Check its current state
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 6229754c8c..e9b99e2745 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -60,7 +60,7 @@
-export([trace/3, trace_pattern/3]).
%% Auto import name clash
--export([check_process_code/2]).
+-export([check_process_code/1]).
%%
%% Await result of send to port
@@ -206,7 +206,7 @@ port_info(_Result, _Item) ->
-spec request_system_task(Pid, Prio, Request) -> 'ok' when
Prio :: 'max' | 'high' | 'normal' | 'low',
Request :: {'garbage_collect', term()}
- | {'check_process_code', term(), module(), non_neg_integer()}
+ | {'check_process_code', term(), module()}
| {'copy_literals', term(), boolean()},
Pid :: pid().
@@ -216,7 +216,7 @@ request_system_task(_Pid, _Prio, _Request) ->
-spec request_system_task(RequesterPid, TargetPid, Prio, Request) -> 'ok' | 'dirty_execution' when
Prio :: 'max' | 'high' | 'normal' | 'low',
Request :: {'garbage_collect', term()}
- | {'check_process_code', term(), module(), non_neg_integer()}
+ | {'check_process_code', term(), module()}
| {'copy_literals', term(), boolean()},
RequesterPid :: pid(),
TargetPid :: pid().
@@ -224,12 +224,9 @@ request_system_task(_Pid, _Prio, _Request) ->
request_system_task(_RequesterPid, _TargetPid, _Prio, _Request) ->
erlang:nif_error(undefined).
--define(ERTS_CPC_ALLOW_GC, (1 bsl 0)).
-
--spec check_process_code(Module, Flags) -> boolean() when
- Module :: module(),
- Flags :: non_neg_integer().
-check_process_code(_Module, _Flags) ->
+-spec check_process_code(Module) -> boolean() when
+ Module :: module().
+check_process_code(_Module) ->
erlang:nif_error(undefined).
-spec check_process_code(Pid, Module, OptionList) -> CheckResult | async when
@@ -240,7 +237,7 @@ check_process_code(_Module, _Flags) ->
OptionList :: [Option],
CheckResult :: boolean() | aborted.
check_process_code(Pid, Module, OptionList) ->
- {Async, Flags} = get_cpc_opts(OptionList, sync, ?ERTS_CPC_ALLOW_GC),
+ Async = get_cpc_opts(OptionList, sync),
case Async of
{async, ReqId} ->
{priority, Prio} = erlang:process_info(erlang:self(),
@@ -249,13 +246,12 @@ check_process_code(Pid, Module, OptionList) ->
Prio,
{check_process_code,
ReqId,
- Module,
- Flags}),
+ Module}),
async;
sync ->
case Pid == erlang:self() of
true ->
- erts_internal:check_process_code(Module, Flags);
+ erts_internal:check_process_code(Module);
false ->
{priority, Prio} = erlang:process_info(erlang:self(),
priority),
@@ -264,8 +260,7 @@ check_process_code(Pid, Module, OptionList) ->
Prio,
{check_process_code,
ReqId,
- Module,
- Flags}),
+ Module}),
receive
{check_process_code, ReqId, CheckResult} ->
CheckResult
@@ -273,18 +268,14 @@ check_process_code(Pid, Module, OptionList) ->
end
end.
-% gets async and flag opts and verify valid option list
-get_cpc_opts([{async, _ReqId} = AsyncTuple | Options], _OldAsync, Flags) ->
- get_cpc_opts(Options, AsyncTuple, Flags);
-get_cpc_opts([{allow_gc, AllowGC} | Options], Async, Flags) ->
- get_cpc_opts(Options, Async, cpc_flags(Flags, ?ERTS_CPC_ALLOW_GC, AllowGC));
-get_cpc_opts([], Async, Flags) ->
- {Async, Flags}.
-
-cpc_flags(OldFlags, Bit, true) ->
- OldFlags bor Bit;
-cpc_flags(OldFlags, Bit, false) ->
- OldFlags band (bnot Bit).
+% gets async opt and verify valid option list
+get_cpc_opts([{async, _ReqId} = AsyncTuple | Options], _OldAsync) ->
+ get_cpc_opts(Options, AsyncTuple);
+get_cpc_opts([{allow_gc, AllowGC} | Options], Async) when AllowGC == true;
+ AllowGC == false ->
+ get_cpc_opts(Options, Async);
+get_cpc_opts([], Async) ->
+ Async.
-spec check_dirty_process_code(Pid,Module) -> 'true' | 'false' when
Pid :: pid(),