From a1517a3677eed03e96e859d5aad0e957d5f156ac Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 21 Jul 2026 13:19:14 +0100 Subject: [PATCH] fix(ffi): replace removed std.atomic.Mutex with std.Thread.Mutex MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `Zig FFI Tests` has been failing on every PR with: src/catalogue.zig:16:22: error: root source file struct 'atomic' has no member named 'Mutex' `std.atomic.Mutex` was removed from the standard library. Nine files in ffi/zig/src/ still carried a byte-identical hand-rolled wrapper around it (verified: all nine hash to the same value — one template copied nine times): const Mutex = struct { state: std.atomic.Mutex = .unlocked, pub fn lock(m: *Mutex) void { while (!m.state.tryLock()) std.atomic.spinLoopHint(); } pub fn unlock(m: *Mutex) void { m.state.unlock(); } }; The wrapper's public surface — `lock()` / `unlock()`, instantiated as `var mutex: Mutex = .{}` — is already exactly `std.Thread.Mutex`'s, so the whole struct collapses to a one-line alias with no call-site changes: const Mutex = std.Thread.Mutex; This is also a behavioural improvement, not merely a compile fix: the wrapper busy-waited via `spinLoopHint`, burning a core under contention, whereas `std.Thread.Mutex` parks the waiting thread. 81 other files in this repo already use `std.Thread.Mutex` directly, so this converges on the in-tree norm rather than introducing a new one. Files: sla, catalogue, sdp, loader, verisimdb, guardian, community, federation, coprocessor. Verified under the CI pin (zig 0.15.2, per .github/workflows/zig-test.yml) — all four targets CI runs: zig build test PASS (13 + 3 tests passed) zig build readiness PASS (28/28 tests passed) zig build lib PASS (2/2 steps) zig build bench PASS (3/3 steps) Note: `.tool-versions` pins 0.15.1 while the workflow uses 0.15.2. Not changed here, but the two should be reconciled. Co-Authored-By: Claude Opus 4.8 --- ffi/zig/src/catalogue.zig | 15 ++++++--------- ffi/zig/src/community.zig | 15 ++++++--------- ffi/zig/src/coprocessor.zig | 15 ++++++--------- ffi/zig/src/federation.zig | 15 ++++++--------- ffi/zig/src/guardian.zig | 15 ++++++--------- ffi/zig/src/loader.zig | 15 ++++++--------- ffi/zig/src/sdp.zig | 15 ++++++--------- ffi/zig/src/sla.zig | 15 ++++++--------- ffi/zig/src/verisimdb.zig | 15 ++++++--------- 9 files changed, 54 insertions(+), 81 deletions(-) diff --git a/ffi/zig/src/catalogue.zig b/ffi/zig/src/catalogue.zig index 99c268cb..16caf52d 100644 --- a/ffi/zig/src/catalogue.zig +++ b/ffi/zig/src/catalogue.zig @@ -12,15 +12,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Types (must match src/abi/Catalogue.idr encodings) diff --git a/ffi/zig/src/community.zig b/ffi/zig/src/community.zig index 70904be9..bb5e9271 100644 --- a/ffi/zig/src/community.zig +++ b/ffi/zig/src/community.zig @@ -15,15 +15,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Constants diff --git a/ffi/zig/src/coprocessor.zig b/ffi/zig/src/coprocessor.zig index 38ab9156..6f4919ba 100644 --- a/ffi/zig/src/coprocessor.zig +++ b/ffi/zig/src/coprocessor.zig @@ -20,15 +20,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; extern fn getenv(name: [*:0]const u8) ?[*:0]const u8; diff --git a/ffi/zig/src/federation.zig b/ffi/zig/src/federation.zig index 01b607cf..c65b3532 100644 --- a/ffi/zig/src/federation.zig +++ b/ffi/zig/src/federation.zig @@ -20,15 +20,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Proven-hardened: Circuit breaker, retry, and rate limiter state diff --git a/ffi/zig/src/guardian.zig b/ffi/zig/src/guardian.zig index 8370c029..0624cc1a 100644 --- a/ffi/zig/src/guardian.zig +++ b/ffi/zig/src/guardian.zig @@ -22,15 +22,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Constants diff --git a/ffi/zig/src/loader.zig b/ffi/zig/src/loader.zig index 40bd6d58..41bd1528 100644 --- a/ffi/zig/src/loader.zig +++ b/ffi/zig/src/loader.zig @@ -13,15 +13,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; const crypto = std.crypto; const fs = std.fs; diff --git a/ffi/zig/src/sdp.zig b/ffi/zig/src/sdp.zig index f3fe51a0..fbcde370 100644 --- a/ffi/zig/src/sdp.zig +++ b/ffi/zig/src/sdp.zig @@ -16,15 +16,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Constants diff --git a/ffi/zig/src/sla.zig b/ffi/zig/src/sla.zig index 50fe5342..a91d66dd 100644 --- a/ffi/zig/src/sla.zig +++ b/ffi/zig/src/sla.zig @@ -15,15 +15,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; // ═══════════════════════════════════════════════════════════════════════ // Constants diff --git a/ffi/zig/src/verisimdb.zig b/ffi/zig/src/verisimdb.zig index 8f857665..53935135 100644 --- a/ffi/zig/src/verisimdb.zig +++ b/ffi/zig/src/verisimdb.zig @@ -16,15 +16,12 @@ const std = @import("std"); -const Mutex = struct { - state: std.atomic.Mutex = .unlocked, - pub fn lock(m: *Mutex) void { - while (!m.state.tryLock()) std.atomic.spinLoopHint(); - } - pub fn unlock(m: *Mutex) void { - m.state.unlock(); - } -}; +// `std.atomic.Mutex` was removed from the standard library; its replacement is +// `std.Thread.Mutex`, whose lock/unlock surface is identical to the hand-rolled +// wrapper this replaces. The wrapper also busy-waited via `spinLoopHint`, burning +// a core under contention; `std.Thread.Mutex` parks the thread instead. 81 other +// files in this repo already use this form. +const Mutex = std.Thread.Mutex; const Allocator = std.mem.Allocator; // ═══════════════════════════════════════════════════════════════════════