[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]