aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_process.c
diff options
context:
space:
mode:
authorLukas Larsson <[email protected]>2014-01-29 14:38:56 +0100
committerLukas Larsson <[email protected]>2014-02-24 15:16:05 +0100
commitff463a10f37ca74c0b6a8c0e24ce919e56b12bb8 (patch)
treec40571670df39e3397d8c7da4a781659e802fb09 /erts/emulator/beam/erl_process.c
parent31c4876582acf42f77f65f0d822d4d224d642364 (diff)
downloadotp-ff463a10f37ca74c0b6a8c0e24ce919e56b12bb8.tar.gz
otp-ff463a10f37ca74c0b6a8c0e24ce919e56b12bb8.tar.bz2
otp-ff463a10f37ca74c0b6a8c0e24ce919e56b12bb8.zip
ose: Add fair scheduling yields
This is needed on OSs that do not do round robin scheduling of threads.
Diffstat (limited to 'erts/emulator/beam/erl_process.c')
-rw-r--r--erts/emulator/beam/erl_process.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 929dbfd16b..48e9b63462 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -2620,6 +2620,8 @@ aux_thread(void *unused)
erts_thr_progress_active(NULL, thr_prgr_active = 0);
erts_thr_progress_prepare_wait(NULL);
+ ERTS_SCHED_FAIR_YIELD();
+
flgs = sched_spin_wait(ssi, 0);
if (flgs & ERTS_SSI_FLG_SLEEPING) {
@@ -2733,6 +2735,8 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
erts_thr_progress_prepare_wait(esdp);
}
+ ERTS_SCHED_FAIR_YIELD();
+
flgs = sched_spin_wait(ssi, spincount);
if (flgs & ERTS_SSI_FLG_SLEEPING) {
ASSERT(flgs & ERTS_SSI_FLG_WAITING);
@@ -2798,7 +2802,7 @@ scheduler_wait(int *fcalls, ErtsSchedulerData *esdp, ErtsRunQueue *rq)
#ifdef ERTS_SCHED_ONLY_POLL_SCHED_1
sys_poll_try:
while(!prepare_for_sys_schedule()) {
- delay(1);
+ ERTS_SCHED_FAIR_YIELD();
}
#endif
@@ -8069,10 +8073,12 @@ Process *schedule(Process *p, int calls)
erts_aint32_t aux_work;
int leader_update = erts_thr_progress_update(esdp);
aux_work = erts_atomic32_read_acqb(&esdp->ssi->aux_work);
- if (aux_work | leader_update) {
+ if (aux_work | leader_update | ERTS_SCHED_FAIR) {
erts_smp_runq_unlock(rq);
if (leader_update)
erts_thr_progress_leader_update(esdp);
+ else if (ERTS_SCHED_FAIR)
+ ERTS_SCHED_FAIR_YIELD();
if (aux_work)
handle_aux_work(&esdp->aux_work_data, aux_work, 0);
erts_smp_runq_lock(rq);