Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- const std = @import("std");
- const State = enum {
- peekto,
- readto,
- output,
- start,
- done,
- sever,
- anyinput,
- };
- const stageError = error {
- noInStream,
- noOutStream,
- };
- const Conn = struct {
- src:*Stage = undefined, // used by output
- from:usize = 0,
- sout:usize = 0,
- dst:*Stage = undefined, // user by input
- to:usize = 0,
- sin:usize = 0,
- in:bool = false,
- data:usize = undefined,
- fn set(self:*Conn, p:[]Stage, f:usize, o:usize, t:usize, s:usize) void {
- self.from=f;
- self.src=&p[f];
- self.sout=o;
- self.to=t;
- self.dst=&p[t];
- self.sin=s;
- if (o==0) self.src.outC = self;
- if (s==0) self.dst.inC = self;
- }
- //pub fn format(
- // self: SelfType,
- // comptime fmt: []const u8,
- // options: FormatOptions,
- // writer: anytype,
- //) !void {
- // if (fmt.len == 0) {
- // return std.fmt.format(writer, "Conn{*} src {*} {} dst {*} {} in {} {}\n\n",.{self, self.src, self.sout, self.dst, self.sin, self.in, self.data});
- // } else {
- // @compileError("Unknown format string: '" ++ fmt ++ "'");
- // }
- //}
- };
- const Stage = struct {
- outC:?*Conn = null,
- inC:?*Conn = null,
- state:State = .start,
- frame:anyframe = undefined,
- n:*std.ArrayList(Conn),
- pub fn peekto(self:*Stage) !usize {
- std.log.info("peekto {*} inC {*}\n",.{self, self.inC});
- if (self.inC) |c| {
- std.log.info("peekto {*} in {} {}\n",.{c, c.in, c.data});
- while (!c.in) {
- std.log.info("while suspended",.{});
- suspend{
- self.state = .peekto;
- self.frame=@frame();
- }
- }
- std.log.info("while exited",.{});
- }
- if (self.inC) |c| {
- self.state = .done;
- return c.data;
- }
- self.state = .done;
- return error.noInStream;
- }
- pub fn readto(self:*Stage) !usize {
- if (self.inC) |c| {
- while (!c.in) {
- suspend{
- self.state = .readto;
- self.frame=@frame();
- }
- }
- }
- if (self.inC) |c| {
- c.in = false;
- self.state = .done;
- return c.data;
- }
- self.state = .done;
- return error.noInStream;
- }
- pub fn output(self:*Stage, v:usize) !void {
- if (self.outC) |c| {
- while (c.in) {
- suspend {
- self.state = .output;
- self.frame=@frame();
- }
- }
- }
- if (self.outC) |c| {
- // std.log.info("p {} s {} v {}",.{l.num, l.sin, v});
- c.in = true;
- c.data = v;
- self.state = .done;
- return;
- }
- self.state = .done;
- return error.noOutStream;
- }
- pub fn selectOutput(self:*Stage, o:usize) !void {
- return self.setoutC(o);
- }
- pub fn selectInput(self:*Stage, i:usize) !void {
- return self.setinC(i);
- }
- pub fn selectAnyInput(self:*Stage) !usize {
- if (self.inC) |c| {
- while (!c.in) {
- suspend {
- self.state = .anyinput;
- self.frame=@frame();
- }
- }
- }
- if (self.inC) |c| {
- self.state = .done;
- return c.sin;
- }
- self.state = .done;
- return error.noInStream;
- }
- pub fn setinC(self:*Stage, i:usize) !void {
- for (self.n.items) |*c| {
- if (c.dst == self and c.sin == i) {
- self.inC = c;
- return;
- }
- }
- return error.noInStream;
- }
- pub fn setoutC(self:*Stage, o:usize) !void {
- for (self.n.items) |*c| {
- if (c.src == self and c.sout == o) {
- self.outC = c;
- return;
- }
- }
- return error.noOutStream;
- }
- };
- fn exactdiv(self:*Stage, d:usize) !void {
- var i:usize = undefined;
- while (true) {
- i = try self.peekto();
- if (i%d == 0)
- try self.selectOutput(0)
- else
- try self.selectOutput(1);
- _ = try self.output(i);
- _ = try self.readto();
- }
- }
- fn console(self:*Stage) !void {
- const stdout = std.io.getStdOut().writer();
- var i:usize = undefined;
- while (true) {
- i = try self.peekto();
- try stdout.print(" {}\n", .{i});
- _ = try self.output(i);
- _ = try self.readto();
- }
- }
- fn fanin(self:*Stage) !void {
- while (true) {
- _ = try self.selectAnyInput();
- try self.output(try self.peekto());
- _ = try self.readto();
- }
- }
- fn gen(self:*Stage, limit:usize) !void {
- var i:usize = 0;
- while (i<limit) : (i+=1) {
- try self.output(i);
- }
- }
- // print("{any}\n", .{ std.mem.asBytes(&s.in).* });
- pub fn main() !void {
- var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
- defer arena.deinit();
- const allocator = &arena.allocator;
- var nodes = try std.ArrayList(Conn).initCapacity(allocator, 20);
- try nodes.resize(20);
- for (nodes.items) |_| {
- try nodes.append(Conn{});
- }
- var p = [_]Stage{
- Stage{.n=&nodes},
- Stage{.n=&nodes},
- Stage{.n=&nodes},
- Stage{.n=&nodes},
- Stage{.n=&nodes}
- };
- nodes.items[0].set(&p,3,0,4,0);
- nodes.items[1].set(&p,2,0,3,0);
- nodes.items[2].set(&p,1,0,3,1);
- nodes.items[3].set(&p,1,1,2,0);
- nodes.items[4].set(&p,0,0,1,0);
- try nodes.resize(5); // think the rest the Conn nodes are still initialized incase we add connections dynamicily
- for (nodes.items) |*c| {
- std.log.info("start {*} src {*} {} dst {*} {} in {} {}\n\n",.{c, c.src, c.sout, c.dst, c.sin, c.in, c.data});
- }
- //p[0].set(.{Conn.set(&p,0,0,1,0), null});
- //p[1].set(.{Conn.set(&p,1,0,3,1), Conn.set(&p,1,1,2,0)});
- //p[2].set(.{Conn.set(&p,2,0,3,0), null});
- //p[3].set(.{Conn.set(&p,3,0,4,0), null});
- //p[4].set(.{null, null});
- _ = @asyncCall(try allocator.alignedAlloc(u8,16,@frameSize(console)), {}, console, .{&p[4]} );
- _ = @asyncCall(try allocator.alignedAlloc(u8,16,@frameSize(fanin)), {}, fanin, .{&p[3]} );
- _ = @asyncCall(try allocator.alignedAlloc(u8,16,@frameSize(exactdiv)), {}, exactdiv, .{&p[2], 3} );
- _ = @asyncCall(try allocator.alignedAlloc(u8,16,@frameSize(exactdiv)), {}, exactdiv, .{&p[1], 2} );
- _ = @asyncCall(try allocator.alignedAlloc(u8,16,@frameSize(gen)), {}, gen, .{&p[0], 10} );
- // main dispatch loop
- running: while (true) {
- std.log.info("\n\n",.{});
- for (nodes.items) |*c, i| {
- // const c = &nodes.items[i];
- // std.log.info("dst.state {} {} sin {} {} in {}\n",.{c.dst.state, c.to, c.sin, c.dst.outs, c.in });
- std.log.info("dst.state {} {} sin {} in {} {} ",.{c.dst.state, c.to, c.sin, c.in, c.data });
- std.log.info("src.state {} {} sout {} in {}",.{c.src.state, c.from, c.sout, c.in });
- if ((c.dst.state == .peekto or c.dst.state == .readto) and c.in) {
- resume c.dst.frame;
- std.log.info("p dst.state {} {} sin {} in {} {}\n\n",.{c.dst.state, c.to, c.sin, c.in, c.data });
- continue :running;
- }
- if (c.dst.state == .anyinput and c.in) {
- c.dst.inC = c;
- resume c.dst.frame;
- std.log.info("p dst.state {} {} sin {} \n\n",.{c.dst.state, c.to, c.sin });
- continue :running;
- }
- // std.log.info("src.state {} sout {} in {}\n",.{c.src.state, c.sout, c.in });
- if (c.src.state == .output and !c.in) {
- resume c.src.frame;
- std.log.info("p src.state {} {} sout {} in {} {}\n\n",.{c.src.state, c.from, c.sout, c.in, c.data });
- continue :running;
- }
- }
- // when we use os threads in stages we will need to wait for them here.
- break;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement