aboutsummaryrefslogtreecommitdiffstats
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
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.
-rw-r--r--erts/emulator/beam/erl_process.c10
-rw-r--r--erts/emulator/beam/erl_process.h7
-rw-r--r--erts/emulator/beam/erl_trace.c2
-rw-r--r--erts/emulator/sys/ose/erl_ose_sys.h5
4 files changed, 20 insertions, 4 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);
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index cf20ed5acf..a86ac65aa2 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -607,6 +607,13 @@ extern ErtsAlignedSchedulerData *erts_aligned_dirty_io_scheduler_data;
extern ErtsSchedulerData *erts_scheduler_data;
#endif
+#ifdef ERTS_SCHED_FAIR
+#define ERTS_SCHED_FAIR_YIELD() ETHR_YIELD()
+#else
+#define ERTS_SCHED_FAIR 0
+#define ERTS_SCHED_FAIR_YIELD()
+#endif
+
#if defined(ERTS_SMP) && defined(ERTS_ENABLE_LOCK_CHECK)
int erts_smp_lc_runq_is_locked(ErtsRunQueue *);
#endif
diff --git a/erts/emulator/beam/erl_trace.c b/erts/emulator/beam/erl_trace.c
index 62a0b8ccea..43e7435d2a 100644
--- a/erts/emulator/beam/erl_trace.c
+++ b/erts/emulator/beam/erl_trace.c
@@ -3309,6 +3309,8 @@ sys_msg_dispatcher_func(void *unused)
if (erts_thr_progress_update(NULL))
erts_thr_progress_leader_update(NULL);
+ ERTS_SCHED_FAIR_YIELD();
+
#ifdef DEBUG_PRINTOUTS
print_msg_type(smqp);
#endif
diff --git a/erts/emulator/sys/ose/erl_ose_sys.h b/erts/emulator/sys/ose/erl_ose_sys.h
index db8607b650..cd66d95c26 100644
--- a/erts/emulator/sys/ose/erl_ose_sys.h
+++ b/erts/emulator/sys/ose/erl_ose_sys.h
@@ -41,8 +41,9 @@
#include "ethread.h"
/* FIXME: configuration options */
-#define ERTS_SCHED_MIN_SPIN
-#define ERTS_SCHED_ONLY_POLL_SCHED_1
+#define ERTS_SCHED_MIN_SPIN 1
+#define ERTS_SCHED_ONLY_POLL_SCHED_1 1
+#define ERTS_SCHED_FAIR 1
#define NO_SYSCONF 1
#define OPEN_MAX FOPEN_MAX