Treat the zlib ordering program as a timer race

g05-zlib starts a zlib.gzip from a 0 ms island timer and arms a 2 ms
timer on the native side. The 0 ms timer's callback runs before the 2 ms
timer is due, so the gzip job races that timer: if the job completes on
libuv's thread pool before the timer's turn, its callback runs first.
Node orders the two the other way only because its first gzip usually
takes longer than the wait. With zlib already loaded and the thread pool
started, Node prints i-zlib first in about a quarter of runs. On fast
macOS hosts the native runs took the other order.

Mark it `// @order: race`, as g01 (fs), g03 (child process) and g04
(dns) already are, so its native runs must produce the lines of one of
Node's outputs in any order, and name thread-pool work among the races
the harness describes.
This commit is contained in:
Chris Tate
2026-10-28 01:47:01 -05:00
parent 5ef693cb89
commit d7198f016f
2 changed files with 4 additions and 1 deletions
@@ -1,4 +1,5 @@
// @requires-libnode
// @order: race
// X { T 0 { Z { L i-zlib } } } T 2 { B 80 L h-sync }
import { callSync } from "@scriptc/node";
import { readFile, writeSync } from "node:fs";
+3 -1
View File
@@ -13,7 +13,9 @@
* A program whose head says `// @order: race` races a timer against I/O
* whose duration differs between the sides (scriptc's own fs callbacks
* complete in one turn where Node's readFile takes several; module loading
* on the first call into Node takes longer than in a Node process), or two
* on the first call into Node takes longer than in a Node process; a job on
* libuv's thread pool, such as zlib's, can finish before or after a 2 ms
* timer depending on the host), or two
* equal timers armed on either side of an island call, which a millisecond
* boundary between them (likely in a sanitized build) puts in different
* loop turns, so Node permits orders it rarely produces in M runs. Its