diff options
author | Erlang/OTP <otp@erlang.org> | 2020-03-04 08:23:50 +0100 |
---|---|---|
committer | Erlang/OTP <otp@erlang.org> | 2020-03-04 08:23:50 +0100 |
commit | d7b423584bc4f950f0208d3d4108d26bf6da905e (patch) | |
tree | 91099cea4246e70746d729c61e9165c9cc148b75 | |
parent | b3f5b04e05fedfc5a05e8121c225cc1ebbd39403 (diff) | |
parent | 180c5e1782a94db9c6a7211bfe3a2fd159fb6111 (diff) | |
download | erlang-d7b423584bc4f950f0208d3d4108d26bf6da905e.tar.gz |
Merge branch 'rickard/dirty-low-prio-bug/ERL-1157/OTP-16446' into maint-21
* rickard/dirty-low-prio-bug/ERL-1157/OTP-16446:
Fix low priority dirty execution
# Conflicts:
# erts/emulator/test/scheduler_SUITE.erl
-rw-r--r-- | erts/emulator/beam/erl_process.c | 19 | ||||
-rw-r--r-- | erts/emulator/test/scheduler_SUITE.erl | 77 |
2 files changed, 94 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index dbcac4459b..2c4bd2b0f5 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9648,6 +9648,24 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) ASSERT(p); /* Wrong qmask in rq->flags? */ +#ifdef DEBUG + switch (((erts_aint32_t) 1) << ERTS_PSFLGS_GET_PRQ_PRIO(state)) { + case MAX_BIT: + ASSERT(qbit == MAX_BIT); + break; + case HIGH_BIT: + ASSERT(qbit == HIGH_BIT); + break; + case NORMAL_BIT: + case LOW_BIT: + ASSERT(qbit == NORMAL_BIT || qbit == LOW_BIT); + break; + default: + ASSERT(0); + break; + } +#endif + if (is_normal_sched) { psflg_running = ERTS_PSFLG_RUNNING; psflg_running_sys = ERTS_PSFLG_RUNNING_SYS; @@ -9658,6 +9676,7 @@ Process *erts_schedule(ErtsSchedulerData *esdp, Process *p, int calls) psflg_running = ERTS_PSFLG_DIRTY_RUNNING; psflg_running_sys = ERTS_PSFLG_DIRTY_RUNNING_SYS; psflg_band_mask = ~((erts_aint32_t) 0); + qbit = ((erts_aint32_t) 1) << ERTS_PSFLGS_GET_PRQ_PRIO(state); } if (!(state & ERTS_PSFLG_PROXY)) diff --git a/erts/emulator/test/scheduler_SUITE.erl b/erts/emulator/test/scheduler_SUITE.erl index f61949c75b..59cf66d277 100644 --- a/erts/emulator/test/scheduler_SUITE.erl +++ b/erts/emulator/test/scheduler_SUITE.erl @@ -58,7 +58,8 @@ scheduler_suspend/1, dirty_scheduler_threads/1, poll_threads/1, - reader_groups/1]). + reader_groups/1, + otp_16446/1]). suite() -> [{ct_hooks,[ts_install_cth]}, @@ -74,7 +75,8 @@ all() -> scheduler_suspend_basic, scheduler_suspend, dirty_scheduler_threads, poll_threads, - reader_groups]. + reader_groups, + otp_16446]. groups() -> [{scheduler_bind, [], @@ -1794,6 +1796,77 @@ reader_groups_map(CPUT, Groups) -> erlang:system_flag(cpu_topology, Old), lists:sort(Res). +otp_16446(Config) when is_list(Config) -> + ct:timetrap({minutes, 1}), + + process_flag(priority, high), + + DIO = erlang:system_info(dirty_io_schedulers), + NoPrioProcs = 10*DIO, + io:format("DIO = ~p~nNoPrioProcs = ~p~n", [DIO, NoPrioProcs]), + + DirtyLoop = fun Loop(P, N) -> + erts_debug:dirty_io(wait,1), + receive {get, From} -> From ! {P, N} + after 0 -> Loop(P,N+1) + end + end, + + Spawn = fun SpawnLoop(_Prio, 0, Acc) -> + Acc; + SpawnLoop(Prio, N, Acc) -> + Pid = spawn_opt(fun () -> DirtyLoop(Prio, 0) end, + [link, {priority, Prio}]), + SpawnLoop(Prio, N-1, [Pid|Acc]) + end, + + Ns = Spawn(normal, NoPrioProcs, []), + Ls = Spawn(low, NoPrioProcs, []), + + receive after 10000 -> ok end, + + RequestInfo = fun (P) -> P ! {get, self()} end, + lists:foreach(RequestInfo, Ns), + lists:foreach(RequestInfo, Ls), + + Collect = fun CollectFun(0, LLs, NLs) -> + {LLs, NLs}; + CollectFun(N, LLs, NLs) -> + receive + {low, Calls} -> + CollectFun(N-1, LLs+Calls, NLs); + {normal, Calls} -> + CollectFun(N-1, LLs, NLs+Calls) + end + end, + + {LLs, NLs} = Collect(2*NoPrioProcs, 0, 0), + + %% expected ratio 0.125, but this is not especially exact... + Ratio = LLs / NLs, + + io:format("LLs = ~p~nNLs = ~p~nRatio = ~p~n", [LLs, NLs, Ratio]), + + true = Ratio > 0.05, + true = Ratio < 0.5, + + WaitUntilDead = fun (P) -> + case is_process_alive(P) of + false -> + ok; + true -> + unlink(P), + exit(P, kill), + false = is_process_alive(P) + end + end, + + lists:foreach(WaitUntilDead, Ns), + lists:foreach(WaitUntilDead, Ls), + Comment = "low/normal ratio: " ++ erlang:float_to_list(Ratio,[{decimals,4}]), + erlang:display(Comment), + {comment, Comment}. + %% %% Utils %% |