mn timer thread: force wakeups for timeouts

This commit is contained in:
Andre Muta 2025-10-30 00:55:40 -03:00 committed by Takashi Kokubun
parent 0b7ea9c795
commit 7ec94afa8f
2 changed files with 19 additions and 14 deletions

View File

@ -2854,24 +2854,29 @@ timer_thread_set_timeout(rb_vm_t *vm)
}
ractor_sched_unlock(vm, NULL);
if (vm->ractor.sched.timeslice_wait_inf) {
rb_native_mutex_lock(&timer_th.waiting_lock);
{
struct rb_thread_sched_waiting *w = ccan_list_top(&timer_th.waiting, struct rb_thread_sched_waiting, node);
rb_thread_t *th = thread_sched_waiting_thread(w);
// Always check waiting threads to find minimum timeout
// even when scheduler has work (grq_cnt > 0)
rb_native_mutex_lock(&timer_th.waiting_lock);
{
struct rb_thread_sched_waiting *w = ccan_list_top(&timer_th.waiting, struct rb_thread_sched_waiting, node);
rb_thread_t *th = thread_sched_waiting_thread(w);
if (th && (th->sched.waiting_reason.flags & thread_sched_waiting_timeout)) {
rb_hrtime_t now = rb_hrtime_now();
rb_hrtime_t hrrel = rb_hrtime_sub(th->sched.waiting_reason.data.timeout, now);
if (th && (th->sched.waiting_reason.flags & thread_sched_waiting_timeout)) {
rb_hrtime_t now = rb_hrtime_now();
rb_hrtime_t hrrel = rb_hrtime_sub(th->sched.waiting_reason.data.timeout, now);
RUBY_DEBUG_LOG("th:%u now:%lu rel:%lu", rb_th_serial(th), (unsigned long)now, (unsigned long)hrrel);
RUBY_DEBUG_LOG("th:%u now:%lu rel:%lu", rb_th_serial(th), (unsigned long)now, (unsigned long)hrrel);
// TODO: overflow?
timeout = (int)((hrrel + RB_HRTIME_PER_MSEC - 1) / RB_HRTIME_PER_MSEC); // ms
// TODO: overflow?
int thread_timeout = (int)((hrrel + RB_HRTIME_PER_MSEC - 1) / RB_HRTIME_PER_MSEC); // ms
// Use minimum of scheduler timeout and thread sleep timeout
if (timeout < 0 || thread_timeout < timeout) {
timeout = thread_timeout;
}
}
rb_native_mutex_unlock(&timer_th.waiting_lock);
}
rb_native_mutex_unlock(&timer_th.waiting_lock);
RUBY_DEBUG_LOG("timeout:%d inf:%d", timeout, (int)vm->ractor.sched.timeslice_wait_inf);

View File

@ -830,8 +830,8 @@ timer_thread_register_waiting(rb_thread_t *th, int fd, enum thread_sched_waiting
verify_waiting_list();
// update timeout seconds
timer_thread_wakeup();
// update timeout seconds; force wake so timer thread notices short deadlines
timer_thread_wakeup_force();
}
}
else {