diff options
author | Rickard Green <[email protected]> | 2010-09-04 00:18:45 +0200 |
---|---|---|
committer | Rickard Green <[email protected]> | 2010-09-04 00:29:53 +0200 |
commit | d8e862b5b4a354bdeee2d2b4d6d46024d4aabb0e (patch) | |
tree | 5573684db6aec82d59af13239e16461f4c61303d | |
parent | 14b1091a4b09e5626aaa63e9d1ea60e829fc829b (diff) | |
download | otp-d8e862b5b4a354bdeee2d2b4d6d46024d4aabb0e.tar.gz otp-d8e862b5b4a354bdeee2d2b4d6d46024d4aabb0e.tar.bz2 otp-d8e862b5b4a354bdeee2d2b4d6d46024d4aabb0e.zip |
Add scheduler wakup threshold as command line argument
The scheduler wakeup threshold is now possible to adjust at system boot.
For more information see the `+swt' command line argument of `erl'.
-rw-r--r-- | erts/doc/src/erl.xml | 26 | ||||
-rw-r--r-- | erts/emulator/beam/erl_init.c | 16 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.c | 31 | ||||
-rw-r--r-- | erts/emulator/beam/erl_process.h | 2 | ||||
-rw-r--r-- | erts/etc/common/erlexec.c | 1 |
5 files changed, 66 insertions, 10 deletions
diff --git a/erts/doc/src/erl.xml b/erts/doc/src/erl.xml index f477280a6f..e36d0adb0d 100644 --- a/erts/doc/src/erl.xml +++ b/erts/doc/src/erl.xml @@ -831,14 +831,28 @@ <p>For more information, see <seealso marker="erlang#system_flag_cpu_topology">erlang:system_flag(cpu_topology, CpuTopology)</seealso>.</p> </item> + <tag><marker id="+swt"><c>+swt very_low|low|medium|high|very_high</c></marker></tag> + <item> + <p>Set scheduler wakeup threshold. Default is <c>medium</c>. + The threshold determines when to wake up sleeping schedulers + when more work than can be handled by currently awake schedulers + exist. A low threshold will cause earlier wakeups, and a high + threshold will cause later wakeups. Early wakeups will + distribute work over multiple schedulers faster, but work will + more easily bounce between schedulers. + </p> + <p><em>NOTE:</em> This flag may be removed or changed at any time + without prior notice. + </p> + </item> + <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag> + <item> + <p>Suggested stack size, in kilowords, for scheduler threads. + Valid range is 4-8192 kilowords. The default stack size + is OS dependent.</p> + </item> </taglist> </item> - <tag><marker id="sched_thread_stack_size"><c><![CDATA[+sss size]]></c></marker></tag> - <item> - <p>Suggested stack size, in kilowords, for scheduler threads. - Valid range is 4-8192 kilowords. The default stack size - is OS dependent.</p> - </item> <tag><marker id="+t"><c><![CDATA[+t size]]></c></marker></tag> <item> <p>Set the maximum number of atoms the VM can handle. Default is 1048576.</p> diff --git a/erts/emulator/beam/erl_init.c b/erts/emulator/beam/erl_init.c index 14bd10b42c..4ae656a3ad 100644 --- a/erts/emulator/beam/erl_init.c +++ b/erts/emulator/beam/erl_init.c @@ -512,6 +512,8 @@ void erts_usage(void) erts_fprintf(stderr, " u|ns|ts|ps|s|nnts|nnps|tnnps|db\n"); erts_fprintf(stderr, "-sct cput set cpu topology,\n"); erts_fprintf(stderr, " see the erl(1) documentation for more info.\n"); + erts_fprintf(stderr, "-swt val set scheduler wakeup threshold, valid values are:\n"); + erts_fprintf(stderr, " very_low|low|medium|high|very_high.\n"); erts_fprintf(stderr, "-sss size suggested stack size in kilo words for scheduler threads,\n"); erts_fprintf(stderr, " valid range is [%d-%d]\n", ERTS_SCHED_THREAD_MIN_STACK_SIZE, @@ -1176,10 +1178,20 @@ erl_start(int argc, char **argv) } else if (sys_strcmp("mrq", sub_param) == 0) use_multi_run_queue = 1; - else if (sys_strcmp("srq", sub_param) == 0) - use_multi_run_queue = 0; else if (sys_strcmp("nsp", sub_param) == 0) erts_use_sender_punish = 0; + else if (sys_strcmp("srq", sub_param) == 0) + use_multi_run_queue = 0; + else if (sys_strcmp("wt", sub_param) == 0) { + arg = get_arg(sub_param+2, argv[i+1], &i); + if (erts_sched_set_wakeup_limit(arg) != 0) { + erts_fprintf(stderr, "scheduler wakeup threshold: %s\n", + arg); + erts_usage(); + } + VERBOSE(DEBUG_SYSTEM, + ("scheduler wakup threshold: %s\n", arg)); + } else if (has_prefix("ss", sub_param)) { /* suggested stack size (Kilo Words) for scheduler threads */ arg = get_arg(sub_param+2, argv[i+1], &i); diff --git a/erts/emulator/beam/erl_process.c b/erts/emulator/beam/erl_process.c index 6e34b25190..901167a315 100644 --- a/erts/emulator/beam/erl_process.c +++ b/erts/emulator/beam/erl_process.c @@ -54,7 +54,12 @@ (ERTS_SCHED_SYS_SLEEP_SPINCOUNT*ERTS_SCHED_TSE_SLEEP_SPINCOUNT_FACT) #define ERTS_SCHED_SUSPEND_SLEEP_SPINCOUNT 0 -#define ERTS_WAKEUP_OTHER_LIMIT (10*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH (200*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_HIGH (50*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_MEDIUM (10*CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_LOW (CONTEXT_REDS) +#define ERTS_WAKEUP_OTHER_LIMIT_VERY_LOW (CONTEXT_REDS/10) + #define ERTS_WAKEUP_OTHER_DEC 10 #define ERTS_WAKEUP_OTHER_FIXED_INC (CONTEXT_REDS/10) @@ -112,6 +117,8 @@ Uint erts_no_schedulers; Uint erts_max_processes = ERTS_DEFAULT_MAX_PROCESSES; Uint erts_process_tab_index_mask; +static int wakeup_other_limit; + #ifdef ERTS_SMP Uint erts_max_main_threads; #endif @@ -2373,7 +2380,27 @@ void erts_early_init_scheduling(void) { early_cpu_bind_init(); + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM; +} + +int +erts_sched_set_wakeup_limit(char *str) +{ + if (sys_strcmp(str, "very_high") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_VERY_HIGH; + else if (sys_strcmp(str, "high") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_HIGH; + else if (sys_strcmp(str, "medium") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_MEDIUM; + else if (sys_strcmp(str, "low") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_LOW; + else if (sys_strcmp(str, "very_low") == 0) + wakeup_other_limit = ERTS_WAKEUP_OTHER_LIMIT_VERY_LOW; + else + return EINVAL; + return 0; } + void erts_init_scheduling(int mrq, int no_schedulers, int no_schedulers_online) @@ -7169,7 +7196,7 @@ Process *schedule(Process *p, int calls) if (rq->wakeup_other < 0) rq->wakeup_other = 0; } - else if (rq->wakeup_other < ERTS_WAKEUP_OTHER_LIMIT) + else if (rq->wakeup_other < wakeup_other_limit) rq->wakeup_other += rq->len*wo_reds + ERTS_WAKEUP_OTHER_FIXED_INC; else { if (erts_common_run_queue) { diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index e49710a7ed..4365e409e5 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1038,6 +1038,8 @@ ErtsProcList *erts_proclist_create(Process *); void erts_proclist_destroy(ErtsProcList *); int erts_proclist_same(ErtsProcList *, Process *); +int erts_sched_set_wakeup_limit(char *str); + #ifdef DEBUG void erts_dbg_multi_scheduling_return_trap(Process *, Eterm); #endif diff --git a/erts/etc/common/erlexec.c b/erts/etc/common/erlexec.c index 76ce0a7e3c..c1fc2aebee 100644 --- a/erts/etc/common/erlexec.c +++ b/erts/etc/common/erlexec.c @@ -120,6 +120,7 @@ static char *plusM_other_switches[] = { static char *pluss_val_switches[] = { "bt", "ct", + "wt", "ss", NULL }; |