aboutsummaryrefslogtreecommitdiffstats
path: root/thread_pthread.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-11-11 14:37:31 +0900
committerKoichi Sasada <ko1@atdot.net>2020-11-11 15:49:02 +0900
commit1e8abe5d03ae386af82e2c95ef05170cd9791889 (patch)
tree053d9153f20d975961d39cc6e2471290a49bd618 /thread_pthread.c
parentdd07354f2797473261f06159801e50dc6445ef76 (diff)
downloadruby-1e8abe5d03ae386af82e2c95ef05170cd9791889.tar.gz
introduce USE_VM_CLOCK for windows.
The timer function used on windows system set timer interrupt flag of current main ractor's executing ec and thread can detect the end of time slice. However, to set all ec->interrupt_flag for all running ractors, it is requires to synchronize with other ractors. However, timer thread can not acquire the ractor-wide lock because of some limitation. To solve this issue, this patch introduces USE_VM_CLOCK compile option to introduce rb_vm_t::clock. This clock will be incremented by the timer thread and each thread can check the incrementing by comparison with previous checked clock. At last, on windows platform this patch introduces some overhead, but I think there is no critical performance issue because of this modification.
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index 71667aec69..97879f559a 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -194,6 +194,7 @@ designate_timer_thread(rb_global_vm_lock_t *gvl)
static void
do_gvl_timer(rb_global_vm_lock_t *gvl, rb_thread_t *th)
{
+ rb_vm_t *vm = GET_VM();
static rb_hrtime_t abs;
native_thread_data_t *nd = &th->native_thread_data;
@@ -208,14 +209,14 @@ do_gvl_timer(rb_global_vm_lock_t *gvl, rb_thread_t *th)
gvl->timer_err = native_cond_timedwait(&nd->cond.gvlq, &gvl->lock, &abs);
ubf_wakeup_all_threads();
- ruby_sigchld_handler(GET_VM());
+ ruby_sigchld_handler(vm);
if (UNLIKELY(rb_signal_buff_size())) {
- if (th == GET_VM()->ractor.main_thread) {
+ if (th == vm->ractor.main_thread) {
RUBY_VM_SET_TRAP_INTERRUPT(th->ec);
}
else {
- threadptr_trap_interrupt(GET_VM()->ractor.main_thread);
+ threadptr_trap_interrupt(vm->ractor.main_thread);
}
}
@@ -223,7 +224,10 @@ do_gvl_timer(rb_global_vm_lock_t *gvl, rb_thread_t *th)
* Timeslice. Warning: the process may fork while this
* thread is contending for GVL:
*/
- if (gvl->owner) timer_thread_function(gvl->owner->ec);
+ if (gvl->owner) {
+ // strictly speaking, accessing "gvl->owner" is not thread-safe
+ RUBY_VM_SET_TIMER_INTERRUPT(gvl->owner->ec);
+ }
gvl->timer = 0;
}