fix: drop select atomics in favour of a thread-safe channel

This commit is contained in:
2023-03-10 02:02:34 -06:00
parent 11eae091db
commit bd872ee1c0
4 changed files with 55 additions and 32 deletions

View File

@@ -5,9 +5,9 @@ const config = @import("../config.zig");
const Scheduler = @import("scheduler.zig").Scheduler;
const Arm7tdmi = @import("cpu.zig").Arm7tdmi;
const Tracker = @import("../util.zig").FpsTracker;
const TwoWayChannel = @import("zba-util").TwoWayChannel;
const Timer = std.time.Timer;
const Atomic = std.atomic.Atomic;
/// 4 Cycles in 1 dot
const cycles_per_dot = 4;
@@ -35,29 +35,40 @@ const RunKind = enum {
LimitedFPS,
};
pub fn run(quit: *Atomic(bool), pause: *Atomic(bool), cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: *Tracker) void {
pub fn run(cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: *Tracker, channel: *TwoWayChannel) void {
const audio_sync = config.config().guest.audio_sync and !config.config().host.mute;
if (audio_sync) log.info("Audio sync enabled", .{});
if (config.config().guest.video_sync) {
inner(.LimitedFPS, audio_sync, quit, pause, cpu, scheduler, tracker);
inner(.LimitedFPS, audio_sync, cpu, scheduler, tracker, channel);
} else {
inner(.UnlimitedFPS, audio_sync, quit, pause, cpu, scheduler, tracker);
inner(.UnlimitedFPS, audio_sync, cpu, scheduler, tracker, channel);
}
}
fn inner(comptime kind: RunKind, audio_sync: bool, quit: *Atomic(bool), pause: *Atomic(bool), cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: ?*Tracker) void {
fn inner(comptime kind: RunKind, audio_sync: bool, cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: ?*Tracker, channel: *TwoWayChannel) void {
if (kind == .UnlimitedFPS or kind == .LimitedFPS) {
std.debug.assert(tracker != null);
log.info("FPS tracking enabled", .{});
}
var paused: bool = false;
switch (kind) {
.Unlimited, .UnlimitedFPS => {
log.info("Emulation w/out video sync", .{});
while (!quit.load(.Monotonic)) {
if (pause.load(.Monotonic)) continue;
while (true) {
if (channel.emu.pop()) |e| switch (e) {
.Quit => break,
.Resume => paused = false,
.Pause => {
paused = true;
channel.gui.push(.Paused);
},
};
if (paused) continue;
runFrame(scheduler, cpu);
audioSync(audio_sync, cpu.bus.apu.stream, &cpu.bus.apu.is_buffer_full);
@@ -70,8 +81,17 @@ fn inner(comptime kind: RunKind, audio_sync: bool, quit: *Atomic(bool), pause: *
var timer = Timer.start() catch @panic("failed to initalize std.timer.Timer");
var wake_time: u64 = frame_period;
while (!quit.load(.Monotonic)) {
if (pause.load(.Monotonic)) continue;
while (true) {
if (channel.emu.pop()) |e| switch (e) {
.Quit => break,
.Resume => paused = false,
.Pause => {
paused = true;
channel.gui.push(.Paused);
},
};
if (paused) continue;
runFrame(scheduler, cpu);
const new_wake_time = videoSync(&timer, wake_time);