Skip to main content

MAX_READS_IN_FLIGHT

Constant MAX_READS_IN_FLIGHT 

Source
pub const MAX_READS_IN_FLIGHT: usize = 16;
Expand description

How many commands JdwpConnection::read_independently may leave unanswered at once (PERF-1, #100).

Named for InFlight rather than for a window, and it was INDEPENDENT_READ_WINDOW first. Every other “… window” in this codebase is a span of TIME — a capture window, a suspension window, an observation window, the escalation window, the window in which a watchpoint’s old value is still readable — and this is a count of concurrent commands. Two axes on one word, in a pub constant, is the collision batch already cost this project once (see the independent reads entry’s _Avoid_). Renamed while nothing was pinned to it: it went public unreleased, and CONTEXT.md’s own VOCAB-1 passage is that the window for doing this cheaply does not reopen.

It is a safety bound before it is a tuning knob, and the thing it makes impossible is a deadlock. The cycle to rule out: the event loop blocks writing a command because the JVM has stopped reading; the JVM has stopped reading because it is blocked writing replies; it is blocked writing because our receive buffer is full and the reader task is parked on a full PACKET_CHANNEL_DEPTH channel; and the reader is parked because the loop — blocked in that write — is not draining it. Every arrow there is real. What breaks it is that the loop can only block in a write once the send buffer fills, and a JDWP command is 11-43 bytes: sixteen of them is under a kilobyte against a send buffer of at least sixteen. A window of one thousand — which a caller expanding a thousand-element collection would otherwise ask for — is a different conversation.

It is also the memory bound on buffered replies, which is the other reason it is not the caller’s list length: a reply may be up to MAX_PACKET_SIZE, so the window is the ceiling on how much of the debuggee’s heap can be sitting in oneshot channels at once. Sixteen small reads is nothing; sixteen AllClasses replies would be 160MB, and nothing converted to this path reads anything of that shape.

Sixteen also caps the win, since n reads cost ceil(n / 16) round trips rather than one. That is the trade and it is deliberately on the safe side of it: sixteen-fold is already most of the available fan-out on the reads PERF-1 names, and the numbers above stop being reassuring well before a window large enough to matter more.

Public because a caller with a deadline has to chunk by it. A dump checks its suspension budget between threads, and nothing can interrupt one call to read_independently; chunking the caller’s list by this hands the budget back every window at no cost in time, since a window takes about as long as one sequential read. That is the only reason a tuning constant is on the public surface.