a73x

fd817e8a

Add grep gate that forbids unbounded Vulkan waits outside vk_sync

a73x   2026-04-18 15:22

Commit message
Add grep gate that forbids unbounded Vulkan waits outside vk_sync

tests/check_unbounded_vk.sh scans src/ for direct calls to
vkd.waitForFences / acquireNextImageKHR / deviceWaitIdle /
queueWaitIdle and fails CI if any appear outside src/vk_sync.zig.
Wired into zig build test.

Part of issue ab6c92f0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

build.zig
Old New
@@ -341,6 +341,9 @@ pub fn build(b: *std.Build) void {
341 const vk_sync_tests = b.addTest(.{ .root_module = vk_sync_test_mod }); 341 const vk_sync_tests = b.addTest(.{ .root_module = vk_sync_test_mod });
342 test_step.dependOn(&b.addRunArtifact(vk_sync_tests).step); 342 test_step.dependOn(&b.addRunArtifact(vk_sync_tests).step);
343 343
344 const check_unbounded_vk = b.addSystemCommand(&.{ "tests/check_unbounded_vk.sh" });
345 test_step.dependOn(&check_unbounded_vk.step);
346
344 // capture module — --capture mode (render a VT script to PNG) 347 // capture module — --capture mode (render a VT script to PNG)
345 const capture_mod = b.createModule(.{ 348 const capture_mod = b.createModule(.{
346 .root_source_file = b.path("src/capture.zig"), 349 .root_source_file = b.path("src/capture.zig"),
tests/check_unbounded_vk.sh
Old New
@@ -0,0 +1,47 @@
1 #!/usr/bin/env bash
2 # Grep gate: fail if any source file outside src/vk_sync.zig calls
3 # Vulkan blocking primitives directly. All such calls must go through
4 # src/vk_sync.zig helpers (waitFenceBounded, acquireImageBounded,
5 # waitIdleForShutdown, etc.).
6
7 set -euo pipefail
8
9 REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
10 cd "$REPO_ROOT"
11
12 PATTERNS=(
13 'vkd\.waitForFences'
14 'vkd\.acquireNextImageKHR'
15 'vkd\.deviceWaitIdle'
16 'vkd\.queueWaitIdle'
17 )
18
19 # Find all .zig files in src/ except vk_sync.zig
20 mapfile -t files < <(find src -name '*.zig' ! -path 'src/vk_sync.zig' | sort)
21
22 violations=0
23 violation_lines=()
24
25 for file in "${files[@]}"; do
26 for pat in "${PATTERNS[@]}"; do
27 while IFS= read -r hit; do
28 violation_lines+=("$file:$hit")
29 violations=$((violations + 1))
30 done < <(grep -nE "$pat" "$file" || true)
31 done
32 done
33
34 if [[ $violations -gt 0 ]]; then
35 echo "ERROR: $violations unbounded Vulkan wait call(s) found outside src/vk_sync.zig:" >&2
36 for line in "${violation_lines[@]}"; do
37 echo " $line" >&2
38 done
39 echo "" >&2
40 echo "Use src/vk_sync.zig helpers instead:" >&2
41 echo " waitFenceBounded — replace vkd.waitForFences" >&2
42 echo " acquireImageBounded — replace vkd.acquireNextImageKHR" >&2
43 echo " waitIdleForShutdown — replace vkd.deviceWaitIdle / queueWaitIdle" >&2
44 exit 1
45 fi
46
47 echo "vk grep gate: ok (${#files[@]} files, no violations)"