summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorErlang/OTP <otp@erlang.org>2013-09-16 16:21:35 +0200
committerErlang/OTP <otp@erlang.org>2013-09-16 16:21:35 +0200
commita3941acbcd17afb80167ee906530cabed2a76f56 (patch)
treed77555ccad374284569087d58b57a6e4e399370f
parentc72b20183a780c7199d3959f09eb88c1a930a064 (diff)
parent1fefbd886bf3f02f0d34d64ea49d3d0838cba9ee (diff)
downloaderlang-a3941acbcd17afb80167ee906530cabed2a76f56.tar.gz
Merge branch 'fredrik/sfwi-r15b03/OTP-11164' into maint-r15
* fredrik/sfwi-r15b03/OTP-11164: erts: reorganization of functions to r15b03 standards erts: bumped version number erts: Add the +sfwi system flag
-rw-r--r--erts/doc/src/erl.xml14
-rw-r--r--erts/emulator/beam/erl_init.c16
-rw-r--r--erts/emulator/beam/erl_process.c85
-rw-r--r--erts/emulator/beam/erl_process.h4
-rw-r--r--erts/etc/common/erlexec.c3
-rw-r--r--erts/vsn.mk2
6 files changed, 120 insertions, 4 deletions
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml
index f931445a3e..12cdb4b628 100644
--- a/erts/doc/src/erl.xml
+++ b/erts/doc/src/erl.xml
@@ -907,6 +907,20 @@
<p>For more information, see
<seealso marker="erlang#system_info_cpu_topology">erlang:system_info(cpu_topology)</seealso>.</p>
</item>
+ <tag><marker id="+sfwi"><c>+sfwi Interval</c></marker></tag>
+ <item>
+ <p>Set scheduler forced wakeup interval. All run queues will
+ be scanned each <c>Interval</c> milliseconds. While there are
+ sleeping schedulers in the system, one scheduler will be woken
+ for each non-empty run queue found. An <c>Interval</c> of zero
+ disables this feature, which also is the default.
+ </p>
+ <p>This feature has been introduced as a temporary workaround
+ for lengthy executing native code, and native code that do not
+ bump reductions properly in OTP. When these bugs have be fixed
+ the <c>+sfwi</c> flag will be removed.
+ </p>
+ </item>
<tag><marker id="+sws"><c>+sws default|legacy|proposal</c></marker></tag>
<item>
<p>Set scheduler wakeup strategy. Default is <c>legacy</c> (has been
diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c
index 1eb3dba240..7f52b111ac 100644
--- a/erts/emulator/beam/erl_init.c
+++ b/erts/emulator/beam/erl_init.c
@@ -1240,6 +1240,22 @@ erl_start(int argc, char **argv)
("suggested scheduler thread stack size %d kilo words\n",
erts_sched_thread_suggested_stack_size));
}
+ else if (has_prefix("fwi", sub_param)) {
+ long val;
+ arg = get_arg(sub_param+3, argv[i+1], &i);
+ errno = 0;
+ val = strtol(arg, NULL, 10);
+ if (errno != 0 || val < 0) {
+ erts_fprintf(stderr,
+ "bad scheduler forced wakeup "
+ "interval %s\n",
+ arg);
+ erts_usage();
+ }
+#ifdef ERTS_SMP
+ erts_runq_supervision_interval = val;
+#endif
+ }
else {
erts_fprintf(stderr, "bad scheduling option %s\n", argv[i]);
erts_usage();
diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c
index 9425fa7088..d7d440d81a 100644
--- a/erts/emulator/beam/erl_process.c
+++ b/erts/emulator/beam/erl_process.c
@@ -218,6 +218,10 @@ static erts_smp_atomic32_t function_calls;
#ifdef ERTS_SMP
static erts_smp_atomic32_t doing_sys_schedule;
static erts_smp_atomic32_t no_empty_run_queues;
+long erts_runq_supervision_interval = 0;
+static ethr_event runq_supervision_event;
+static erts_tid_t runq_supervisor_tid;
+static erts_atomic_t runq_supervisor_sleeping;
#else /* !ERTS_SMP */
ErtsSchedulerData *erts_scheduler_data;
#endif
@@ -1885,7 +1889,13 @@ empty_runq(ErtsRunQueue *rq)
*/
ASSERT(0 <= empty && empty < 2*erts_no_run_queues);
#endif
- erts_smp_atomic32_inc_relb(&no_empty_run_queues);
+ if (!erts_runq_supervision_interval)
+ erts_smp_atomic32_inc_relb(&no_empty_run_queues);
+ else {
+ erts_smp_atomic32_inc_mb(&no_empty_run_queues);
+ if (erts_atomic_read_nob(&runq_supervisor_sleeping))
+ ethr_event_set(&runq_supervision_event);
+ }
}
}
@@ -1903,7 +1913,14 @@ non_empty_runq(ErtsRunQueue *rq)
*/
ASSERT(0 < empty && empty <= 2*erts_no_run_queues);
#endif
- erts_smp_atomic32_dec_relb(&no_empty_run_queues);
+ if (!erts_runq_supervision_interval)
+ erts_smp_atomic32_dec_relb(&no_empty_run_queues);
+ else {
+ erts_aint32_t no;
+ no = erts_smp_atomic32_dec_read_mb(&no_empty_run_queues);
+ if (no > 0 && erts_atomic_read_nob(&runq_supervisor_sleeping))
+ ethr_event_set(&runq_supervision_event);
+ }
}
}
@@ -2505,7 +2522,6 @@ try_inc_no_active_runqs(int active)
return 0;
}
-
static ERTS_INLINE int
chk_wake_sched(ErtsRunQueue *crq, int ix, int activate)
{
@@ -3829,6 +3845,53 @@ set_wakeup_other_data(void)
}
}
+static int
+no_runqs_to_supervise(void)
+{
+ int used;
+ erts_aint32_t nerq = erts_smp_atomic32_read_acqb(&no_empty_run_queues);
+ if (nerq <= 0)
+ return 0;
+ get_no_runqs(NULL, &used);
+ if (nerq >= used)
+ return 0;
+ return used;
+}
+
+static void *
+runq_supervisor(void *unused)
+{
+ while (1) {
+ int ix, no_rqs;
+
+ erts_milli_sleep(erts_runq_supervision_interval);
+ no_rqs = no_runqs_to_supervise();
+ if (!no_rqs) {
+ erts_atomic_set_nob(&runq_supervisor_sleeping, 1);
+ while (1) {
+ ethr_event_reset(&runq_supervision_event);
+ no_rqs = no_runqs_to_supervise();
+ if (no_rqs) {
+ erts_atomic_set_nob(&runq_supervisor_sleeping, 0);
+ break;
+ }
+ ethr_event_wait(&runq_supervision_event);
+ }
+ }
+
+ for (ix = 0; ix < no_rqs; ix++) {
+ ErtsRunQueue *rq = ERTS_RUNQ_IX(ix);
+ if (erts_smp_atomic32_read_acqb(&rq->info_flags) & ERTS_RUNQ_IFLG_NONEMPTY) {
+ erts_smp_runq_lock(rq);
+ if (rq->len != 0)
+ wake_scheduler_on_empty_runq(rq); /* forced wakeup... */
+ erts_smp_runq_unlock(rq);
+ }
+ }
+ }
+ return NULL;
+}
+
#endif
void
@@ -5235,6 +5298,22 @@ erts_start_schedulers(void)
ethr_thr_opts opts = ETHR_THR_OPTS_DEFAULT_INITER;
opts.detached = 1;
+
+#ifdef ERTS_SMP
+ if (erts_runq_supervision_interval) {
+ opts.suggested_stack_size = 16;
+ erts_atomic_init_nob(&runq_supervisor_sleeping, 0);
+ if (0 != ethr_event_init(&runq_supervision_event))
+ erl_exit(1, "Failed to create run-queue supervision event\n");
+ if (0 != ethr_thr_create(&runq_supervisor_tid,
+ runq_supervisor,
+ NULL,
+ &opts))
+ erl_exit(1, "Failed to create run-queue supervision thread\n");
+
+ }
+#endif
+
opts.suggested_stack_size = erts_sched_thread_suggested_stack_size;
if (wanted < 1)
diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h
index 968971ed4c..9b0e9f1ccd 100644
--- a/erts/emulator/beam/erl_process.h
+++ b/erts/emulator/beam/erl_process.h
@@ -371,6 +371,10 @@ struct ErtsRunQueue_ {
} ports;
};
+#ifdef ERTS_SMP
+extern long erts_runq_supervision_interval;
+#endif
+
typedef union {
ErtsRunQueue runq;
char align[ERTS_ALC_CACHE_LINE_ALIGN_SIZE(sizeof(ErtsRunQueue))];
diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c
index 52add1c1ba..c4bdc4ee4b 100644
--- a/erts/etc/common/erlexec.c
+++ b/erts/etc/common/erlexec.c
@@ -124,6 +124,9 @@ static char *pluss_val_switches[] = {
"bwt",
"cl",
"ct",
+ "fwi",
+ "tbt",
+ "wct",
"wt",
"ws",
"ss",
diff --git a/erts/vsn.mk b/erts/vsn.mk
index f522b4c758..7e1d43429c 100644
--- a/erts/vsn.mk
+++ b/erts/vsn.mk
@@ -17,7 +17,7 @@
# %CopyrightEnd%
#
-VSN = 5.9.3.2
+VSN = 5.9.3.3
SYSTEM_VSN = R15B03
# Port number 4365 in 4.2