ruby-changes:52259
From: normal <ko1@a...>
Date: Sun, 19 Aug 2018 09:01:12 +0900 (JST)
Subject: [ruby-changes:52259] normal:r64467 (trunk): thread_pthread.c: reset timeslice delay when uncontended
normal 2018-08-19 09:01:08 +0900 (Sun, 19 Aug 2018) New Revision: 64467 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64467 Log: thread_pthread.c: reset timeslice delay when uncontended This matches the behavior of old timer thread more closely and seems to fix [Bug #14999] when limited to a single CPU. I cannot reproduce the error on a multi-core system unless I use schedtool to force affinity to a single CPU: schedtool -a 0x01 -e make test-spec \ MSPECOPT='-R1000 spec/ruby/library/conditionvariable/wait_spec.rb' While it may be good enough to pass the spec, I don't have huge degree of confidence in the interrupt handling robustness under extremely heavy load (these may be ancient bugs, though). Modified files: trunk/thread_pthread.c trunk/thread_pthread.h Index: thread_pthread.c =================================================================== --- thread_pthread.c (revision 64466) +++ thread_pthread.c (revision 64467) @@ -180,19 +180,18 @@ static void https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L180 do_gvl_timer(rb_vm_t *vm, rb_thread_t *th) { static struct timespec ts; - static int err = ETIMEDOUT; native_thread_data_t *nd = &th->native_thread_data; /* take over wakeups from UBF_TIMER */ ubf_timer_disarm(); - if (err == ETIMEDOUT) { + if (vm->gvl.timer_err == ETIMEDOUT) { ts.tv_sec = 0; ts.tv_nsec = TIME_QUANTUM_NSEC; ts = native_cond_timeout(&nd->cond.gvlq, ts); } vm->gvl.timer = th; - err = native_cond_timedwait(&nd->cond.gvlq, &vm->gvl.lock, &ts); + vm->gvl.timer_err = native_cond_timedwait(&nd->cond.gvlq, &vm->gvl.lock, &ts); vm->gvl.timer = 0; ubf_wakeup_all_threads(); @@ -244,6 +243,9 @@ gvl_acquire_common(rb_vm_t *vm, rb_threa https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L243 rb_native_cond_signal(&vm->gvl.switch_cond); } } + else { /* reset timer if uncontended */ + vm->gvl.timer_err = ETIMEDOUT; + } vm->gvl.acquired = th; if (!vm->gvl.timer) { if (!designate_timer_thread(vm) && !ubf_threads_empty()) { @@ -325,6 +327,7 @@ gvl_init(rb_vm_t *vm) https://github.com/ruby/ruby/blob/trunk/thread_pthread.c#L327 list_head_init(&vm->gvl.waitq); vm->gvl.acquired = 0; vm->gvl.timer = 0; + vm->gvl.timer_err = ETIMEDOUT; vm->gvl.need_yield = 0; vm->gvl.wait_yield = 0; } Index: thread_pthread.h =================================================================== --- thread_pthread.h (revision 64466) +++ thread_pthread.h (revision 64467) @@ -53,6 +53,7 @@ typedef struct rb_global_vm_lock_struct https://github.com/ruby/ruby/blob/trunk/thread_pthread.h#L53 /* slow path */ struct list_head waitq; const struct rb_thread_struct *timer; + int timer_err; /* yield */ rb_nativethread_cond_t switch_cond; -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/