diff --git a/zig/build/cuda.zig b/zig/build/cuda.zig index 5fadb17f06..2573889f3a 100644 --- a/zig/build/cuda.zig +++ b/zig/build/cuda.zig @@ -225,7 +225,8 @@ pub fn hostTests(b: *std.Build, draft_ids: *std.Build.Module, build_options: *st const host = b.graph.host; step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = b.createModule(.{ .root_source_file = b.path("zig/build/check_fatbins.zig"), .target = host }) })).step); const cuda = runtime(b, host, .debug, &.{}); - @import("h3_host.zig").targets(b, cuda, step); + // H3's library opens its checkpoint with mmap: not Windows + if (host.result.os.tag != .windows) @import("h3_host.zig").targets(b, cuda, step); const mods = family(b, host, .debug, cuda, draft_ids); @import("qwen_contract.zig").host(b, mods.core, step); const mtp_policy = b.createModule(.{ .root_source_file = b.path("zig/nemotron_mtp_policy_host.zig"), .target = host, .optimize = .debug, .link_libc = true, .imports = &.{ .{ .name = "nemotron", .module = mods.nemotron }, .{ .name = "lanes", .module = mods.lanes } } }); @@ -358,7 +359,8 @@ pub fn hostTests(b: *std.Build, draft_ids: *std.Build.Module, build_options: *st _ = open_object.getEmittedBin(); b.step("compile-omni-video-host", "Compile actual native CUDA startup and offer for Linux without images or GPU execution").dependOn(&open_object.step); const h3_checkpoint = b.createModule(.{ .root_source_file = b.path("zig/src/families/h3/checkpoint.zig"), .target = host, .optimize = .debug, .link_libc = true }); - step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = h3_checkpoint })).step); + // the checkpoint maps its file with mmap: not Windows + if (host.result.os.tag != .windows) step.dependOn(&b.addRunArtifact(b.addTest(.{ .root_module = h3_checkpoint })).step); // the HTTP server's unit tests (zig/src/server/root.zig), which the macOS build runs, on Linux hosts too const template = b.createModule(.{ .root_source_file = b.path("zig/src/core/template/template.zig"), .target = host, .optimize = .debug, .link_libc = true }); const server_tests = b.createModule(.{ diff --git a/zig/src/core/checkpoint_identity_test.zig b/zig/src/core/checkpoint_identity_test.zig index a058bca520..c2e3857c8a 100644 --- a/zig/src/core/checkpoint_identity_test.zig +++ b/zig/src/core/checkpoint_identity_test.zig @@ -124,6 +124,7 @@ fn fixturePaths(a: std.mem.Allocator, tmp: *const std.testing.TmpDir, sub: []con } test "whole and split consumers share cached file digests and still check manifests" { + if (!@import("digest_key.zig").persistent) return error.SkipZigTest; const a = std.testing.allocator; const io = std.testing.io; var tmp = std.testing.tmpDir(.{}); @@ -168,6 +169,7 @@ test "full checkpoint identity includes payloads and detects changed files at re } test "a corrupt shared digest cache refuses the real content consumer" { + if (!@import("digest_key.zig").persistent) return error.SkipZigTest; const a = std.testing.allocator; const io = std.testing.io; var tmp = std.testing.tmpDir(.{}); diff --git a/zig/src/core/digest_cache_probe.zig b/zig/src/core/digest_cache_probe.zig index ad75b8c90e..87ddf5e253 100644 --- a/zig/src/core/digest_cache_probe.zig +++ b/zig/src/core/digest_cache_probe.zig @@ -30,5 +30,7 @@ pub fn main(init: std.process.Init) !void { } var output: [32]u8 = undefined; const text = try std.fmt.bufPrint(&output, "{d}\n", .{calls}); + // std.c.write takes a HANDLE on Windows; this executable is built without the sys module + if (@import("builtin").os.tag == .windows) return std.Io.File.stdout().writeStreamingAll(init.io, text); if (std.c.write(1, text.ptr, text.len) != text.len) return error.Output; } diff --git a/zig/src/core/digest_key.zig b/zig/src/core/digest_key.zig index 966f1fd223..e3682575ee 100644 --- a/zig/src/core/digest_key.zig +++ b/zig/src/core/digest_key.zig @@ -31,7 +31,7 @@ pub const Key = struct { } const s = try file.stat(io); if (s.kind != .file) return error.DigestNotRegular; - return .{ .device = 0, .inode = s.inode, .size = s.size, .mtime = s.mtime.toNanoseconds(), .ctime = s.ctime.toNanoseconds() }; + return .{ .device = 0, .inode = @as(u64, @bitCast(s.inode)), .size = s.size, .mtime = s.mtime.toNanoseconds(), .ctime = s.ctime.toNanoseconds() }; } pub fn equal(a: Key, b: Key) bool { diff --git a/zig/src/core/picture/picture_test.zig b/zig/src/core/picture/picture_test.zig index 287493a71c..80ddb5f4d1 100644 --- a/zig/src/core/picture/picture_test.zig +++ b/zig/src/core/picture/picture_test.zig @@ -119,7 +119,7 @@ test "edge pictures (zig/tests/fixtures/picture/edges.json) get 0.6.6's outcome, /// WebP cases need the pinned libwebp: required when TENSORFOLD_LIBWEBP names one, skipped when none loads. fn webpReady(a: std.mem.Allocator) !bool { if (picture.webp.available(std.testing.io, a)) return true; - if (std.testing.environ.getPosix(picture.webp.env) != null) return error.PinnedLibraryDidNotLoad; + if (@import("sys").getenv(picture.webp.env) != null) return error.PinnedLibraryDidNotLoad; std.debug.print("libwebp {s} not found: WebP pixel cases skipped\n", .{picture.webp.pinned}); return false; } diff --git a/zig/src/core/picture/webp.zig b/zig/src/core/picture/webp.zig index db6d9f7131..b45a2180e1 100644 --- a/zig/src/core/picture/webp.zig +++ b/zig/src/core/picture/webp.zig @@ -66,7 +66,7 @@ fn find(io: std.Io, a: Allocator) Loaded { /// One candidate: null when it does not load or lacks a function; `.wrong` when its version is not the pin. fn open(path: []const u8) ?Loaded { - var dl = std.DynLib.open(path) catch return null; + var dl = @import("sys").DynLib.open(path) catch return null; var f: Fns = undefined; const info = @typeInfo(Fns).@"struct"; inline for (info.field_names, info.field_types) |name, T| { diff --git a/zig/src/cuda/copy_source_close_test.zig b/zig/src/cuda/copy_source_close_test.zig index d1bf218d06..f71959f230 100644 --- a/zig/src/cuda/copy_source_close_test.zig +++ b/zig/src/cuda/copy_source_close_test.zig @@ -84,7 +84,7 @@ pub fn run(reap: *const fn (*const Driver) void) !void { Fake.s = .{}; Fake.reap = reap; var d: Driver = undefined; - d.lib = try std.DynLib.open(if (builtin.os.tag == .windows) "kernel32.dll" else if (builtin.os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); + d.lib = try @import("sys").DynLib.open(if (builtin.os.tag == .windows) "kernel32.dll" else if (builtin.os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); d.api.cuMemHostAlloc = Fake.alloc; d.api.cuMemFreeHost = Fake.free; d.api.cuMemcpyHtoDAsync_v2 = Fake.copy; diff --git a/zig/src/cuda/copy_source_race_test.zig b/zig/src/cuda/copy_source_race_test.zig index 0eed0c9a1b..68583dfb15 100644 --- a/zig/src/cuda/copy_source_race_test.zig +++ b/zig/src/cuda/copy_source_race_test.zig @@ -97,7 +97,7 @@ pub fn run(reaper: *const fn (*const Driver) void, completing: bool) !void { Fake.reaper = reaper; Fake.completing = completing; var d: Driver = undefined; - d.lib = try std.DynLib.open(if (builtin.os.tag == .windows) "kernel32.dll" else if (builtin.os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); + d.lib = try @import("sys").DynLib.open(if (builtin.os.tag == .windows) "kernel32.dll" else if (builtin.os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); d.api.cuMemHostAlloc = Fake.alloc; d.api.cuMemFreeHost = Fake.free; d.api.cuMemcpyHtoDAsync_v2 = Fake.copy; diff --git a/zig/src/cuda/memory_receipt.zig b/zig/src/cuda/memory_receipt.zig index a9b6aa7060..6143868f9e 100644 --- a/zig/src/cuda/memory_receipt.zig +++ b/zig/src/cuda/memory_receipt.zig @@ -1,13 +1,14 @@ //! Opt-in process-local allocator boundary receipts; no CUDA calls and no global peak reset unless requested. const std = @import("std"); +const platform = @import("sys"); const memory = @import("memory.zig"); pub const Phase = enum { load_begin, load_end, cleanup_begin, cleanup_end, reset }; pub fn enabled() bool { if (@import("builtin").is_test) return false; - const env = std.c.getenv("TF_CUDA_MEMORY_RECEIPTS") orelse return false; - return std.mem.eql(u8, std.mem.span(env), "1"); + const env = platform.getenv("TF_CUDA_MEMORY_RECEIPTS") orelse return false; + return std.mem.eql(u8, env, "1"); } pub fn emit(rank: u32, phase: Phase, reset: bool) void { @@ -17,22 +18,22 @@ pub fn emit(rank: u32, phase: Phase, reset: bool) void { pub fn emitUsage(rank: u32, phase: Phase, reset: bool, usage: memory.Usage) void { if (!enabled()) return; - var ts: std.c.timespec = undefined; - const ns: ?u64 = if (std.c.clock_gettime(.MONOTONIC, &ts) == 0) + var ts: platform.c.timespec = undefined; + const ns: ?u64 = if (platform.c.clock_gettime(platform.c.CLOCK.MONOTONIC, &ts) == 0) @as(u64, @intCast(ts.sec)) * std.time.ns_per_s + @as(u64, @intCast(ts.nsec)) else null; - const receipt: Receipt = .{ .pid = std.c.getpid(), .rank = rank, .phase = phase, .reset = reset, .monotonic_ns = ns, .usage = usage }; + const receipt: Receipt = .{ .pid = platform.c.getpid(), .rank = rank, .phase = phase, .reset = reset, .monotonic_ns = ns, .usage = usage }; std.debug.print("TF_MEMORY {f}\n", .{std.json.fmt(receipt, .{})}); } pub fn snapshot(rank: u32, phase: Phase, reset: bool, monotonic_ns: ?u64) Receipt { - return .{ .pid = std.c.getpid(), .rank = rank, .phase = phase, .reset = reset, .monotonic_ns = monotonic_ns, .usage = memory.usage(reset) }; + return .{ .pid = platform.c.getpid(), .rank = rank, .phase = phase, .reset = reset, .monotonic_ns = monotonic_ns, .usage = memory.usage(reset) }; } pub const Receipt = struct { schema: u32 = 1, - pid: std.c.pid_t, + pid: platform.c.pid_t, rank: u32, phase: Phase, reset: bool, diff --git a/zig/src/cuda/roce.zig b/zig/src/cuda/roce.zig index 25295d9bcc..9faf1af51a 100644 --- a/zig/src/cuda/roce.zig +++ b/zig/src/cuda/roce.zig @@ -1,6 +1,7 @@ //! Two-rank all-gathers as one-shot RoCE writes after b12x's RoCEnante (local-inference-lab/b12x, Apache-2.0). const std = @import("std"); +const platform = @import("sys"); const abi = @import("abi.zig"); const Driver = @import("driver.zig").Driver; const memory = @import("memory.zig"); @@ -212,7 +213,7 @@ const Hca = struct { pub const Gather = struct { gpa: std.mem.Allocator, d: *const Driver, - lib: std.DynLib, + lib: platform.DynLib, api: Api, rank: u8, hcas: [max_hcas]Hca = @splat(.{}), @@ -284,7 +285,7 @@ pub const Gather = struct { fn setup(g: *Gather, gpa: std.mem.Allocator, io: std.Io, d: *const Driver, rank: u8, max_bytes: usize) !void { g.* = .{ .gpa = gpa, .d = d, .lib = undefined, .api = undefined, .rank = rank, .layout = .of(max_bytes), .region = undefined, .region_dev = 0, .counters = undefined, .module = undefined, .f = undefined, .max_bytes = max_bytes }; - g.lib = std.DynLib.open("libibverbs.so.1") catch return error.VerbsUnavailable; + g.lib = platform.DynLib.open("libibverbs.so.1") catch return error.VerbsUnavailable; errdefer g.lib.close(); const info = @typeInfo(Api).@"struct"; inline for (info.field_names, info.field_types) |name, T| { diff --git a/zig/src/families/drama3/cuda/blas.zig b/zig/src/families/drama3/cuda/blas.zig index 60ff29a991..97a78c72c5 100644 --- a/zig/src/families/drama3/cuda/blas.zig +++ b/zig/src/families/drama3/cuda/blas.zig @@ -1,5 +1,6 @@ //! cuBLAS (the classic API) opened at run time: the strided batched GEMM Drama 3's prompt rows and codec take. const std = @import("std"); +const platform = @import("sys"); const cuda = @import("cuda"); pub const Status = c_int; @@ -33,7 +34,7 @@ pub const Api = struct { /// The library and one handle with its workspace, bound to a stream per call. pub const Blas = struct { - lib: std.DynLib, + lib: platform.DynLib, api: Api, h: Handle, @@ -49,7 +50,7 @@ pub const Blas = struct { } fn openPath(path: []const u8, workspace: Ptr, workspace_bytes: usize) Error!Blas { - var lib = std.DynLib.open(path) catch return error.LibraryUnavailable; + var lib = platform.DynLib.open(path) catch return error.LibraryUnavailable; errdefer lib.close(); var b: Blas = .{ .lib = lib, .api = undefined, .h = null }; const info = @typeInfo(Api).@"struct"; diff --git a/zig/src/families/flashnext/cuda_lanes_restore_test.zig b/zig/src/families/flashnext/cuda_lanes_restore_test.zig index e0e5967ecf..aa441f6166 100644 --- a/zig/src/families/flashnext/cuda_lanes_restore_test.zig +++ b/zig/src/families/flashnext/cuda_lanes_restore_test.zig @@ -49,6 +49,7 @@ pub fn fakeDriver() cuda.Driver { /// Exercise the actual lane open and explicit snapshot entry points with a CPU control peer. pub fn run(comptime Cuda: type, comptime open: anytype, comptime restore: anytype, comptime drop: anytype, explicit: bool, drafting: bool) !void { + if (@import("builtin").os.tag == .windows) return error.SkipZigTest; // the peer rank is a Unix socket pair const a = std.testing.allocator; Device.next = 0x100000; Device.copies = 0; diff --git a/zig/src/families/flashnext/cuda_ple.zig b/zig/src/families/flashnext/cuda_ple.zig index 459f56905d..1ea1fe4e7b 100644 --- a/zig/src/families/flashnext/cuda_ple.zig +++ b/zig/src/families/flashnext/cuda_ple.zig @@ -388,7 +388,7 @@ pub const Ngram = struct { const file = findOpen(g.files.items, path) orelse file: { var o = try Open.load(gpa, io, path); errdefer o.close(gpa); - std.posix.madvise(o.file.map.memory.ptr, o.file.map.memory.len, std.posix.MADV.RANDOM) catch {}; + if (@import("builtin").os.tag != .windows) std.posix.madvise(o.file.map.memory.ptr, o.file.map.memory.len, std.posix.MADV.RANDOM) catch {}; try g.files.append(gpa, o); break :file &g.files.items[g.files.items.len - 1]; }; diff --git a/zig/src/families/flashnext/cuda_rank_media.zig b/zig/src/families/flashnext/cuda_rank_media.zig index 79a783b8b4..4461af16e0 100644 --- a/zig/src/families/flashnext/cuda_rank_media.zig +++ b/zig/src/families/flashnext/cuda_rank_media.zig @@ -58,5 +58,5 @@ test "rank media frames are bounded and rebuild the same image plan" { } test { - _ = @import("cuda_rank_media_test.zig"); + if (@import("builtin").os.tag != .windows) _ = @import("cuda_rank_media_test.zig"); // over a Unix socket pair } diff --git a/zig/src/families/flashnext/cuda_rank_wire.zig b/zig/src/families/flashnext/cuda_rank_wire.zig index a49429688d..98606b2994 100644 --- a/zig/src/families/flashnext/cuda_rank_wire.zig +++ b/zig/src/families/flashnext/cuda_rank_wire.zig @@ -1,6 +1,7 @@ //! Bounded Linux TCP control channel. Tensor bytes travel over NCCL; this channel owns command order and peer EOF. const std = @import("std"); const builtin = @import("builtin"); +const platform = @import("sys"); const p = std.posix; const net = std.Io.net; @@ -43,8 +44,8 @@ pub const Header = struct { }; pub fn now() u64 { - var ts: std.c.timespec = undefined; - if (std.c.clock_gettime(.MONOTONIC, &ts) != 0 or ts.sec < 0) return 0; + var ts: platform.c.timespec = undefined; + if (platform.c.clock_gettime(platform.c.CLOCK.MONOTONIC, &ts) != 0 or ts.sec < 0) return 0; return @as(u64, @intCast(ts.sec)) * std.time.ns_per_ms * 1000 + @as(u64, @intCast(ts.nsec)); } @@ -53,8 +54,8 @@ pub fn deadline(ms: u64) u64 { } pub fn pause() void { - const ts: std.c.timespec = .{ .sec = 0, .nsec = 50_000 }; - _ = std.c.nanosleep(&ts, null); + const ts: platform.c.timespec = .{ .sec = 0, .nsec = 50_000 }; + _ = platform.c.nanosleep(&ts, null); } fn wait(fd: p.socket_t, events: i16, until: ?u64) !void { @@ -131,6 +132,7 @@ pub const Link = struct { } pub fn send(l: Link, bytes: []const u8, until: u64) !void { + if (builtin.os.tag == .windows) return error.RankPlatform; // no MSG.NOSIGNAL or DONTWAIT in Winsock var at: usize = 0; while (at < bytes.len) { if (now() >= until) return error.RankTimeout; @@ -148,6 +150,7 @@ pub const Link = struct { } pub fn receive(l: Link, bytes: []u8, until: ?u64) !void { + if (builtin.os.tag == .windows) return error.RankPlatform; var at: usize = 0; while (at < bytes.len) { if (until) |end| if (now() >= end) return error.RankTimeout; @@ -179,6 +182,7 @@ pub const Link = struct { /// A non-consuming EOF check while a GPU collective progresses. A future control frame stays queued. pub fn checkPeer(l: Link) !void { + if (builtin.os.tag == .windows) return error.RankPlatform; var byte: u8 = 0; const rc = std.c.recv(l.fd, &byte, 1, p.MSG.PEEK | p.MSG.DONTWAIT); if (rc == 0) return error.RankDisconnected; diff --git a/zig/src/families/nemotron/cuda_pages_safety_test.zig b/zig/src/families/nemotron/cuda_pages_safety_test.zig index 057c443672..3a00438422 100644 --- a/zig/src/families/nemotron/cuda_pages_safety_test.zig +++ b/zig/src/families/nemotron/cuda_pages_safety_test.zig @@ -159,6 +159,7 @@ const Child = struct { extern "c" fn fork() c_int; }; test "kv safety: paged constructor fatal completion failure precedes every destination or parent release" { + if (@import("builtin").os.tag == .windows) return error.SkipZigTest; // the child process comes from fork for ([_]Case{ .clear, .slots, .cpu, .wait }) |case| { const pid = Child.fork(); if (pid < 0) return error.ForkFailed; diff --git a/zig/src/native/cuda_load_gpu.zig b/zig/src/native/cuda_load_gpu.zig index 41d8abd90e..1774c6eebb 100644 --- a/zig/src/native/cuda_load_gpu.zig +++ b/zig/src/native/cuda_load_gpu.zig @@ -156,7 +156,7 @@ const Fake = struct { const g = try t.allocator.create(Gpu); g.gpa = t.allocator; g.next = null; - g.driver.lib = try std.DynLib.open(if (@import("builtin").os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); + g.driver.lib = try @import("sys").DynLib.open(if (@import("builtin").os.tag == .windows) "kernel32.dll" else if (@import("builtin").os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); g.driver.api.cuMemAlloc_v2 = alloc; g.driver.api.cuMemFree_v2 = free; g.driver.api.cuMemcpyHtoD_v2 = copy; @@ -278,7 +278,7 @@ const Barrier = @import("load_barrier_test.zig"); fn secondGpu(first: *Gpu) !*Gpu { const g = try t.allocator.create(Gpu); g.* = first.*; - g.driver.lib = try std.DynLib.open(if (@import("builtin").os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); + g.driver.lib = try @import("sys").DynLib.open(if (@import("builtin").os.tag == .windows) "kernel32.dll" else if (@import("builtin").os.tag == .macos) "/usr/lib/libSystem.B.dylib" else "libc.so.6"); g.ctx = .{ .d = &g.driver, .device = 1, .handle = @ptrFromInt(7) }; g.next = null; return g; diff --git a/zig/src/server/listener.zig b/zig/src/server/listener.zig index 55dee3333c..4095cd8e51 100644 --- a/zig/src/server/listener.zig +++ b/zig/src/server/listener.zig @@ -155,10 +155,12 @@ test "accepted IPv4 and IPv6 TCP streams disable Nagle for incremental responses if (posix.errno(posix.system.connect(client, &storage.any, len)) != .SUCCESS) return error.ConnectFailed; const accepted = acceptWithin(listener, 2000) orelse return error.AcceptFailed; defer _ = posix.system.close(accepted.fd); - var value: c_int = 0; - var size: posix.socklen_t = @sizeOf(c_int); - try std.testing.expect(std.c.getsockopt(accepted.fd, posix.IPPROTO.TCP, posix.TCP.NODELAY, &value, &size) == 0); - try std.testing.expect(value != 0); + if (!platform.windows) { // sys wraps no getsockopt to read the option back on Windows + var value: c_int = 0; + var size: posix.socklen_t = @sizeOf(c_int); + try std.testing.expect(std.c.getsockopt(accepted.fd, posix.IPPROTO.TCP, posix.TCP.NODELAY, &value, &size) == 0); + try std.testing.expect(value != 0); + } } } diff --git a/zig/src/server/root.zig b/zig/src/server/root.zig index c7b31b5004..dcb194bf17 100644 --- a/zig/src/server/root.zig +++ b/zig/src/server/root.zig @@ -39,7 +39,7 @@ test { _ = @import("chunk_plan.zig"); _ = @import("status_routes.zig"); _ = @import("speech.zig"); - _ = @import("speech_stream_test.zig"); + if (comptime @import("builtin").os.tag != .windows) _ = @import("speech_stream_test.zig"); // over a Unix socket pair _ = @import("drama_prompt.zig"); _ = @import("health_test.zig"); _ = @import("memory_routes.zig"); @@ -110,9 +110,6 @@ test { _ = @import("benchmark_cli_test.zig"); _ = @import("benchmark_run_test.zig"); _ = @import("benchmark_early_test.zig"); + _ = @import("benchmark_config_test.zig"); } } - -test { - _ = @import("benchmark_config_test.zig"); -} diff --git a/zig/src/server/speech.zig b/zig/src/server/speech.zig index ec6166bed9..b7f474facd 100644 --- a/zig/src/server/speech.zig +++ b/zig/src/server/speech.zig @@ -1,5 +1,6 @@ //! POST /v1/audio/speech: WAV or raw PCM whole, or raw PCM chunks with stream; only complete synthesis is audio. const std = @import("std"); +const platform = @import("sys"); const api = @import("engine_api"); const json = @import("json"); const errors = @import("errors.zig"); @@ -276,10 +277,10 @@ fn startStream(c: *Conn, sample_rate: u32) error{Closed}!void { if (c.close) c.addHeader("Connection", "close") catch return error.Closed; // each chunk leaves at once rather than waiting on the client's acknowledgement of the last (no effect off TCP) const one: c_int = 1; - _ = std.c.setsockopt(c.fd, std.posix.IPPROTO.TCP, std.posix.TCP.NODELAY, &one, @sizeOf(c_int)); + if (platform.windows) platform.posix.setsockopt(c.fd, platform.posix.IPPROTO.TCP, platform.posix.TCP.NODELAY, std.mem.asBytes(&one)) catch {} else _ = std.c.setsockopt(c.fd, std.posix.IPPROTO.TCP, std.posix.TCP.NODELAY, &one, @sizeOf(c_int)); // a blocking write into a full socket returns after the stall limit, so writeAll's poll can end a stalled stream - const stall: std.posix.timeval = .{ .sec = @divTrunc(c.timeouts.write_ms, 1000), .usec = @rem(c.timeouts.write_ms, 1000) * 1000 }; - std.posix.setsockopt(c.fd, std.posix.SOL.SOCKET, std.posix.SO.SNDTIMEO, std.mem.asBytes(&stall)) catch {}; + const stall: platform.posix.timeval = .{ .sec = @divTrunc(c.timeouts.write_ms, 1000), .usec = @rem(c.timeouts.write_ms, 1000) * 1000 }; + platform.posix.setsockopt(c.fd, platform.posix.SOL.SOCKET, platform.posix.SO.SNDTIMEO, std.mem.asBytes(&stall)) catch {}; return c.finish(""); } diff --git a/zig/src/vision/qwen_cuda_test.zig b/zig/src/vision/qwen_cuda_test.zig index 113cee6323..a088bb4069 100644 --- a/zig/src/vision/qwen_cuda_test.zig +++ b/zig/src/vision/qwen_cuda_test.zig @@ -245,6 +245,7 @@ const Child = struct { extern "c" fn kill(c_int, c_int) c_int; }; test "a stream and context that never complete end the process before an owner is freed" { + if (@import("builtin").os.tag == .windows) return error.SkipZigTest; // the child process comes from fork const pid = Child.fork(); if (pid < 0) return error.ForkFailed; if (pid == 0) {