aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_process.c
diff options
context:
space:
mode:
authorRickard Green <[email protected]>2010-01-22 13:47:23 +0000
committerErlang/OTP <[email protected]>2010-01-22 13:47:23 +0000
commite19d6e4463a9cc3b738fd32a46e0ce9282a70fd5 (patch)
treed4014c55c5cd8c4559c9227b25e187e0f457fc46 /erts/emulator/beam/erl_process.c
parentc7187afaf4d672e0320a73708fe44d5ac5520b52 (diff)
downloadotp-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/erl_process.c')
-rw-r--r--erts/emulator/beam/erl_process.c22
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;
}
}