mruby-task: refactor sleep implementation to use microseconds

Rename sleep_ms_impl to sleep_us_impl as the base implementation,
providing true microsecond precision for usleep. sleep_ms_impl now
simply calls sleep_us_impl with converted values.

This ensures usleep provides proper microsecond granularity instead of
losing precision by converting to milliseconds.

Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2025-10-06 07:45:45 +09:00
parent ef4a14996a
commit ee398ddcdc
+13 -8
View File
@@ -354,7 +354,7 @@ mrb_tasks_run(mrb_state *mrb)
*/
static void
sleep_ms_impl(mrb_state *mrb, mrb_int ms)
sleep_us_impl(mrb_state *mrb, mrb_int usec)
{
mrb_task *t = q_ready_; /* Current running task */
@@ -362,14 +362,14 @@ sleep_ms_impl(mrb_state *mrb, mrb_int ms)
/* Not in task context - use blocking sleep with retry on interruption */
#ifdef __unix__
struct timespec req, rem;
req.tv_sec = ms / 1000;
req.tv_nsec = (ms % 1000) * 1000000;
req.tv_sec = usec / 1000000;
req.tv_nsec = (usec % 1000000) * 1000;
/* nanosleep automatically retries on EINTR with SA_RESTART */
while (nanosleep(&req, &rem) == -1) {
req = rem; /* Continue with remaining time if interrupted */
}
#elif defined(_WIN32)
Sleep((DWORD)ms);
Sleep((DWORD)(usec / 1000));
#endif
return;
}
@@ -382,7 +382,8 @@ sleep_ms_impl(mrb_state *mrb, mrb_int ms)
/* Move to waiting queue */
t->status = MRB_TASKSTATUS_WAITING;
t->reason = MRB_TASKREASON_SLEEP;
t->wakeup_tick = tick_ + (ms / MRB_TICK_UNIT);
/* Convert microseconds to ticks (tick unit is in milliseconds) */
t->wakeup_tick = tick_ + ((usec / 1000) / MRB_TICK_UNIT);
/* Update next wakeup time if this task wakes earlier */
if (t->wakeup_tick < wakeup_tick_) {
@@ -397,6 +398,12 @@ sleep_ms_impl(mrb_state *mrb, mrb_int ms)
switching_ = TRUE;
}
static void
sleep_ms_impl(mrb_state *mrb, mrb_int ms)
{
sleep_us_impl(mrb, ms * 1000);
}
static mrb_value
mrb_f_sleep(mrb_state *mrb, mrb_value self)
{
@@ -456,9 +463,7 @@ mrb_f_usleep(mrb_state *mrb, mrb_value self)
mrb_raise(mrb, E_ARGUMENT_ERROR, "time interval must be positive");
}
/* Convert microseconds to milliseconds */
mrb_int ms = usec / 1000;
sleep_ms_impl(mrb, ms);
sleep_us_impl(mrb, usec);
return mrb_fixnum_value(usec);
}