zba/src/scheduler.zig

69 lines
1.8 KiB
Zig
Raw Normal View History

2021-12-29 21:09:00 +00:00
const std = @import("std");
2022-10-21 08:11:44 +00:00
const Bus = @import("bus.zig").Bus;
const Arm7tdmi = @import("cpu.zig").Arm7tdmi;
2021-12-29 21:09:00 +00:00
const Order = std.math.Order;
const PriorityQueue = std.PriorityQueue;
const Allocator = std.mem.Allocator;
pub const Scheduler = struct {
tick: u64,
queue: PriorityQueue(Event, void, lessThan),
pub fn init(alloc: Allocator) @This() {
2021-12-29 21:09:00 +00:00
var scheduler = Scheduler{ .tick = 0, .queue = PriorityQueue(Event, void, lessThan).init(alloc, {}) };
scheduler.queue.add(.{
.kind = EventKind.HeatDeath,
.tick = std.math.maxInt(u64),
}) catch unreachable;
return scheduler;
}
2022-10-21 08:11:47 +00:00
pub fn deinit(self: *@This()) void {
self.queue.deinit();
}
2022-10-21 08:11:44 +00:00
pub fn handleEvent(self: *@This(), _: *Arm7tdmi, _: *Bus) void {
2021-12-29 21:09:00 +00:00
const should_handle = if (self.queue.peek()) |e| self.tick >= e.tick else false;
if (should_handle) {
const event = self.queue.remove();
switch (event.kind) {
.HeatDeath => {
std.debug.panic("[Scheduler] Somehow, a u64 overflowed", .{});
2021-12-29 21:09:00 +00:00
},
.HBlank => {
std.debug.panic("[Scheduler] tick {}: Hblank", .{self.tick});
},
.VBlank => {
std.debug.panic("[Scheduler] tick {}: VBlank", .{self.tick});
},
2021-12-29 21:09:00 +00:00
}
}
}
pub inline fn nextTimestamp(self: *@This()) u64 {
if (self.queue.peek()) |e| {
return e.tick;
} else unreachable;
}
};
pub const Event = struct {
kind: EventKind,
tick: u64,
};
2022-10-21 08:11:44 +00:00
fn lessThan(_: void, a: Event, b: Event) Order {
2021-12-29 21:09:00 +00:00
return std.math.order(a.tick, b.tick);
}
pub const EventKind = enum {
HeatDeath,
HBlank,
VBlank,
2021-12-29 21:09:00 +00:00
};