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
This commit is contained in:
parent
77038f9f82
commit
d2afeb9445
@ -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;
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ typedef struct rb_global_vm_lock_struct {
|
||||
/* slow path */
|
||||
struct list_head waitq;
|
||||
const struct rb_thread_struct *timer;
|
||||
int timer_err;
|
||||
|
||||
/* yield */
|
||||
rb_nativethread_cond_t switch_cond;
|
||||
|
Loading…
x
Reference in New Issue
Block a user