From d097dcc2f561ed9f6ebbee1cc8072ddb98a9d206 Mon Sep 17 00:00:00 2001 From: paoda Date: Fri, 15 Dec 2023 02:35:58 -0600 Subject: [PATCH] fix(gui): quit when emu thread exits first --- lib/zba-gdbstub | 2 +- src/core/emu.zig | 12 ++++++------ src/main.zig | 19 +++++-------------- src/platform.zig | 4 ++-- 4 files changed, 14 insertions(+), 23 deletions(-) diff --git a/lib/zba-gdbstub b/lib/zba-gdbstub index 5947747..479319e 160000 --- a/lib/zba-gdbstub +++ b/lib/zba-gdbstub @@ -1 +1 @@ -Subproject commit 5947747533ec9ee63b4598455a281edd5e55b4a9 +Subproject commit 479319e7cad78c3fd38b6865c56e9fe9e78d495c diff --git a/src/core/emu.zig b/src/core/emu.zig index f972927..d85422f 100644 --- a/src/core/emu.zig +++ b/src/core/emu.zig @@ -18,12 +18,12 @@ pub const Synchro = struct { const AtomicBool = std.atomic.Atomic(bool); // UI -> Emulator - ui_busy: *AtomicBool, - paused: *AtomicBool, // FIXME: can ui_busy and paused be the same? - should_quit: *AtomicBool, + ui_busy: AtomicBool = AtomicBool.init(false), + paused: AtomicBool = AtomicBool.init(true), // FIXME: can ui_busy and paused be the same? + should_quit: AtomicBool = AtomicBool.init(false), // Emulator -> UI - did_pause: *AtomicBool, + did_pause: AtomicBool = AtomicBool.init(false), }; /// 4 Cycles in 1 dot @@ -52,7 +52,7 @@ const RunKind = enum { LimitedFPS, }; -pub fn run(cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: *Tracker, sync: Synchro) void { +pub fn run(cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: *Tracker, sync: *Synchro) void { const audio_sync = config.config().guest.audio_sync and !config.config().host.mute; if (audio_sync) log.info("Audio sync enabled", .{}); @@ -63,7 +63,7 @@ pub fn run(cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: *Tracker, sync: Synch } } -fn inner(comptime kind: RunKind, audio_sync: bool, cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: ?*Tracker, sync: Synchro) void { +fn inner(comptime kind: RunKind, audio_sync: bool, cpu: *Arm7tdmi, scheduler: *Scheduler, tracker: ?*Tracker, sync: *Synchro) void { if (kind == .UnlimitedFPS or kind == .LimitedFPS) { std.debug.assert(tracker != null); log.info("FPS tracking enabled", .{}); diff --git a/src/main.zig b/src/main.zig index 7b3f249..2299f1d 100644 --- a/src/main.zig +++ b/src/main.zig @@ -119,16 +119,7 @@ pub fn main() void { var gui = Gui.init(allocator, &bus.apu, title_ptr) catch |e| exitln("failed to init gui: {}", .{e}); defer gui.deinit(); - var sync: Synchro = blk: { - const AtomicBool = std.atomic.Atomic(bool); - - var ui_busy = AtomicBool.init(false); - var paused = AtomicBool.init(true); - var should_quit = AtomicBool.init(false); - var did_pause = AtomicBool.init(false); - - break :blk .{ .ui_busy = &ui_busy, .paused = &paused, .should_quit = &should_quit, .did_pause = &did_pause }; - }; + var sync: Synchro = .{}; if (result.args.gdb != 0) { const Server = @import("gdbstub").Server; @@ -145,25 +136,25 @@ pub fn main() void { log.info("Starting GDB Server Thread", .{}); - const thread = std.Thread.spawn(.{}, Server.run, .{ &server, allocator, sync.should_quit }) catch |e| exitln("gdb server thread crashed: {}", .{e}); + const thread = std.Thread.spawn(.{}, Server.run, .{ &server, allocator, &sync.should_quit }) catch |e| exitln("gdb server thread crashed: {}", .{e}); defer thread.join(); gui.run(.{ .cpu = &cpu, .scheduler = &scheduler, - .sync = sync, + .sync = &sync, }) catch |e| exitln("main thread panicked: {}", .{e}); } else { var tracker = FpsTracker.init(); - const thread = std.Thread.spawn(.{}, emu.run, .{ &cpu, &scheduler, &tracker, sync }) catch |e| exitln("emu thread panicked: {}", .{e}); + const thread = std.Thread.spawn(.{}, emu.run, .{ &cpu, &scheduler, &tracker, &sync }) catch |e| exitln("emu thread panicked: {}", .{e}); defer thread.join(); gui.run(.{ .cpu = &cpu, .scheduler = &scheduler, .tracker = &tracker, - .sync = sync, + .sync = &sync, }) catch |e| exitln("main thread panicked: {}", .{e}); } } diff --git a/src/platform.zig b/src/platform.zig index c5ddac2..ff37581 100644 --- a/src/platform.zig +++ b/src/platform.zig @@ -95,7 +95,7 @@ pub const Gui = struct { } const RunOptions = struct { - sync: Synchro, + sync: *Synchro, tracker: ?*FpsTracker = null, cpu: *Arm7tdmi, scheduler: *Scheduler, @@ -127,7 +127,7 @@ pub const Gui = struct { emu_loop: while (true) { // Outside of `SDL.SDL_QUIT` below, the DearImgui UI might signal that the program // should exit, in which case we should also handle this - if (self.state.should_quit) break :emu_loop; + if (self.state.should_quit or sync.should_quit.load(.Monotonic)) break :emu_loop; var event: SDL.SDL_Event = undefined; while (SDL.SDL_PollEvent(&event) != 0) {