summaryrefslogtreecommitdiff
path: root/thread_pthread.c
diff options
context:
space:
mode:
authorAndre Muta <andremuta@gmail.com>2025-10-30 00:55:40 -0300
committerJohn Hawthorn <john@hawthorn.email>2025-10-30 13:44:25 -0700
commit0531fa4d6fea100f69f0bac9e03973fe49ecd570 (patch)
treeb908efca37a74e99602178a4cfd80a6620782704 /thread_pthread.c
parent6707945f0c065d47a4a9e8fd1627345bfcb85c10 (diff)
mn timer thread: force wakeups for timeouts
Diffstat (limited to 'thread_pthread.c')
-rw-r--r--thread_pthread.c29
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);