Project

General

Profile

Bug #15263 ยป 0001-vm_trace.c-postponed_job_register-only-hit-main-thre.patch

normalperson (Eric Wong), 10/27/2018 11:35 PM

View differences:

cont.c
{
rb_execution_context_t *ec = &fib->cont.saved_ec;
ruby_current_execution_context_ptr = th->ec = ec;
if (th->vm->main_thread == th) {
/*
* Other thread may set interrupt on previous th->ec at any time;
* ensure we do not delay (or lose) the trap interrupt handling.
*/
rb_atomic_t old_fl, new_fl;
rb_execution_context_t *prev_ec = ruby_current_execution_context_ptr;
/*
* timer-thread may set trap interrupt on previous th->ec at any time;
* ensure we do not delay (or lose) the trap interrupt handling.
*/
if (th->vm->main_thread == th && rb_signal_buff_size() > 0) {
RUBY_VM_SET_TRAP_INTERRUPT(ec);
ruby_current_execution_context_ptr = th->ec = ec;
old_fl = ATOMIC_EXCHANGE(prev_ec->interrupt_flag, 0);
/* migrate interrupts from the previous EC to the current EC */
new_fl = old_fl & (TIMER_INTERRUPT_MASK |
POSTPONED_JOB_INTERRUPT_MASK |
TRAP_INTERRUPT_MASK);
if (new_fl) ATOMIC_OR(ec->interrupt_flag, new_fl);
/* Pending-interrupts stay with the previous EC */
old_fl &= PENDING_INTERRUPT_MASK;
if (old_fl) ATOMIC_OR(prev_ec->interrupt_flag, old_fl);
}
else {
ruby_current_execution_context_ptr = th->ec = ec;
}
VM_ASSERT(ec->fiber_ptr->cont.self == 0 || ec->vm_stack != NULL);
vm_trace.c
/* Async-signal-safe */
static enum postponed_job_register_result
postponed_job_register(rb_execution_context_t *ec, rb_vm_t *vm,
postponed_job_register(rb_vm_t *vm,
unsigned int flags, rb_postponed_job_func_t func, void *data, int max, int expected_index)
{
rb_postponed_job_t *pjob;
......
pjob->func = func;
pjob->data = data;
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec);
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(vm->main_thread->ec);
return PJRR_SUCCESS;
}
......
int
rb_postponed_job_register(unsigned int flags, rb_postponed_job_func_t func, void *data)
{
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_t *vm = GET_VM();
begin:
switch (postponed_job_register(ec, vm, flags, func, data, MAX_POSTPONED_JOB, vm->postponed_job_index)) {
switch (postponed_job_register(vm, flags, func, data, MAX_POSTPONED_JOB, vm->postponed_job_index)) {
case PJRR_SUCCESS : return 1;
case PJRR_FULL : return 0;
case PJRR_INTERRUPTED: goto begin;
......
int
rb_postponed_job_register_one(unsigned int flags, rb_postponed_job_func_t func, void *data)
{
rb_execution_context_t *ec = GET_EC();
rb_vm_t *vm = rb_ec_vm_ptr(ec);
rb_vm_t *vm = GET_VM();
rb_postponed_job_t *pjob;
int i, index;
......
for (i=0; i<index; i++) {
pjob = &vm->postponed_job_buffer[i];
if (pjob->func == func) {
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(ec);
RUBY_VM_SET_POSTPONED_JOB_INTERRUPT(vm->main_thread->ec);
return 2;
}
}
switch (postponed_job_register(ec, vm, flags, func, data, MAX_POSTPONED_JOB + MAX_POSTPONED_JOB_SPECIAL_ADDITION, index)) {
switch (postponed_job_register(vm, flags, func, data, MAX_POSTPONED_JOB + MAX_POSTPONED_JOB_SPECIAL_ADDITION, index)) {
case PJRR_SUCCESS : return 1;
case PJRR_FULL : return 0;
case PJRR_INTERRUPTED: goto begin;
-
    (1-1/1)