diff options
author | Rickard Green <[email protected]> | 2010-01-22 13:47:23 +0000 |
---|---|---|
committer | Erlang/OTP <[email protected]> | 2010-01-22 13:47:23 +0000 |
commit | e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5 (patch) | |
tree | d4014c55c5cd8c4559c9227b25e187e0f457fc46 /erts/emulator/beam | |
parent | c7187afaf4d672e0320a73708fe44d5ac5520b52 (diff) | |
download | otp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.tar.gz otp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.tar.bz2 otp-e19d6e4463a9cc3b738fd32a46e0ce9282a70fd5.zip |
OTP-8386 Immediately repeated multi-scheduling block/unblock cycles using
erlang:system_flag(multi_scheduling, block | unblock) could
deadlock the runtime system.
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r-- | erts/emulator/beam/erl_process.c | 22 |
1 files changed, 13 insertions, 9 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 476e29d96f..b519b39d63 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -2522,8 +2522,11 @@ suspend_scheduler(ErtsSchedulerData *esdp) NULL); } - erts_smp_atomic_inc(&schdlr_sspnd.active); - + active_schedulers = erts_smp_atomic_inctest(&schdlr_sspnd.active); + if (schdlr_sspnd.changing == ERTS_SCHED_CHANGING_MULTI_SCHED + && schdlr_sspnd.online == active_schedulers) { + schdlr_sspnd.changing = 0; + } erts_smp_mtx_unlock(&schdlr_sspnd.mtx); if (erts_system_profile_flags.scheduler) @@ -2750,11 +2753,12 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all) ErtsProcList *plp; erts_smp_mtx_lock(&schdlr_sspnd.mtx); - if (on) { - if (schdlr_sspnd.changing) { - res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */ - } - else if (erts_is_multi_scheduling_blocked()) { + + if (schdlr_sspnd.changing) { + res = ERTS_SCHDLR_SSPND_YIELD_RESTART; /* Yield */ + } + else if (on) { /* ------ BLOCK ------ */ + if (erts_is_multi_scheduling_blocked()) { plp = proclist_create(p); plp->next = schdlr_sspnd.msb.procs; schdlr_sspnd.msb.procs = plp; @@ -2842,10 +2846,11 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all) } } else if (!ongoing_multi_scheduling_block()) { + /* unblock not ongoing */ ASSERT(!schdlr_sspnd.msb.procs); res = ERTS_SCHDLR_SSPND_DONE; } - else { + else { /* ------ UNBLOCK ------ */ if (p->flags & F_HAVE_BLCKD_MSCHED) { ErtsProcList **plpp = &schdlr_sspnd.msb.procs; plp = schdlr_sspnd.msb.procs; @@ -2930,7 +2935,6 @@ erts_block_multi_scheduling(Process *p, ErtsProcLocks plocks, int on, int all) erts_smp_mtx_lock(&schdlr_sspnd.mtx); } erts_smp_cnd_broadcast(&schdlr_sspnd.cnd); - schdlr_sspnd.changing = 0; res = ERTS_SCHDLR_SSPND_DONE; } } |