Skip to content

[pull] master from ruby:master - #1361

Merged
pull[bot] merged 8 commits into
turkdevops:masterfrom
ruby:master
Aug 30, 2026
Merged

[pull] master from ruby:master#1361
pull[bot] merged 8 commits into
turkdevops:masterfrom
ruby:master

Conversation

@pull

@pull pull Bot commented Aug 30, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

ko1 and others added 8 commits August 30, 2026 15:27
A blocking read used to cost four epoll_ctl per wait cycle: ADD before
the wait and DEL after the wake, on both ends of an exchange.  The DEL
ran on the timer thread, the one serial resource every io readiness
event already passes through.

With EPOLLONESHOT the delivery itself disarms the fd inside the kernel:
the post-wake DEL becomes no syscall at all, and the next wait re-arms
with one MOD on a registration that persists for the fd's lifetime.
A disarm with no delivery (timeout, interrupt) MODs the event mask to
zero instead of deleting.  Registration stays level-triggered, so a
woken reader is under no obligation to drain the fd; the generation tag
already guards against events queued under an old arming, and a stale
registration left by close is repaired by the existing ENOENT fallback
on the next arm.

Two round trips of a 64-byte socketpair exchange drop from 12 to 10
syscalls (epoll_ctl 4.00 -> 2.00) and the timer thread falls from 97%
to 82% of a core.  On master 22e4a75, sp4 (16 cores), medians:

  io_intensive (socketpair round trips, 2 Ractors/pair)
     8 pairs   218,839 -> 432,810 rt/s  (+98%)
    64 pairs   276,556 -> 591,171 rt/s  (+114%)
  punicorn (one Ractor per connection, wrk from a second box)
    keepalive c=64      280,678 -> 309,530 rps  (+10%)
    4x memcached/req    59,683 ->  67,082 rps  (+12%)
  SSE probe beside 512 held streams   193,769 -> 205,602 rps (+6%)

Workloads that wait on the timer wheel (sleep), the GVL (cpu), or
connection churn are unchanged; so are Ractor creation, GC and plain
threads (~50 configurations within +-2%).

make btest and full test-all pass with the feature on, as does btest on
a RUBY_DEBUG=1 build, and an adversarial fd close/reuse + cross-thread
close + fork-with-live-io stress.  Platforms: epoll only; kqueue keeps
its current path (EV_DISPATCH would be the analogue).  EPOLLONESHOT
predates every kernel that can build ruby (Linux 2.6.2), and an epoll
without it now falls back to USE_MN_THREADS=0 at compile time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Only allocate and use the partial objects table when a load proc is active or loaded objects must be frozen.

Co-authored-by: Codex <noreply@openai.com>
It just returns `false` no matter the other argument.
It just does `RBOOL(RTEST(other))`.
This helps figure out what part of long functions is causing the exit or
fallback or whatever is being traced.
This appears when doing e.g. `l & (a == b)` (as in the included new
test) where `TrueClass#&` does `RTEST(RBOOL(rhs))` and then the right
hand side is already known to be returning a `BoolExact` because it's
from `FixnumEq`.
It doesn't end up generating any code (we catch this in codegen too) but
we might as well not have the instruction lying around in our IR.
@pull pull Bot locked and limited conversation to collaborators Aug 30, 2026
@pull pull Bot added the ⤵️ pull label Aug 30, 2026
@pull
pull Bot merged commit a889da9 into turkdevops:master Aug 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants