global: take minimal instead of juicy main

The early-stage main Zig wrapper recognizes if main only needs the
minimal state (args and lower-level environment) and skips a bunch of
unneeded initialization (allocator, arena, threaded I/O, and the
higher-level environment map). Particularly, the fact that it does not
set up an I/O instance means that we won't have any unneeded signal
handlers set up for the unused threaded I/O implementation, which is
similar in spirit to the fixes we applied for the C VT implementation,
with the notable difference that we do actually set a threaded I/O up in
global state - hence, again, we don't want the duplicate unused one.
This commit is contained in:
Chris Marchesi
2026-07-21 21:42:25 -07:00
parent da04b65d4c
commit 048619a6bf
3 changed files with 10 additions and 10 deletions

View File

@@ -45,12 +45,12 @@ pub const Action = enum {
};
/// An entrypoint for the benchmark CLI.
pub fn main(init: std.process.Init) !void {
try global.init(.{ .tool = init });
pub fn main(minimal: std.process.Init.Minimal) !void {
try global.init(.{ .tool = minimal });
const alloc = std.heap.c_allocator;
const action_ = try cli.action.detectArgs(Action, alloc, init.minimal.args);
const action_ = try cli.action.detectArgs(Action, alloc, minimal.args);
const action = action_ orelse return error.NoAction;
try mainAction(alloc, action, .{ .cli = init.minimal.args });
try mainAction(alloc, action, .{ .cli = minimal.args });
}
/// Arguments that can be passed to the benchmark.

View File

@@ -34,14 +34,14 @@ pub const xev = @import("xev").Dynamic;
var state: ?GlobalState = undefined;
pub const InitOpts = union(enum) {
main: std.process.Init,
main: std.process.Init.Minimal,
/// Same as `main` but for auxiliary tool binaries (e.g. ghostty-bench
/// and ghostty-gen) that have their own CLI action namespace. This
/// skips detection of ghostty app CLI actions, since tool actions
/// (e.g. `+terminal-stream`) are not valid app actions and would
/// otherwise cause init to fail with InvalidAction.
tool: std.process.Init,
tool: std.process.Init.Minimal,
c: struct {
argc: usize,
@@ -60,11 +60,11 @@ pub fn init(opts: InitOpts) !void {
.gpa = null,
.alloc = undefined,
.environ = switch (opts) {
.main, .tool => |m| m.minimal.environ,
.main, .tool => |m| m.environ,
.c => |c| c.environ,
},
.args = switch (opts) {
.main, .tool => |m| m.minimal.args,
.main, .tool => |m| m.args,
// TODO: Using the C API from Windows is unsupported at this time.
//
// When do we plan on supporting Windows, it's recommended to

View File

@@ -23,12 +23,12 @@ const MainReturn = switch (build_config.artifact) {
else => void,
};
pub fn main(init: std.process.Init) !MainReturn {
pub fn main(minimal: std.process.Init.Minimal) !MainReturn {
// We first start by initializing our global state. This will setup
// process-level state we need to run the terminal. The reason we use
// a global is because the C API needs to be able to access this state;
// no other Zig code should EVER access the global state.
global.init(.{ .main = init }) catch |err| {
global.init(.{ .main = minimal }) catch |err| {
var buffer: [1024]u8 = undefined;
var stderr_writer = std.Io.File.stderr().writer(global.io(), &buffer);
const stderr = &stderr_writer.interface;