summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Patterson <[email protected]>2024-11-01 15:06:35 -0700
committerAaron Patterson <[email protected]>2024-12-12 16:04:49 -0800
commitfffef9aa5d89b6cca3dc634f5278b1fc67fb3d08 (patch)
tree600f63118e7ef716d183b2894e918febcdeb3c49
parente7ee7d43f3d22f499845ee2c8c420201d6b453a3 (diff)
Add an environment variable for controlling the default Thread quantum
This commit adds an environment variable `RUBY_THREAD_TIMESLICE` for specifying the default thread quantum in milliseconds. You can adjust this variable to tune throughput, which is especially useful on multithreaded systems that are mixing CPU bound work and IO bound work. The default quantum remains 100ms. [Feature #20861] Co-Authored-By: John Hawthorn <[email protected]>
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11981
-rw-r--r--man/ruby.14
-rw-r--r--thread.c10
-rw-r--r--thread_none.c4
-rw-r--r--thread_pthread.c7
4 files changed, 13 insertions, 12 deletions
diff --git a/man/ruby.1 b/man/ruby.1
index 905c712f4c..b1b8e42401 100644
--- a/man/ruby.1
+++ b/man/ruby.1
@@ -537,6 +537,10 @@ Introduced in Ruby 3.3, default: unset.
.Pp
.It Ev RUBY_PAGER
The pager command that will be used for
+.Pp
+.It Ev RUBY_THREAD_TIMESLICE
+Sets the default thread time slice (thread quantum) in milliseconds.
+Introduced in Ruby 3.4, default: 100ms.
.Fl -help
option.
Introduced in Ruby 3.0, default:
diff --git a/thread.c b/thread.c
index 86c7392e9c..2d2951d18a 100644
--- a/thread.c
+++ b/thread.c
@@ -116,6 +116,8 @@ static VALUE sym_immediate;
static VALUE sym_on_blocking;
static VALUE sym_never;
+static uint32_t thread_default_quantum_ms = 100;
+
#define THREAD_LOCAL_STORAGE_INITIALISED FL_USER13
#define THREAD_LOCAL_STORAGE_INITIALISED_P(th) RB_FL_TEST_RAW((th), THREAD_LOCAL_STORAGE_INITIALISED)
@@ -2538,7 +2540,7 @@ rb_threadptr_execute_interrupts(rb_thread_t *th, int blocking_timing)
}
if (timer_interrupt) {
- uint32_t limits_us = TIME_QUANTUM_USEC;
+ uint32_t limits_us = thread_default_quantum_ms * 1000;
if (th->priority > 0)
limits_us <<= th->priority;
@@ -5506,6 +5508,12 @@ Init_Thread(void)
rb_define_method(cThGroup, "enclosed?", thgroup_enclosed_p, 0);
rb_define_method(cThGroup, "add", thgroup_add, 1);
+ const char * ptr = getenv("RUBY_THREAD_TIMESLICE");
+
+ if (ptr) {
+ thread_default_quantum_ms = (uint32_t)strtol(ptr, NULL, 0);
+ }
+
{
th->thgroup = th->ractor->thgroup_default = rb_obj_alloc(cThGroup);
rb_define_const(cThGroup, "Default", th->thgroup);
diff --git a/thread_none.c b/thread_none.c
index 1582609821..8d32aaabee 100644
--- a/thread_none.c
+++ b/thread_none.c
@@ -19,10 +19,6 @@
# include "wasm/machine.h"
#endif
-#define TIME_QUANTUM_MSEC (100)
-#define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
-#define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
-
// Do nothing for GVL
static void
thread_sched_to_running(struct rb_thread_sched *sched, rb_thread_t *th)
diff --git a/thread_pthread.c b/thread_pthread.c
index 09c2969e8c..357454f9b5 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -317,13 +317,6 @@ static void threadptr_trap_interrupt(rb_thread_t *);
#define native_thread_yield() ((void)0)
#endif
-/* 100ms. 10ms is too small for user level thread scheduling
- * on recent Linux (tested on 2.6.35)
- */
-#define TIME_QUANTUM_MSEC (100)
-#define TIME_QUANTUM_USEC (TIME_QUANTUM_MSEC * 1000)
-#define TIME_QUANTUM_NSEC (TIME_QUANTUM_USEC * 1000)
-
static void native_thread_dedicated_inc(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt);
static void native_thread_dedicated_dec(rb_vm_t *vm, rb_ractor_t *cr, struct rb_native_thread *nt);
static void native_thread_assign(struct rb_native_thread *nt, rb_thread_t *th);