From 70500ff2407c7e3e9ffdd9a51a9ee026fa8ab720 Mon Sep 17 00:00:00 2001 From: freref <35976402+freref@users.noreply.github.com> Date: Sun, 7 Sep 2025 21:55:05 +0200 Subject: [PATCH 1/4] Updates for 0.15.1 --- .gitignore | 5 ++--- build.zig | 29 +++++++++++++++++++++++++++++ build.zig.zon | 15 +++++++++++++++ demo.zig | 8 ++++---- spsc_ring.zig | 32 ++++++++++++++------------------ 5 files changed, 64 insertions(+), 25 deletions(-) create mode 100644 build.zig create mode 100644 build.zig.zon diff --git a/.gitignore b/.gitignore index d12ece0..3389c86 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ -zig-cache/ -demo -demo.o +.zig-cache/ +zig-out/ diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..91363a3 --- /dev/null +++ b/build.zig @@ -0,0 +1,29 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const mod = b.addModule("unmanaged_spsc_queue", .{ + .root_source_file = b.path("spsc_ring.zig"), + .target = target, + }); + + const example_exe = b.addExecutable(.{ + .name = "demo", + .root_module = b.createModule(.{ + .root_source_file = b.path("demo.zig"), + .target = target, + .optimize = optimize, + .imports = &.{ + .{ .name = "spsc_queue", .module = mod }, + }, + }), + }); + b.installArtifact(example_exe); + + const run_example = b.step("run", "Run the example"); + const run_example_cmd = b.addRunArtifact(example_exe); + run_example.dependOn(&run_example_cmd.step); + if (b.args) |args| run_example_cmd.addArgs(args); +} diff --git a/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..8c144b0 --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,15 @@ +.{ + .name = .zig_spsc_ring, + .version = "0.0.0", + .fingerprint = 0x2991ff75c63dce16, // Changing this has security and trust implications. + .minimum_zig_version = "0.15.1", + .dependencies = .{}, + .paths = .{ + "build.zig", + "build.zig.zon", + "src", + // For example... + //"LICENSE", + //"README.md", + }, +} diff --git a/demo.zig b/demo.zig index cd92908..6753774 100644 --- a/demo.zig +++ b/demo.zig @@ -16,14 +16,14 @@ fn producer(ring: *Ring(u64)) void { } fn consumer(ring: *Ring(u64)) !void { - const stdout_file = std.io.getStdOut().writer(); - var bw = std.io.bufferedWriter(stdout_file); - const stdout = bw.writer(); + var stdout_buffer: [1024]u8 = undefined; + var stdout_writer = std.fs.File.stdout().writer(&stdout_buffer); + const stdout = &stdout_writer.interface; while (true) { if (ring.dequeue()) |answer| { try stdout.print("answer = {}\n", .{answer}); - try bw.flush(); + try stdout.flush(); return; } } diff --git a/spsc_ring.zig b/spsc_ring.zig index 691807b..cdf1fe5 100644 --- a/spsc_ring.zig +++ b/spsc_ring.zig @@ -23,13 +23,13 @@ const std = @import("std"); const PaddedConsumer = struct { - head: std.atomic.Atomic(usize), - padding: [std.atomic.cache_line - @sizeOf(std.atomic.Atomic(usize))]u8 = undefined, + head: std.atomic.Value(usize), + padding: [std.atomic.cache_line - @sizeOf(std.atomic.Value(usize))]u8 = undefined, }; const PaddedProducer = struct { - tail: std.atomic.Atomic(usize), - padding: [std.atomic.cache_line - @sizeOf(std.atomic.Atomic(usize))]u8 = undefined, + tail: std.atomic.Value(usize), + padding: [std.atomic.cache_line - @sizeOf(std.atomic.Value(usize))]u8 = undefined, }; pub fn Ring(comptime T: type) type { @@ -45,16 +45,16 @@ pub fn Ring(comptime T: type) type { std.debug.assert(std.math.isPowerOfTwo(items.len)); return Self{ - .consumer = PaddedConsumer{ .head = std.atomic.Atomic(usize).init(0) }, - .producer = PaddedProducer{ .tail = std.atomic.Atomic(usize).init(0) }, + .consumer = PaddedConsumer{ .head = std.atomic.Value(usize).init(0) }, + .producer = PaddedProducer{ .tail = std.atomic.Value(usize).init(0) }, .items = items, .mask = items.len - 1, }; } pub inline fn enqueue(self: *Self, value: T) bool { - const consumer = self.consumer.head.load(std.atomic.Ordering.Acquire); - const producer = self.producer.tail.load(std.atomic.Ordering.Acquire); + const consumer = self.consumer.head.load(.acquire); + const producer = self.producer.tail.load(.acquire); const delta = producer + 1; if (delta & self.mask == consumer & self.mask) @@ -62,32 +62,28 @@ pub fn Ring(comptime T: type) type { self.items[producer & self.mask] = value; - std.atomic.fence(std.atomic.Ordering.Release); - self.producer.tail.store(delta, std.atomic.Ordering.Release); + self.producer.tail.store(delta, .release); return true; } pub inline fn dequeue(self: *Self) ?T { - const consumer = self.consumer.head.load(std.atomic.Ordering.Acquire); - const producer = self.producer.tail.load(std.atomic.Ordering.Acquire); + const consumer = self.consumer.head.load(.acquire); + const producer = self.producer.tail.load(.acquire); if (consumer == producer) return null; - std.atomic.fence(std.atomic.Ordering.Acquire); - const value = self.items[consumer & self.mask]; - std.atomic.fence(std.atomic.Ordering.Release); - self.consumer.head.store(consumer + 1, std.atomic.Ordering.Release); + self.consumer.head.store(consumer + 1, .release); return value; } pub inline fn length(self: *Self) usize { - const consumer = self.consumer.head.load(std.atomic.Ordering.Acquire); - const producer = self.producer.tail.load(std.atomic.Ordering.Acquire); + const consumer = self.consumer.head.load(.acquire); + const producer = self.producer.tail.load(.acquire); return (producer - consumer) & self.mask; } }; From 6c09b41966cf7f556d0bff0c2b82a99658133e38 Mon Sep 17 00:00:00 2001 From: freref <35976402+freref@users.noreply.github.com> Date: Sun, 7 Sep 2025 21:56:47 +0200 Subject: [PATCH 2/4] Remove old naming --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 91363a3..613fb35 100644 --- a/build.zig +++ b/build.zig @@ -4,7 +4,7 @@ pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); - const mod = b.addModule("unmanaged_spsc_queue", .{ + const mod = b.addModule("spsc_ring", .{ .root_source_file = b.path("spsc_ring.zig"), .target = target, }); From aab1415f346d03b3172e610242d1dcb97326cf7b Mon Sep 17 00:00:00 2001 From: freref <35976402+freref@users.noreply.github.com> Date: Sun, 7 Sep 2025 21:57:51 +0200 Subject: [PATCH 3/4] Remove more old naming --- build.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.zig b/build.zig index 613fb35..6132210 100644 --- a/build.zig +++ b/build.zig @@ -16,7 +16,7 @@ pub fn build(b: *std.Build) void { .target = target, .optimize = optimize, .imports = &.{ - .{ .name = "spsc_queue", .module = mod }, + .{ .name = "spsc_ring", .module = mod }, }, }), }); From ee0dfbe99dc45894f56f7a511d59c743a3b3b3ff Mon Sep 17 00:00:00 2001 From: freref <35976402+freref@users.noreply.github.com> Date: Sun, 7 Sep 2025 22:10:18 +0200 Subject: [PATCH 4/4] Move files to src dir --- build.zig | 4 ++-- demo.zig => src/demo.zig | 0 spsc_ring.zig => src/spsc_ring.zig | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename demo.zig => src/demo.zig (100%) rename spsc_ring.zig => src/spsc_ring.zig (100%) diff --git a/build.zig b/build.zig index 6132210..3f18aeb 100644 --- a/build.zig +++ b/build.zig @@ -5,14 +5,14 @@ pub fn build(b: *std.Build) void { const optimize = b.standardOptimizeOption(.{}); const mod = b.addModule("spsc_ring", .{ - .root_source_file = b.path("spsc_ring.zig"), + .root_source_file = b.path("src/spsc_ring.zig"), .target = target, }); const example_exe = b.addExecutable(.{ .name = "demo", .root_module = b.createModule(.{ - .root_source_file = b.path("demo.zig"), + .root_source_file = b.path("src/demo.zig"), .target = target, .optimize = optimize, .imports = &.{ diff --git a/demo.zig b/src/demo.zig similarity index 100% rename from demo.zig rename to src/demo.zig diff --git a/spsc_ring.zig b/src/spsc_ring.zig similarity index 100% rename from spsc_ring.zig rename to src/spsc_ring.zig