mirror of
https://github.com/ghostty-org/ghostty.git
synced 2026-08-24 16:11:43 +00:00
macos: cache unified logging loggers per scope
The logFn for macOS unified logging created and released an os_log_t logger on every single log call. Loggers are now cached per log scope for the process lifetime via an atomic pointer (a creation race wastes at most one create). Measured on macOS (Apple Silicon) with local timing instrumentation during app launch, the version-info logging block in global.init: before: 1070us-2629us after: 858us-1319us
This commit is contained in:
@@ -140,11 +140,12 @@ fn logFn(
|
||||
.err => .fault,
|
||||
};
|
||||
|
||||
// Initialize a logger. This is slow to do on every operation
|
||||
// but we shouldn't be logging too much.
|
||||
const logger = macos.os.Log.create(build_config.bundle_id, @tagName(scope));
|
||||
defer logger.release();
|
||||
logger.log(std.heap.c_allocator, mac_level, prefix ++ format, args);
|
||||
macosLogger(scope).log(
|
||||
std.heap.c_allocator,
|
||||
mac_level,
|
||||
prefix ++ format,
|
||||
args,
|
||||
);
|
||||
}
|
||||
|
||||
stderr: {
|
||||
@@ -166,6 +167,37 @@ fn logFn(
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the macOS unified logging logger for the given scope. The
|
||||
/// logger is created once per scope and cached for the lifetime of the
|
||||
/// process, because os_log object creation is slow (it shows up in
|
||||
/// startup profiles when done per log call) and Apple's guidance is to
|
||||
/// create loggers once and reuse them.
|
||||
fn macosLogger(comptime scope: @TypeOf(.EnumLiteral)) *macos.os.Log {
|
||||
const S = struct {
|
||||
var cached: std.atomic.Value(?*macos.os.Log) = .init(null);
|
||||
};
|
||||
|
||||
if (S.cached.load(.acquire)) |v| return v;
|
||||
|
||||
// Create and attempt to store our logger. If we race with another
|
||||
// thread then we use theirs and release ours.
|
||||
const created = macos.os.Log.create(
|
||||
build_config.bundle_id,
|
||||
@tagName(scope),
|
||||
);
|
||||
if (S.cached.cmpxchgStrong(
|
||||
null,
|
||||
created,
|
||||
.acq_rel,
|
||||
.acquire,
|
||||
)) |existing| {
|
||||
created.release();
|
||||
return existing.?;
|
||||
}
|
||||
|
||||
return created;
|
||||
}
|
||||
|
||||
pub const std_options: std.Options = .{
|
||||
// Our log level is always at least info in every build mode.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user