config: control cgroup isolation

This commit is contained in:
Mitchell Hashimoto
2024-06-05 09:43:57 -07:00
parent 7d9da34259
commit ad5d44af10
3 changed files with 55 additions and 12 deletions

View File

@ -44,6 +44,9 @@ config: Config,
app: *c.GtkApplication,
ctx: *c.GMainContext,
/// True if the app was launched with single instance mode.
single_instance: bool,
/// The "none" cursor. We use one that is shared across the entire app.
cursor_none: ?*c.GdkCursor,
@ -269,6 +272,7 @@ pub fn init(core_app: *CoreApp, opts: Options) !App {
.ctx = ctx,
.cursor_none = cursor_none,
.x11_xkb = x11_xkb,
.single_instance = single_instance,
// If we are NOT the primary instance, then we never want to run.
// This means that another instance of the GTK app is running and
// our "activate" call above will open a window.
@ -388,17 +392,25 @@ pub fn run(self: *App) !void {
// If we are running, then we proceed to setup our app.
// Setup our cgroup configurations for our surfaces.
if (cgroup.init(self)) |cgroup_path| {
self.transient_cgroup_base = cgroup_path;
} else |err| {
// If we can't initialize cgroups then that's okay. We
// want to continue to run so we just won't isolate surfaces.
// NOTE(mitchellh): do we want a config to force it?
log.warn(
"failed to initialize cgroups, terminals will not be isolated err={}",
.{err},
);
}
if (switch (self.config.@"linux-cgroup") {
.never => false,
.always => true,
.@"single-instance" => self.single_instance,
}) cgroup: {
const path = cgroup.init(self) catch |err| {
// If we can't initialize cgroups then that's okay. We
// want to continue to run so we just won't isolate surfaces.
// NOTE(mitchellh): do we want a config to force it?
log.warn(
"failed to initialize cgroups, terminals will not be isolated err={}",
.{err},
);
break :cgroup;
};
log.info("cgroup isolation enabled base={s}", .{path});
self.transient_cgroup_base = path;
} else log.debug("cgroup isoation disabled config={}", .{self.config.@"linux-cgroup"});
// Setup our menu items
self.initActions();

View File

@ -12,7 +12,7 @@ pub const fish_completions = comptimeGenerateFishCompletions();
fn comptimeGenerateFishCompletions() []const u8 {
comptime {
@setEvalBranchQuota(13000);
@setEvalBranchQuota(15000);
var counter = std.io.countingWriter(std.io.null_writer);
try writeFishCompletions(&counter.writer());

View File

@ -988,6 +988,30 @@ keybind: Keybinds = .{},
/// This does not work with GLFW builds.
@"macos-option-as-alt": OptionAsAlt = .false,
/// Put every surface (tab, split, window) into a dedicated Linux cgroup.
///
/// This makes it so that resource management can be done on a per-surface
/// granularity. For example, if a shell program is using too much memory,
/// only that shell will be killed by the oom monitor instead of the entire
/// Ghostty process. Similarly, if a shell program is using too much CPU,
/// only that surface will be CPU-throttled.
///
/// This will cause startup times to be slower (a hundred milliseconds or so),
/// so the default value is "single-instance." In single-instance mode, only
/// one instance of Ghostty is running (see gtk-single-instance) so the startup
/// time is a one-time cost. Additionally, single instance Ghostty is much
/// more likely to have many windows, tabs, etc. so cgroup isolation is a
/// big benefit.
///
/// Valid values are:
///
/// * `never` - Never use cgroups.
/// * `always` - Always use cgroups.
/// * `single-instance` - Enable cgroups only for Ghostty instances launched
/// as single-instance applications (see gtk-single-instance).
///
@"linux-cgroup": LinuxCgroup = .@"single-instance",
/// If true, the Ghostty GTK application will run in single-instance mode:
/// each new `ghostty` process launched will result in a new window if there
/// is already a running process.
@ -3495,3 +3519,10 @@ pub const GraphemeWidthMethod = enum {
legacy,
unicode,
};
/// See linux-cgroup
pub const LinuxCgroup = enum {
never,
always,
@"single-instance",
};