Skip to content

Merge PR #28: Execution cancellation API (jtakakura) + refinements#43

Merged
chaploud merged 9 commits intomainfrom
develop/feat-execution-cancellation
Apr 24, 2026
Merged

Merge PR #28: Execution cancellation API (jtakakura) + refinements#43
chaploud merged 9 commits intomainfrom
develop/feat-execution-cancellation

Conversation

@chaploud
Copy link
Copy Markdown
Contributor

Closes #27. Supersedes #28 (keeps @jtakakura's commits intact as the first three on this branch).

Summary

  • Core feature (by @jtakakura, 3 commits):
    • Vm.cancel() / WasmModule.cancel() / zwasm_module_cancel() — thread-safe async abort via atomic flag, polled at the existing deadline checkpoints (interpreter: every ~1024 instructions; JIT: via jit_fuel cap firing jitFuelCheckHelper).
    • Opt-out: Config.cancellable / zwasm_config_set_cancellable().
    • error.Canceled, FFI cross-thread test, docs + book (en/ja).
  • Refinements (6 follow-up commits on this branch):
    • Revert loadLinked(..., cancellable: bool) signature breakage — rely on Vm default, expose opt-out via post-load flag flip.
    • Config.cancellable?bool = null to match sibling fields (fuel, force_interpreter, ...).
    • Document reset-at-invoke semantics on WasmModule.cancel() Zig API.
    • Add D134 decision entry in .dev/decisions.md.
    • CHANGELOG [Unreleased] Added/Changed block.
    • Record bench baseline PR28 in bench/history.yaml (long benches ±1% of v1.8.0).

Test plan

  • zig build test — 398/398 pass, 0 leak (Mac aarch64)
  • python3 test/spec/run_spec.py --build --summary — 62263/62263, 0 fail, 0 skip
  • bash test/e2e/run_e2e.sh --convert --summary — 796/796, 0 fail
  • bash test/realworld/run_compat.sh — PASS=50, FAIL=0, CRASH=0
  • bash test/c_api/run_ffi_test.sh --build — 80/80 pass (includes cross-thread cancel test)
  • Minimal build -Djit=false -Dcomponent=false -Dwat=false — 267 pass, 15 skip
  • Size guard — 1.31MB stripped < 1.5MB
  • Bench recorded — long benches within ±1% of v1.8.0 baseline
  • Ubuntu x86_64 Merge Gate (pending, running via OrbStack)
  • ClojureWasm downstream verification (pending)
  • CI green

jtakakura and others added 9 commits April 22, 2026 12:47
perf: optimize atomic memory ordering in cancellation logic and add VS Code project settings
Restore the pre-cancellation `WasmModule.loadLinked(allocator, bytes, shared_store)`
signature. The positional bool was breaking source compatibility and reading poorly
at call sites (`loadLinked(..., true)` gave no clue what the literal meant).

The VM default `cancellable = true` covers every current caller. Hosts that need
to opt out can set `result.module.vm.cancellable = false` immediately after the
call; a docstring note points at this escape hatch.
`WasmModule.Config` consistently uses `?T = null` for fields that override a
Vm default, with null meaning "keep the default." `cancellable` stuck out as
the lone non-optional. Normalise it to `?bool = null` and apply in `loadCore`
only when set; this mirrors how `fuel`, `force_interpreter`, and friends are
handled.

The C API surface is unchanged — `zwasm_config_set_cancellable` still takes a
plain bool — and `CApiConfig.toModuleConfig` now forwards the C-side value as
a concrete optional. The default (true) is identical to the Vm default, so C
callers who never touch the setter see no behavioural change.
The Zig docstring said "Has no effect if no function is currently executing,"
which understated an easy-to-miss sharp edge: `invoke()` calls `vm.reset()`
before dispatching, which clears the cancel flag. A host that pre-arms cancel
on an idle module has the request silently dropped when the next `invoke()`
starts. Spell this out so callers know to race the cancel against a live
invocation (the FFI test already encodes this by looping cancel calls across
`invoke` start).
Captures the design behind PR #28: atomic flag piggybacking on the existing
deadline checkpoints, JIT fuel cap to periodically fire the helper, reset-at-
invoke semantics, and the cancellable=false opt-out for peak-throughput hosts.
Document the Zig/C/CLI surface added by PR #28 and the default-on JIT
checkpoint behaviour so v1.9.0 release notes can be assembled from the
Unreleased block without archaeology.
Mac aarch64 / ReleaseSafe / hyperfine 5 runs + 3 warmup. Long benches
(st_fib2, st_sieve, st_matrix, tgo_nqueens, tgo_list, tgo_mfr) are all
within ±1% of the v1.8.0 baseline — the default-on JIT periodic
check-in has no measurable impact on the hot path. Several sub-10ms
and string-heavy benches show high variance (hyperfine flagged
statistical outliers on gc_tree_cached specifically), which is
laptop-class measurement noise rather than a signal. The authoritative
Ubuntu x86_64 numbers will land at Merge Gate time.
@chaploud chaploud merged commit aa14117 into main Apr 24, 2026
5 checks passed
@chaploud chaploud deleted the develop/feat-execution-cancellation branch April 30, 2026 15:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support explicit cancellation of Wasm execution

2 participants