From 5add7c3ea9a13e657fc7cba78b2633b9548a55aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Chris=20Hasi=C5=84ski?= Date: Mon, 26 Jan 2026 16:17:35 +0100 Subject: Fix RUBY_MN_THREADS sleep returning prematurely (#15868) timer_thread_check_exceed() was returning true when the remaining time was less than 1ms, treating it as "too short time". This caused sub-millisecond sleeps (like sleep(0.0001)) to return immediately instead of actually sleeping. The fix removes this optimization that was incorrectly short-circuiting short sleep durations. Now the timeout is only considered exceeded when the actual deadline has passed. Note: There's still a separate performance issue where MN_THREADS mode is slower for sub-millisecond sleeps due to the timer thread using millisecond-resolution polling. This will require a separate fix to use sub-millisecond timeouts in kqueue/epoll. [Bug #21836] --- test/ruby/test_thread.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'test/ruby') diff --git a/test/ruby/test_thread.rb b/test/ruby/test_thread.rb index 7f5dbe9155..b2d8e73693 100644 --- a/test/ruby/test_thread.rb +++ b/test/ruby/test_thread.rb @@ -1652,4 +1652,16 @@ q.pop end end; end + + # [Bug #21836] + def test_mn_threads_sub_millisecond_sleep + assert_separately([{'RUBY_MN_THREADS' => '1'}], "#{<<~"begin;"}\n#{<<~'end;'}", timeout: 30) + begin; + t0 = Process.clock_gettime(Process::CLOCK_MONOTONIC) + 1000.times { sleep 0.0001 } + t1 = Process.clock_gettime(Process::CLOCK_MONOTONIC) + elapsed = t1 - t0 + assert_operator elapsed, :>=, 0.1, "sub-millisecond sleeps should not return immediately" + end; + end end -- cgit v1.2.3