summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRickard Green <rickard@erlang.org>2021-03-26 04:01:21 +0100
committerRickard Green <rickard@erlang.org>2021-04-21 14:23:01 +0200
commitfd68be9571caaee596ef5c04badfd2dae145a60c (patch)
tree84a9728677fee6fda283545bb9e23bc1e7774989
parent7fe7fa3dde556b5b92522f8279d465bb52baf1f6 (diff)
downloaderlang-fd68be9571caaee596ef5c04badfd2dae145a60c.tar.gz
Ensure GC and CPC signals respect signal order
'garbage-collect' signals and 'check-process-code' signals could pass before other signals sent from one process to another. That is, they could be delivered too early.
-rw-r--r--erts/emulator/beam/atom.names2
-rw-r--r--erts/emulator/beam/erl_process.c161
-rw-r--r--erts/emulator/test/code_SUITE.erl50
-rw-r--r--erts/emulator/test/gc_SUITE.erl47
-rw-r--r--erts/emulator/test/process_SUITE.erl50
-rw-r--r--erts/preloaded/ebin/erlang.beambin101968 -> 101832 bytes
-rw-r--r--erts/preloaded/ebin/erts_internal.beambin17852 -> 17672 bytes
-rw-r--r--erts/preloaded/src/erlang.erl8
-rw-r--r--erts/preloaded/src/erts_internal.erl10
9 files changed, 272 insertions, 56 deletions
diff --git a/erts/emulator/beam/atom.names b/erts/emulator/beam/atom.names
index 291bc95604..ceb8c56623 100644
--- a/erts/emulator/beam/atom.names
+++ b/erts/emulator/beam/atom.names
@@ -278,6 +278,7 @@ atom free
atom fullsweep_after
atom functions
atom function_clause
+atom garbage_collect
atom garbage_collecting
atom garbage_collection
atom garbage_collection_info
@@ -328,6 +329,7 @@ atom infinity
atom info
atom info_msg
atom info_trap
+atom inherit
atom init
atom initial_call
atom input
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 1f464e2e5a..d0ae08793a 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -437,7 +437,8 @@ typedef enum {
ERTS_PSTT_COHMQ, /* Change off heap message queue */
ERTS_PSTT_FTMQ, /* Flush trace msg queue */
ERTS_PSTT_ETS_FREE_FIXATION,
- ERTS_PSTT_PRIO_SIG /* Elevate prio on signal management */
+ ERTS_PSTT_PRIO_SIG, /* Elevate prio on signal management */
+ ERTS_PSTT_TEST
} ErtsProcSysTaskType;
#define ERTS_MAX_PROC_SYS_TASK_ARGS 2
@@ -446,6 +447,7 @@ struct ErtsProcSysTask_ {
ErtsProcSysTask *next;
ErtsProcSysTask *prev;
ErtsProcSysTaskType type;
+ Eterm prio;
Eterm requester;
Eterm reply_tag;
Eterm req_id;
@@ -10386,6 +10388,9 @@ execute_sys_tasks(Process *c_p, erts_aint32_t *statep, int in_reds)
}
break;
}
+ case ERTS_PSTT_TEST:
+ st_res = am_true;
+ break;
default:
ERTS_INTERNAL_ERROR("Invalid process sys task type");
st_res = am_false;
@@ -10443,6 +10448,7 @@ cleanup_sys_tasks(Process *c_p, erts_aint32_t in_state, int in_reds)
case ERTS_PSTT_CPC:
case ERTS_PSTT_COHMQ:
case ERTS_PSTT_ETS_FREE_FIXATION:
+ case ERTS_PSTT_TEST:
st_res = am_false;
break;
case ERTS_PSTT_CLA:
@@ -10584,7 +10590,7 @@ erts_execute_dirty_system_task(Process *c_p)
static BIF_RETTYPE
dispatch_system_task(Process *c_p, erts_aint_t fail_state,
ErtsProcSysTask *st, Eterm target,
- Eterm prio, Eterm operation)
+ Eterm operation)
{
Process *rp;
ErtsProcLocks rp_locks = 0;
@@ -10596,9 +10602,19 @@ dispatch_system_task(Process *c_p, erts_aint_t fail_state,
switch (st->type) {
case ERTS_PSTT_CPC:
- rp = erts_dirty_process_signal_handler;
ASSERT(fail_state & (ERTS_PSFLG_DIRTY_RUNNING
| ERTS_PSFLG_DIRTY_RUNNING_SYS));
+ switch (st->prio) {
+ case am_max:
+ rp = erts_dirty_process_signal_handler_max;
+ break;
+ case am_high:
+ rp = erts_dirty_process_signal_handler_high;
+ break;
+ default:
+ rp = erts_dirty_process_signal_handler;
+ break;
+ }
if (c_p == rp) {
ERTS_BIF_PREP_RET(ret, am_dirty_execution);
return ret;
@@ -10618,7 +10634,7 @@ dispatch_system_task(Process *c_p, erts_aint_t fail_state,
ASSERT(is_immed(st->requester));
ASSERT(is_immed(target));
- ASSERT(is_immed(prio));
+ ASSERT(is_immed(st->prio));
osz = size_object(operation);
hsz = 5 /* 4-tuple */ + osz;
@@ -10626,7 +10642,7 @@ dispatch_system_task(Process *c_p, erts_aint_t fail_state,
mp = erts_alloc_message_heap(rp, &rp_locks, hsz, &hp, &ohp);
msg = copy_struct(operation, osz, &hp, ohp);
- msg = TUPLE4(hp, st->requester, target, prio, msg);
+ msg = TUPLE4(hp, st->requester, target, st->prio, msg);
erts_queue_message(rp, rp_locks, mp, msg, am_system);
@@ -10636,16 +10652,19 @@ dispatch_system_task(Process *c_p, erts_aint_t fail_state,
return ret;
}
+static Eterm
+sched_sig_sys_task(Process *c_p, void *vst, int *redsp, ErlHeapFragment **bp);
static BIF_RETTYPE
request_system_task(Process *c_p, Eterm requester, Eterm target,
- Eterm priority, Eterm operation)
+ Eterm priority_req, Eterm operation)
{
BIF_RETTYPE ret;
Process *rp = erts_proc_lookup(target);
ErtsProcSysTask *st = NULL;
erts_aint32_t prio, fail_state = ERTS_PSFLG_EXITING;
- Eterm noproc_res, req_type;
+ Eterm noproc_res, req_type, priority = priority_req;
+ int signal = 0;
if (!rp && !is_internal_pid(target)) {
if (!is_external_pid(target))
@@ -10654,12 +10673,27 @@ request_system_task(Process *c_p, Eterm requester, Eterm target,
goto badarg;
}
- switch (priority) {
+ switch (priority_req) {
case am_max: prio = PRIORITY_MAX; break;
case am_high: prio = PRIORITY_HIGH; break;
case am_normal: prio = PRIORITY_NORMAL; break;
case am_low: prio = PRIORITY_LOW; break;
- default: goto badarg;
+ case am_inherit: {
+ erts_aint32_t state = erts_atomic32_read_nob(&c_p->state);
+ prio = ERTS_PSFLGS_GET_USR_PRIO(state);
+ switch (prio) {
+ case PRIORITY_MAX: priority = am_max; break;
+ case PRIORITY_HIGH: priority = am_high; break;
+ case PRIORITY_NORMAL: priority = am_normal; break;
+ case PRIORITY_LOW: priority = am_low; break;
+ default:
+ ERTS_INTERNAL_ERROR("Unexpected prio");
+ break;
+ }
+ break;
+ }
+ default:
+ goto badarg;
}
if (is_not_tuple(operation))
@@ -10705,6 +10739,7 @@ request_system_task(Process *c_p, Eterm requester, Eterm target,
hp = &st->heap[0];
st->requester = requester;
+ st->prio = priority;
st->reply_tag = req_type;
st->req_id_sz = req_id_sz;
st->req_id = req_id_sz == 0 ? req_id : copy_struct(req_id,
@@ -10720,9 +10755,13 @@ request_system_task(Process *c_p, Eterm requester, Eterm target,
ASSERT(&st->heap[0] + tot_sz == hp);
}
+ ERTS_BIF_PREP_RET(ret, am_ok);
+
switch (req_type) {
case am_garbage_collect:
+ if (c_p->common.id == requester)
+ signal = !0;
switch (st->arg[0]) {
case am_minor: st->type = ERTS_PSTT_GC_MINOR; break;
case am_major: st->type = ERTS_PSTT_GC_MAJOR; break;
@@ -10734,6 +10773,8 @@ request_system_task(Process *c_p, Eterm requester, Eterm target,
break;
case am_check_process_code:
+ if (c_p->common.id == requester)
+ signal = !0;
if (is_not_atom(st->arg[0]))
goto badarg;
noproc_res = am_false;
@@ -10759,30 +10800,60 @@ request_system_task(Process *c_p, Eterm requester, Eterm target,
break;
default:
+ if (ERTS_IS_ATOM_STR("system_task_test", req_type)) {
+ st->type = ERTS_PSTT_TEST;
+ noproc_res = am_false;
+ if (!rp)
+ goto noproc;
+ break;
+ }
goto badarg;
}
+ ASSERT(rp);
+
+ if (signal) {
+ erts_aint32_t state;
+ if (priority_req != am_inherit)
+ goto badarg;
+ state = erts_atomic32_read_acqb(&rp->state);
+ if (state & fail_state & ERTS_PSFLG_EXITING)
+ goto noproc;
+ if (state & (ERTS_PSFLG_SIG_Q | ERTS_PSFLG_SIG_IN_Q)) {
+ /*
+ * Send rpc request signal without reply,
+ * and reply from the system task...
+ */
+ Eterm res = erts_proc_sig_send_rpc_request(c_p,
+ target,
+ 0, /* no reply */
+ sched_sig_sys_task,
+ (void *) st);
+ if (is_non_value(res))
+ goto noproc;
+ return ret; /* signal sent... */
+ }
+ /*
+ * schedule system task directly since we wont violate
+ * signal order...
+ */
+ }
if (!schedule_process_sys_task(rp, prio, st, &fail_state)) {
- Eterm failure;
if (fail_state & ERTS_PSFLG_EXITING) {
noproc:
- failure = noproc_res;
+ notify_sys_task_executed(c_p, st, noproc_res, 1);
}
else if (fail_state & (ERTS_PSFLG_DIRTY_RUNNING
| ERTS_PSFLG_DIRTY_RUNNING_SYS)) {
ret = dispatch_system_task(c_p, fail_state, st,
- target, priority, operation);
+ target, operation);
goto cleanup_return;
}
else {
ERTS_INTERNAL_ERROR("Unknown failure schedule_process_sys_task()");
- failure = am_internal_error;
}
- notify_sys_task_executed(c_p, st, failure, 1);
}
- ERTS_BIF_PREP_RET(ret, am_ok);
-
return ret;
badarg:
@@ -10799,6 +10870,64 @@ cleanup_return:
return ret;
}
+static Eterm
+sched_sig_sys_task(Process *c_p, void *vst, int *redsp, ErlHeapFragment **bp)
+{
+ ErtsProcSysTask *st = (ErtsProcSysTask *) vst;
+ erts_aint32_t prio, fail_state = ERTS_PSFLG_EXITING;
+ Eterm priority = st->prio;
+
+ switch (priority) {
+ case am_max: prio = PRIORITY_MAX; break;
+ case am_high: prio = PRIORITY_HIGH; break;
+ case am_normal: prio = PRIORITY_NORMAL; break;
+ case am_low: prio = PRIORITY_LOW; break;
+ default:
+ ERTS_INTERNAL_ERROR("Invalid prio");
+ prio = -1;
+ break;
+ }
+
+ switch (st->reply_tag) {
+ case am_garbage_collect:
+ break;
+ case am_check_process_code:
+ fail_state |= ERTS_PSFLG_DIRTY_RUNNING;
+ break;
+ default:
+ ERTS_INTERNAL_ERROR("system task not supported as signal");
+ break;
+ }
+ if (!schedule_process_sys_task(c_p, prio, st, &fail_state)) {
+ if (fail_state & (ERTS_PSFLG_EXITING|ERTS_PSFLG_FREE))
+ notify_sys_task_executed(c_p, st, am_false, 1);
+ else if (fail_state & ERTS_PSFLG_DIRTY_RUNNING) {
+ int i, arity = 2;
+ Eterm heap[1 + 2 + ERTS_MAX_PROC_SYS_TASK_ARGS];
+ heap[1] = st->reply_tag;
+ heap[2] = st->req_id;
+ for (i = 0;
+ i < ERTS_MAX_PROC_SYS_TASK_ARGS && is_value(st->arg[i]);
+ i++) {
+ arity++;
+ heap[3 + i] = st->arg[i];
+ }
+ heap[0] = make_arityval(arity);
+ (void) dispatch_system_task(c_p, fail_state, st,
+ c_p->common.id, make_tuple(&heap[0]));
+ erts_cleanup_offheap(&st->off_heap);
+ erts_free(ERTS_ALC_T_PROC_SYS_TSK, st);
+ }
+ else {
+ ERTS_INTERNAL_ERROR("Unknown failure schedule_process_sys_task()");
+ }
+ }
+
+ *redsp = 1;
+
+ return THE_NON_VALUE;
+}
+
BIF_RETTYPE
erts_internal_request_system_task_3(BIF_ALIST_3)
{
diff --git a/erts/emulator/test/code_SUITE.erl b/erts/emulator/test/code_SUITE.erl
index 0444ba4f89..cea6d240ad 100644
--- a/erts/emulator/test/code_SUITE.erl
+++ b/erts/emulator/test/code_SUITE.erl
@@ -28,7 +28,9 @@
fake_literals/1,
false_dependency/1,coverage/1,fun_confusion/1,
t_copy_literals/1, t_copy_literals_frags/1,
- erl_544/1, max_heap_size/1]).
+ erl_544/1, max_heap_size/1,
+ check_process_code_signal_order/1,
+ check_process_code_dirty_exec_proc/1]).
-define(line_trace, 1).
-include_lib("common_test/include/ct.hrl").
@@ -43,7 +45,8 @@ all() ->
constant_pools, constant_refc_binaries, fake_literals,
false_dependency,
coverage, fun_confusion, t_copy_literals, t_copy_literals_frags,
- erl_544, max_heap_size].
+ erl_544, max_heap_size, check_process_code_signal_order,
+ check_process_code_dirty_exec_proc].
init_per_suite(Config) ->
erts_debug:set_internal_state(available_internal_state, true),
@@ -1001,6 +1004,49 @@ max_heap_size_proc(Mod) ->
_ -> Value
end.
+check_process_code_signal_order(Config) when is_list(Config) ->
+ process_flag(scheduler, 1),
+ process_flag(priority, high),
+ {module,versions} = erlang:load_module(versions, compile_version(1, Config)),
+ Pid = spawn_opt(versions, loop, [], [{scheduler, 1}]),
+ true = erlang:delete_module(versions),
+ true = erlang:check_process_code(Pid, versions),
+ Ref = make_ref(),
+ spam_signals(Pid, 10000),
+ %% EXIT signal *should* arrive...
+ exit(Pid, kill),
+ %% ... before CPC signal...
+ async = erlang:check_process_code(Pid, versions, [{async, Ref}]),
+ %% ... which means that the result of the check_process_code *should* be 'false'...
+ false = busy_wait_cpc_res(Ref),
+ ok.
+
+busy_wait_cpc_res(Ref) ->
+ receive
+ {check_process_code, Ref, Res} ->
+ Res
+ after 0 ->
+ busy_wait_cpc_res(Ref)
+ end.
+
+spam_signals(P, N) when N =< 0 ->
+ ok;
+spam_signals(P, N) ->
+ link(P),
+ unlink(P),
+ spam_signals(P, N-2).
+
+check_process_code_dirty_exec_proc(Config) when is_list(Config) ->
+ Pid = spawn(fun () ->
+ erts_debug:dirty_io(wait, 10000)
+ end),
+ receive after 100 -> ok end,
+ false = erlang:check_process_code(Pid, non_existing_module),
+ {status, running} = process_info(Pid, status),
+ exit(Pid, kill),
+ false = is_process_alive(Pid),
+ ok.
+
%% Utilities.
make_sub_binary(Bin) when is_binary(Bin) ->
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index f3942ef416..810409175e 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -33,7 +33,9 @@
grow_stack_heap/1,
max_heap_size/1,
minor_major_gc_option_async/1,
- minor_major_gc_option_self/1
+ minor_major_gc_option_self/1,
+ gc_signal_order/1,
+ gc_dirty_exec_proc/1
]).
suite() ->
@@ -42,7 +44,7 @@ suite() ->
all() ->
[grow_heap, grow_stack, grow_stack_heap, max_heap_size,
minor_major_gc_option_self,
- minor_major_gc_option_async].
+ minor_major_gc_option_async, gc_signal_order, gc_dirty_exec_proc].
%% Produce a growing list of elements,
@@ -248,6 +250,43 @@ minor_major_gc_option_async(_Config) ->
end
end, [gc_minor_start, gc_minor_end]).
+gc_signal_order(Config) when is_list(Config) ->
+ process_flag(scheduler, 1),
+ process_flag(priority, high),
+ Ref = make_ref(),
+ Pid = spawn_opt(fun () -> receive after infinity -> ok end end,[{scheduler, 1}]),
+ spam_signals(Pid, 10000),
+ %% EXIT signal *should* arrive...
+ exit(Pid, kill),
+ %% ... before GC signal...
+ async = garbage_collect(Pid, [{async, Ref}]),
+ %% ... which means that the result of the gc *should* be 'false'...
+ false = busy_wait_gc_res(Ref),
+ ok.
+
+busy_wait_gc_res(Ref) ->
+ receive
+ {garbage_collect, Ref, Res} ->
+ Res
+ after 0 ->
+ busy_wait_gc_res(Ref)
+ end.
+
+spam_signals(P, N) when N =< 0 ->
+ ok;
+spam_signals(P, N) ->
+ link(P),
+ unlink(P),
+ spam_signals(P, N-2).
+
+gc_dirty_exec_proc(Config) when is_list(Config) ->
+ check_gc_tracing_around(
+ fun(Pid, _Ref) ->
+ Pid ! {dirty_exec, 1000},
+ receive after 100 -> ok end,
+ true = erlang:garbage_collect(Pid, [{type, major}])
+ end, [gc_major_start, gc_major_end]).
+
%% Traces garbage collection around the given operation, and fails the test if
%% it results in any unexpected messages or if the expected trace tags are not
%% received.
@@ -257,7 +296,9 @@ check_gc_tracing_around(Fun, ExpectedTraceTags) ->
fun Endless() ->
receive
{gc, Ref, Type} ->
- erlang:garbage_collect(self(), [{type, Type}])
+ erlang:garbage_collect(self(), [{type, Type}]);
+ {dirty_exec, Time} ->
+ erts_debug:dirty_io(wait, 1000)
after 100 ->
ok
end,
diff --git a/erts/emulator/test/process_SUITE.erl b/erts/emulator/test/process_SUITE.erl
index 0cb0d6c1e2..fd770aaccd 100644
--- a/erts/emulator/test/process_SUITE.erl
+++ b/erts/emulator/test/process_SUITE.erl
@@ -2510,6 +2510,8 @@ do_otp_7738_test(Type) ->
gor(Reds, Stop) ->
receive
+ drop_me ->
+ gor(Reds+1, Stop);
{From, reds} ->
From ! {reds, Reds, self()},
gor(Reds+1, Stop);
@@ -2522,7 +2524,11 @@ gor(Reds, Stop) ->
garb_other_running(Config) when is_list(Config) ->
Stop = make_ref(),
{Pid, Mon} = spawn_monitor(fun () -> gor(0, Stop) end),
- Reds = lists:foldl(fun (_, OldReds) ->
+ Reds = lists:foldl(fun (N, OldReds) ->
+ case N rem 2 of
+ 0 -> Pid ! drop_me;
+ _ -> ok
+ end,
erlang:garbage_collect(Pid),
receive after 1 -> ok end,
Pid ! {self(), reds},
@@ -2586,18 +2592,18 @@ no_priority_inversion2(Config) when is_list(Config) ->
tok_loop()
end,
[{priority, low}, monitor, link]),
- RL = request_gc(PL, low),
- RN = request_gc(PL, normal),
- RH = request_gc(PL, high),
+ RL = request_test(PL, low),
+ RN = request_test(PL, normal),
+ RH = request_test(PL, high),
receive
- {garbage_collect, _, _} ->
- ct:fail(unexpected_gc)
+ {system_task_test, _, _} ->
+ ct:fail(unexpected_system_task_completed)
after 1000 ->
ok
end,
- RM = request_gc(PL, max),
+ RM = request_test(PL, max),
receive
- {garbage_collect, RM, true} ->
+ {system_task_test, RM, true} ->
ok
end,
lists:foreach(fun ({P, _}) ->
@@ -2611,15 +2617,15 @@ no_priority_inversion2(Config) when is_list(Config) ->
end
end, MTLs),
receive
- {garbage_collect, RH, true} ->
+ {system_task_test, RH, true} ->
ok
end,
receive
- {garbage_collect, RN, true} ->
+ {system_task_test, RN, true} ->
ok
end,
receive
- {garbage_collect, RL, true} ->
+ {system_task_test, RL, true} ->
ok
end,
unlink(PL),
@@ -2631,18 +2637,18 @@ no_priority_inversion2(Config) when is_list(Config) ->
process_flag(priority, Prio),
ok.
-request_gc(Pid, Prio) ->
+request_test(Pid, Prio) ->
Ref = make_ref(),
- erts_internal:request_system_task(Pid, Prio, {garbage_collect, Ref, major}),
+ erts_internal:request_system_task(Pid, Prio, {system_task_test, Ref}),
Ref.
system_task_blast(Config) when is_list(Config) ->
Me = self(),
GCReq = fun () ->
- RL = gc_req(Me, 100),
+ RL = test_req(Me, 100),
lists:foreach(fun (R) ->
receive
- {garbage_collect, R, true} ->
+ {system_task_test, R, true} ->
ok
end
end, RL),
@@ -2657,14 +2663,14 @@ system_task_blast(Config) when is_list(Config) ->
end, HTLs),
ok.
-gc_req(_Pid, 0) ->
+test_req(_Pid, 0) ->
[];
-gc_req(Pid, N) ->
- R0 = request_gc(Pid, low),
- R1 = request_gc(Pid, normal),
- R2 = request_gc(Pid, high),
- R3 = request_gc(Pid, max),
- [R0, R1, R2, R3 | gc_req(Pid, N-1)].
+test_req(Pid, N) ->
+ R0 = request_test(Pid, low),
+ R1 = request_test(Pid, normal),
+ R2 = request_test(Pid, high),
+ R3 = request_test(Pid, max),
+ [R0, R1, R2, R3 | test_req(Pid, N-1)].
system_task_on_suspended(Config) when is_list(Config) ->
{P, M} = spawn_monitor(fun () ->
diff --git a/erts/preloaded/ebin/erlang.beam b/erts/preloaded/ebin/erlang.beam
index ee96878ff7..563eb8744a 100644
--- a/erts/preloaded/ebin/erlang.beam
+++ b/erts/preloaded/ebin/erlang.beam
Binary files differ
diff --git a/erts/preloaded/ebin/erts_internal.beam b/erts/preloaded/ebin/erts_internal.beam
index bc53a2e431..03b79f0fa8 100644
--- a/erts/preloaded/ebin/erts_internal.beam
+++ b/erts/preloaded/ebin/erts_internal.beam
Binary files differ
diff --git a/erts/preloaded/src/erlang.erl b/erts/preloaded/src/erlang.erl
index 5730e999cb..4bb3b84223 100644
--- a/erts/preloaded/src/erlang.erl
+++ b/erts/preloaded/src/erlang.erl
@@ -931,21 +931,17 @@ garbage_collect(Pid, OptionList) ->
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, GcOpts#gcopt.type}),
+ Pid, inherit, {garbage_collect, ReqId, GcOpts#gcopt.type}),
async;
sync ->
case Pid == erlang:self() of
true ->
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,
+ Pid, inherit,
{garbage_collect, ReqId, GcOpts#gcopt.type}),
receive
{garbage_collect, ReqId, GCResult} ->
diff --git a/erts/preloaded/src/erts_internal.erl b/erts/preloaded/src/erts_internal.erl
index 305b524438..57015a64c8 100644
--- a/erts/preloaded/src/erts_internal.erl
+++ b/erts/preloaded/src/erts_internal.erl
@@ -241,7 +241,7 @@ port_info(_Result, _Item) ->
erlang:nif_error(undefined).
-spec request_system_task(Pid, Prio, Request) -> 'ok' when
- Prio :: 'max' | 'high' | 'normal' | 'low',
+ Prio :: 'max' | 'high' | 'normal' | 'low' | 'inherit',
Type :: 'major' | 'minor',
Request :: {'garbage_collect', term(), Type}
| {'check_process_code', term(), module()}
@@ -283,10 +283,8 @@ check_process_code(Pid, Module, OptionList) ->
Async = get_cpc_opts(OptionList, sync),
case Async of
{async, ReqId} ->
- {priority, Prio} = erlang:process_info(erlang:self(),
- priority),
erts_internal:request_system_task(Pid,
- Prio,
+ inherit,
{check_process_code,
ReqId,
Module}),
@@ -296,11 +294,9 @@ check_process_code(Pid, Module, OptionList) ->
true ->
erts_internal:check_process_code(Module);
false ->
- {priority, Prio} = erlang:process_info(erlang:self(),
- priority),
ReqId = erlang:make_ref(),
erts_internal:request_system_task(Pid,
- Prio,
+ inherit,
{check_process_code,
ReqId,
Module}),