diff options
| author | Andre Muta <andremuta@gmail.com> | 2025-10-30 00:55:40 -0300 |
|---|---|---|
| committer | John Hawthorn <john@hawthorn.email> | 2025-10-30 13:44:25 -0700 |
| commit | 0531fa4d6fea100f69f0bac9e03973fe49ecd570 (patch) | |
| tree | b908efca37a74e99602178a4cfd80a6620782704 /thread_pthread.c | |
| parent | 6707945f0c065d47a4a9e8fd1627345bfcb85c10 (diff) | |
mn timer thread: force wakeups for timeouts
Diffstat (limited to 'thread_pthread.c')
| -rw-r--r-- | thread_pthread.c | 29 |
1 files changed, 17 insertions, 12 deletions
diff --git a/thread_pthread.c b/thread_pthread.c index 323659b649..64912a58da 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -2914,24 +2914,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); |
