From d5e66caf2180324d83ad9be30e887849f5ed74da Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Fri, 10 Mar 2023 02:01:26 -0600 Subject: [PATCH] feat: implement a 2-way channel for message passing --- src/lib.zig | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/src/lib.zig b/src/lib.zig index 4df9855..037422b 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -1,8 +1,29 @@ const std = @import("std"); - const Log2Int = std.math.Log2Int; -pub fn Channel(comptime T: type) type { +const EmuMessage = enum { Pause, Resume, Quit }; +const GuiMessage = enum { Paused, Quit }; + +pub const TwoWayChannel = struct { + const Self = @This(); + + emu: Channel(EmuMessage), + gui: Channel(GuiMessage), + + pub fn init(items: []u8) Self { + comptime std.debug.assert(@sizeOf(EmuMessage) == @sizeOf(GuiMessage)); + comptime std.debug.assert(@sizeOf(@typeInfo([]u8).Pointer.child) == @sizeOf(EmuMessage)); + + std.debug.assert(items.len % 2 == 0); + + const left = @ptrCast([*]EmuMessage, items)[0 .. items.len / 2]; + const right = @ptrCast([*]GuiMessage, items)[items.len / 2 .. items.len]; + + return .{ .emu = Channel(EmuMessage).init(left), .gui = Channel(GuiMessage).init(right) }; + } +}; + +fn Channel(comptime T: type) type { return struct { const Self = @This(); const Index = usize; @@ -29,12 +50,12 @@ pub fn Channel(comptime T: type) type { }; } - pub fn push(self: *Self, value: T) Error!void { + pub fn push(self: *Self, value: T) void { const read_idx = self.read.load(.Acquire); const write_idx = self.write.load(.Acquire); // Check to see if Queue is full - if (write_idx - read_idx == self.buf.len) return Error.buffer_full; + if (write_idx - read_idx == self.buf.len) @panic("Channel: Buffer is full"); self.buf[self.mask(write_idx)] = value; @@ -49,7 +70,7 @@ pub fn Channel(comptime T: type) type { if (read_idx == write_idx) return null; std.atomic.fence(.Acquire); - const value = self.buf[self.mask(self.read)]; + const value = self.buf[self.mask(read_idx)]; std.atomic.fence(.Release); self.read.store(read_idx + 1, .Release); @@ -159,4 +180,4 @@ pub inline fn rotr(comptime T: type, x: T, r: anytype) T { const ar = @intCast(Log2Int(T), @mod(r, @typeInfo(T).Int.bits)); return x >> ar | x << (1 +% ~ar); -} \ No newline at end of file +}