summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authornormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-19 00:01:08 (GMT)
committernormal <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-08-19 00:01:08 (GMT)
commitd2afeb9445a3dc8445fa48f601a78c5ecd743ca6 (patch)
treecd66b3063bf3473dc49da879f735e88ce0436498 /thread_pthread.c
parent77038f9f826dbc988332c9ec4abf7dea57af1160 (diff)
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). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@64467 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c9
1 files changed, 6 insertions, 3 deletions
diff --git a/thread_pthread.c b/thread_pthread.c
index af933d4..2fd60dd 100644
--- a/thread_pthread.c
+++ b/thread_pthread.c
@@ -180,19 +180,18 @@ static void
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_thread_t *th)
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)
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;
}