Switch to using a queue for character devices

This commit is contained in:
2019-12-07 18:35:03 +00:00
parent 4f614c7727
commit 325ec9d591
5 changed files with 77 additions and 39 deletions

View File

@@ -1,7 +1,6 @@
const std = @import("std");
const CharDev = std.ArrayList(i32);
const CharDevLimit = 32;
const CharDev = std.atomic.Queue(i32);
pub fn loadFromStream(alloc: *std.mem.Allocator, stream: *std.fs.File.InStream.Stream) anyerror![]i32 {
var program = try alloc.alloc(i32, 1024);
@@ -91,6 +90,8 @@ const Instruction = struct {
};
pub const Machine = struct {
alloc: *std.mem.Allocator,
memory: []i32,
ip: usize = 0,
@@ -108,9 +109,10 @@ pub const Machine = struct {
pub fn init(alloc: *std.mem.Allocator, program: []i32) anyerror!Machine {
return Machine{
.alloc = alloc,
.memory = program,
.input = try CharDev.initCapacity(alloc, CharDevLimit),
.output = try CharDev.initCapacity(alloc, CharDevLimit),
.input = CharDev.init(),
.output = CharDev.init(),
};
}
@@ -119,8 +121,47 @@ pub const Machine = struct {
}
pub fn deinit(self: *Machine) void {
self.input.deinit();
self.output.deinit();
// TODO
}
pub fn readFromInput(self: *Machine, blocking: bool) !i32 {
return self.__in(&self.input, blocking);
}
pub fn writeToInput(self: *Machine, val: i32) !void {
return self.__out(&self.input, val);
}
pub fn readFromOutput(self: *Machine, blocking: bool) !i32 {
return self.__in(&self.output, blocking);
}
pub fn writeToOutput(self: *Machine, val: i32) !void {
return self.__out(&self.output, val);
}
inline fn __in(self: *Machine, dev: *CharDev, blocking: bool) !i32 {
var node = dev.get();
if (node == null) {
if (!blocking) return std.os.ReadError.WouldBlock;
// Just busy-wait for now
while (node == null) node = dev.get();
}
if (node) |n| {
defer self.alloc.destroy(n);
return n.data;
}
unreachable;
}
inline fn __out(self: *Machine, dev: *CharDev, val: i32) !void {
var node = try self.alloc.create(CharDev.Node);
node.data = val;
dev.put(node);
}
/// Read an immediate or position value from memory. Parameter determines
@@ -159,11 +200,11 @@ pub const Machine = struct {
},
.IN => {
self.__write(0, self.input.orderedRemove(0));
self.__write(0, try self.readFromInput(true)); // blocking read
},
.OUT => {
try self.output.append(self.__read(0, insn.modes[0]));
try self.writeToOutput(self.__read(0, insn.modes[0]));
},
.JNZ => {
@@ -256,12 +297,11 @@ test "day 5 example 1" {
var after: [5]i32 = .{ 666, 0, 4, 0, 99 };
var machine = try Machine.init(test_allocator, before[0..before.len]);
try machine.input.append(666);
try machine.writeToInput(666);
try machine.run();
assert(std.mem.eql(i32, before[0..before.len], after[0..after.len]));
assert(machine.output.len == 1);
assert(machine.output.at(0) == 666);
assert(666 == try machine.readFromOutput(false));
}
test "Instruction#decode ADD" {