Project

General

Profile

Feature #14717 ยป 0001-thread-allow-disabling-preempt.patch

normalperson (Eric Wong), 04/27/2018 08:14 AM

View differences:

test/ruby/test_thread.rb
assert_operator(c1, :>, c2, "[ruby-dev:33124]") # not guaranteed
end
def test_preemptible_disable
assert_predicate Thread.current, :preemptible?
Thread.current.preemptible = false
q = Queue.new
n = '0'
t1 = Thread.new do
q.push :ready
Thread.pass
10000.times { n.succ! }
:done
end
assert_equal :ready, q.pop, 'we yield to a non-preemptible thread'
assert_equal '0', n, 'loop not running, yet'
assert_not_predicate t1, :preemptible?, 'inherited from current thread'
assert_equal :done, t1.value
assert_equal '10000', n, 'loop finished running in cooperating thread'
ensure
Thread.current.preemptible = true
end
def test_new
assert_raise(ThreadError) do
Thread.new
thread.c
th->priority = current_th->priority;
th->thgroup = current_th->thgroup;
th->preemptible = current_th->preemptible;
th->pending_interrupt_queue = rb_ary_tmp_new(0);
th->pending_interrupt_queue_checked = 0;
......
}
}
if (timer_interrupt) {
if (timer_interrupt && th->preemptible) {
uint32_t limits_us = TIME_QUANTUM_USEC;
if (th->priority > 0)
......
return INT2NUM(target_th->priority);
}
static VALUE
rb_thread_preemptible_p(VALUE thread)
{
return rb_thread_ptr(thread)->preemptible ? Qtrue : Qfalse;
}
static VALUE
rb_thread_preemptible_set(VALUE thread, VALUE val)
{
rb_thread_ptr(thread)->preemptible = RTEST(val);
return val;
}
/* for IO */
#if defined(NFDBITS) && defined(HAVE_RB_FD_INIT)
......
rb_define_method(rb_cThread, "keys", rb_thread_keys, 0);
rb_define_method(rb_cThread, "priority", rb_thread_priority, 0);
rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1);
rb_define_method(rb_cThread, "preemptible?", rb_thread_preemptible_p, 0);
rb_define_method(rb_cThread, "preemptible=", rb_thread_preemptible_set, 1);
rb_define_method(rb_cThread, "status", rb_thread_status, 0);
rb_define_method(rb_cThread, "thread_variable_get", rb_thread_variable_get, 1);
rb_define_method(rb_cThread, "thread_variable_set", rb_thread_variable_set, 2);
vm.c
Init_native_thread(th);
th->vm = vm;
th->preemptible = 1;
th_init(th, 0);
rb_thread_set_current_raw(th);
ruby_thread_init_stack(th);
vm_core.h
/* misc */
unsigned int abort_on_exception: 1;
unsigned int report_on_exception: 1;
unsigned int preemptible: 1;
uint32_t running_time_us; /* 12500..800000 */
VALUE name;
} rb_thread_t;
-
    (1-1/1)