From 56018ef95e70c5630c1c6fe16d22b54f8ecd0791 Mon Sep 17 00:00:00 2001 From: Sverker Eriksson Date: Thu, 27 Mar 2014 20:59:01 +0100 Subject: erts: Fix bug of scheduling a suspended process This is a race that can cause RUNNING (instead of RUNNING_SYS) set on a SUSPENDED process. The effect of this race happening is probably quite benign. The bug was discovered by process_SUITE:processes_gc_trap on debug VM crashing on last assert in schedule(): /* Never run a suspended process */ ASSERT(!(ERTS_PSFLG_SUSPENDED & erts_smp_atomic32_read_nob(&p->state))); --- erts/emulator/beam/erl_process.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'erts') diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 37e1d07107..bc69d5ad91 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -9207,7 +9207,6 @@ Process *schedule(Process *p, int calls) */ pick_next_process: { erts_aint32_t psflg_band_mask; - erts_aint32_t running_flag; int prio_q; int qmask; @@ -9269,12 +9268,6 @@ Process *schedule(Process *p, int calls) state = erts_smp_atomic32_read_nob(&p->state); } - - if (state & ERTS_PSFLG_ACTIVE_SYS) - running_flag = ERTS_PSFLG_RUNNING_SYS; - else - running_flag = ERTS_PSFLG_RUNNING; - while (1) { erts_aint32_t exp, new, tmp; tmp = new = exp = state; @@ -9284,8 +9277,12 @@ Process *schedule(Process *p, int calls) tmp = state & (ERTS_PSFLG_SUSPENDED | ERTS_PSFLG_PENDING_EXIT | ERTS_PSFLG_ACTIVE_SYS); - if (tmp != ERTS_PSFLG_SUSPENDED) - new |= running_flag; + if (tmp != ERTS_PSFLG_SUSPENDED) { + if (state & ERTS_PSFLG_ACTIVE_SYS) + new |= ERTS_PSFLG_RUNNING_SYS; + else + new |= ERTS_PSFLG_RUNNING; + } } state = erts_smp_atomic32_cmpxchg_relb(&p->state, new, exp); if (state == exp) { -- cgit v1.2.3