Conversation
Reviewer's GuideRevises forkrun ring scanner worker-spawn signaling to use unbuffered writes instead of dprintf to fix a deadlock, keeps v8.34 implementation as a frozen reference, and extends the benchmark script to cover additional pipeline invocation patterns. Sequence diagram for unbuffered worker-spawn signaling in ring_scannersequenceDiagram
actor User
participant BashLoop as bash_frun_driver
participant Scanner as ring_scanner_main
participant SpawnPipe as fd_spawn
participant Worker as worker_process
User->>BashLoop: run frun ...
BashLoop->>Scanner: start ring_scanner_main(fd, fd_spawn)
loop scanning_batches
Scanner->>Scanner: compute_needed_workers()
alt need_initial_workers
Scanner->>SpawnPipe: write("N\n") using write
SpawnPipe->>BashLoop: data "N\n" available
BashLoop->>BashLoop: read N from fd_spawn
BashLoop->>Worker: fork/exec N workers
Worker-->>Scanner: start consuming ring batches
else adjust_workers_dynamically
Scanner->>SpawnPipe: write("grow\n") using write
SpawnPipe->>BashLoop: data "grow\n" available
BashLoop->>BashLoop: read grow from fd_spawn
BashLoop->>Worker: fork/exec grow additional workers
Worker-->>Scanner: consume additional batches
end
end
Scanner-->>BashLoop: scanner_finished flag set
BashLoop-->>User: pipeline completes without deadlock
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
Hey - I've found 1 issue, and left some high level feedback:
- The new snprintf+write sequences for communicating spawn counts are duplicated in several places in ring_scanner_main; consider factoring this into a small helper (e.g., ring_write_u64_line(fd, value)) to centralize formatting and error handling.
- When using write() to send the formatted spawn counts, only a single write call is made; if you want this to be robust beyond the "very short to a pipe" case, consider looping until all bytes are written or returning a clear error on short writes.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- The new snprintf+write sequences for communicating spawn counts are duplicated in several places in ring_scanner_main; consider factoring this into a small helper (e.g., ring_write_u64_line(fd, value)) to centralize formatting and error handling.
- When using write() to send the formatted spawn counts, only a single write call is made; if you want this to be robust beyond the "very short to a pipe" case, consider looping until all bytes are written or returning a clear error on short writes.
## Individual Comments
### Comment 1
<location> `ring_loadables/forkrun_ring.c:695-698` </location>
<code_context>
if (n_spawn > (W_max_val - W)) n_spawn = W_max_val - W;
if (fd_spawn >= 0) {
- dprintf(fd_spawn, "%lu\n", n_spawn);
+ // CRITICAL FIX: Replace buffered dprintf with unbuffered write
+ char sbuf[64];
+ int slen = snprintf(sbuf, sizeof(sbuf), "%lu\n", n_spawn);
+ if (slen > 0) SYS_CHK(write(fd_spawn, sbuf, slen));
+
W += n_spawn;
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against snprintf returning a length larger than the buffer to avoid over-reading in write()
Because `snprintf` returns the number of characters that *would* have been written, `slen` can be larger than `sizeof(sbuf) - 1` if truncation occurs, even though the buffer is smaller. Using `slen` directly in `write()` can therefore read past `sbuf`.
Clamp the length passed to `write()`, for example:
```c
int slen = snprintf(sbuf, sizeof(sbuf), "%lu\n", n_spawn);
if (slen > 0) {
size_t to_write = (slen < (int)sizeof(sbuf)) ? (size_t)slen : sizeof(sbuf) - 1;
SYS_CHK(write(fd_spawn, sbuf, to_write));
}
```
The same clamping logic should be applied at the other `fd_spawn` write sites below.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
ring_loadables/forkrun_ring.c
Outdated
| // CRITICAL FIX: Replace buffered dprintf with unbuffered write | ||
| char sbuf[64]; | ||
| int slen = snprintf(sbuf, sizeof(sbuf), "%lu\n", n_spawn); | ||
| if (slen > 0) SYS_CHK(write(fd_spawn, sbuf, slen)); |
There was a problem hiding this comment.
issue (bug_risk): Guard against snprintf returning a length larger than the buffer to avoid over-reading in write()
Because snprintf returns the number of characters that would have been written, slen can be larger than sizeof(sbuf) - 1 if truncation occurs, even though the buffer is smaller. Using slen directly in write() can therefore read past sbuf.
Clamp the length passed to write(), for example:
int slen = snprintf(sbuf, sizeof(sbuf), "%lu\n", n_spawn);
if (slen > 0) {
size_t to_write = (slen < (int)sizeof(sbuf)) ? (size_t)slen : sizeof(sbuf) - 1;
SYS_CHK(write(fd_spawn, sbuf, to_write));
}The same clamping logic should be applied at the other fd_spawn write sites below.
Added comprehensive design overview for forkrun's ring architecture, detailing purpose, high-level model, ring buffer mechanics, claiming work, eventfd usage, and failure handling.
This script benchmarks the performance of various checksum algorithms using the hyperfine tool, with options for running in a ramdisk and managing CPU priority.
Updated download URL for frun.bash to point to the latest testing branch.
Measure and export OS pipe limits for capacity.
|
/gemini review |
Removed the 'Extract Encoding Function' step and adjusted the verification step to issue a warning instead of exiting on failure.
Removed the verification step for the final script in the workflow.
Add a script to split base64 sequences into 4-bit and 8-bit segments
|




Summary by Sourcery
Fix worker spawn deadlock in the ring scanner and extend benchmarking coverage for additional pipeline patterns.
Bug Fixes:
Tests:
Chores: