Fix issues with blank scheduler options
Some checks failed
PikaOS Package Build & Release (amd64-v3) / build (push) Failing after 24s
Some checks failed
PikaOS Package Build & Release (amd64-v3) / build (push) Failing after 24s
This commit is contained in:
parent
5c5322a012
commit
5c33d2775e
2
.github/release-nest-v3
vendored
2
.github/release-nest-v3
vendored
@ -1 +1 @@
|
||||
3
|
||||
4
|
@ -1,4 +1,4 @@
|
||||
falcond (1.0.0-101pika2) pika; urgency=low
|
||||
falcond (1.0.0-101pika3) pika; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
|
@ -27,7 +27,7 @@ override_dh_install:
|
||||
cp -r falcond-profiles/usr/share/falcond/profiles debian/falcond/usr/share/falcond/
|
||||
|
||||
override_dh_installsystemd:
|
||||
dh_installsystemd --name=falcond --restart-after-upgrade
|
||||
dh_installsystemd --name=falcond --restart-after-upgrade --start
|
||||
|
||||
override_dh_clean:
|
||||
dh_clean
|
||||
|
@ -7,7 +7,7 @@ const scx_scheds = @import("scx_scheds.zig");
|
||||
pub const Config = struct {
|
||||
enable_performance_mode: bool = true,
|
||||
scx_sched: scx_scheds.ScxScheduler = .none,
|
||||
scx_sched_props: scx_scheds.ScxSchedModes = .gaming,
|
||||
scx_sched_props: ?scx_scheds.ScxSchedModes = null,
|
||||
vcache_mode: vcache_setting.VCacheMode = .none,
|
||||
|
||||
pub fn load(allocator: std.mem.Allocator) !Config {
|
||||
@ -46,7 +46,6 @@ pub const Config = struct {
|
||||
|
||||
try file.writer().print("enable_performance_mode = {}\n", .{self.enable_performance_mode});
|
||||
try file.writer().print("scx_sched = {s}\n", .{@tagName(self.scx_sched)});
|
||||
try file.writer().print("scx_sched_props = {s}\n", .{@tagName(self.scx_sched_props)});
|
||||
try file.writer().print("vcache_mode = {s}\n", .{@tagName(self.vcache_mode)});
|
||||
}
|
||||
};
|
||||
|
@ -236,6 +236,20 @@ pub fn Parser(comptime T: type) type {
|
||||
}
|
||||
}
|
||||
},
|
||||
.optional => |opt_info| {
|
||||
switch (@typeInfo(opt_info.child)) {
|
||||
.@"enum" => {
|
||||
const ident = try self.parseIdentifier();
|
||||
inline for (std.meta.fields(opt_info.child)) |enum_field| {
|
||||
if (std.mem.eql(u8, ident, enum_field.name)) {
|
||||
@field(result, field.name) = @field(opt_info.child, enum_field.name);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
else => return error.InvalidSyntax,
|
||||
}
|
||||
},
|
||||
.pointer => |ptr_info| {
|
||||
if (ptr_info.size != .Slice) return error.InvalidSyntax;
|
||||
switch (ptr_info.child) {
|
||||
|
@ -101,24 +101,30 @@ pub const PowerProfiles = struct {
|
||||
return result.toOwnedSlice();
|
||||
}
|
||||
|
||||
pub fn enablePerformanceMode(self: *PowerProfiles) !void {
|
||||
if (!self.has_performance) {
|
||||
std.log.warn("Performance mode not available", .{});
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.original_profile == null) {
|
||||
self.original_profile = try self.dbus.getProperty("ActiveProfile");
|
||||
}
|
||||
|
||||
try self.dbus.setProperty("ActiveProfile", "performance");
|
||||
}
|
||||
|
||||
pub fn disablePerformanceMode(self: *PowerProfiles) !void {
|
||||
pub fn enablePerformanceMode(self: *PowerProfiles) void {
|
||||
if (!self.has_performance) return;
|
||||
|
||||
if (self.dbus.getProperty("ActiveProfile")) |profile| {
|
||||
defer self.allocator.free(profile);
|
||||
if (!std.mem.eql(u8, profile, "performance")) {
|
||||
self.original_profile = self.allocator.dupe(u8, profile) catch |err| {
|
||||
std.log.err("Failed to store original power profile: {}", .{err});
|
||||
return;
|
||||
};
|
||||
self.dbus.setProperty("ActiveProfile", "performance") catch |err| {
|
||||
std.log.err("Failed to set performance mode: {}", .{err});
|
||||
};
|
||||
}
|
||||
} else |err| {
|
||||
std.log.err("Failed to get active power profile: {}", .{err});
|
||||
}
|
||||
}
|
||||
|
||||
pub fn disablePerformanceMode(self: *PowerProfiles) void {
|
||||
if (self.original_profile) |profile| {
|
||||
try self.dbus.setProperty("ActiveProfile", profile);
|
||||
self.dbus.setProperty("ActiveProfile", profile) catch |err| {
|
||||
std.log.err("Failed to restore power profile: {}", .{err});
|
||||
};
|
||||
self.allocator.free(profile);
|
||||
self.original_profile = null;
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ pub const Profile = struct {
|
||||
name: []const u8,
|
||||
performance_mode: bool = false,
|
||||
scx_sched: scx_scheds.ScxScheduler = .none,
|
||||
scx_sched_props: scx_scheds.ScxSchedModes = .gaming,
|
||||
scx_sched_props: ?scx_scheds.ScxSchedModes = null,
|
||||
vcache_mode: vcache_setting.VCacheMode = .cache,
|
||||
|
||||
pub fn matches(self: *const Profile, process_name: []const u8) bool {
|
||||
@ -67,6 +67,7 @@ pub const ProfileManager = struct {
|
||||
"REDEngineErrorReporter.exe",
|
||||
"REDprelauncher.exe",
|
||||
"SteamService.exe",
|
||||
"UnityCrashHandler64.exe",
|
||||
"start.exe",
|
||||
};
|
||||
|
||||
@ -88,25 +89,26 @@ pub const ProfileManager = struct {
|
||||
|
||||
if (profile.performance_mode and self.power_profiles.isPerformanceAvailable()) {
|
||||
std.log.info("Enabling performance mode for profile: {s}", .{profile.name});
|
||||
try self.power_profiles.enablePerformanceMode();
|
||||
self.power_profiles.enablePerformanceMode();
|
||||
}
|
||||
|
||||
const effective_mode = if (self.config.vcache_mode != .none)
|
||||
self.config.vcache_mode
|
||||
else
|
||||
profile.vcache_mode;
|
||||
try vcache_setting.applyVCacheMode(effective_mode);
|
||||
vcache_setting.applyVCacheMode(effective_mode);
|
||||
|
||||
// Apply scheduler settings, using global config override if set
|
||||
const effective_sched = if (self.config.scx_sched != .none)
|
||||
self.config.scx_sched
|
||||
else
|
||||
profile.scx_sched;
|
||||
const effective_sched_mode = if (self.config.scx_sched != .none)
|
||||
|
||||
const effective_scx_mode = if (self.config.scx_sched != .none)
|
||||
self.config.scx_sched_props
|
||||
else
|
||||
profile.scx_sched_props;
|
||||
try scx_scheds.applyScheduler(self.allocator, effective_sched, effective_sched_mode);
|
||||
|
||||
scx_scheds.applyScheduler(self.allocator, effective_sched, effective_scx_mode);
|
||||
} else {
|
||||
std.log.info("Queueing profile: {s} (active: {s})", .{ profile.name, self.active_profile.?.name });
|
||||
try self.queued_profiles.append(profile);
|
||||
@ -120,12 +122,11 @@ pub const ProfileManager = struct {
|
||||
|
||||
if (profile.performance_mode) {
|
||||
std.log.info("Disabling performance mode for profile: {s}", .{profile.name});
|
||||
try self.power_profiles.disablePerformanceMode();
|
||||
self.power_profiles.disablePerformanceMode();
|
||||
}
|
||||
|
||||
try vcache_setting.applyVCacheMode(.none);
|
||||
try scx_scheds.restorePreviousState(self.allocator);
|
||||
|
||||
vcache_setting.applyVCacheMode(.none);
|
||||
scx_scheds.restorePreviousState(self.allocator);
|
||||
if (self.queued_profiles.items.len > 0) {
|
||||
const next_profile = self.queued_profiles.orderedRemove(0);
|
||||
std.log.info("Activating next queued profile: {s}", .{next_profile.name});
|
||||
@ -256,7 +257,7 @@ pub const ProfileManager = struct {
|
||||
pub fn deinit(self: *ProfileManager) void {
|
||||
if (self.active_profile) |profile| {
|
||||
if (profile.performance_mode) {
|
||||
self.power_profiles.disablePerformanceMode() catch {};
|
||||
self.power_profiles.disablePerformanceMode();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ pub const ScxScheduler = enum {
|
||||
if (std.mem.eql(u8, str, "scx_simple")) return .simple;
|
||||
if (std.mem.eql(u8, str, "scx_userland")) return .userland;
|
||||
if (std.mem.eql(u8, str, "scx_vder")) return .vder;
|
||||
|
||||
return error.InvalidValue;
|
||||
}
|
||||
};
|
||||
@ -61,13 +62,13 @@ pub const ScxSchedModes = enum {
|
||||
server,
|
||||
};
|
||||
|
||||
const PreviousState = struct {
|
||||
const State = struct {
|
||||
scheduler: ?ScxScheduler = null,
|
||||
mode: ?ScxSchedModes = null,
|
||||
};
|
||||
|
||||
var previous_state: PreviousState = .{};
|
||||
var supported_schedulers: []ScxScheduler = undefined;
|
||||
var previous_state = State{};
|
||||
var supported_schedulers: []ScxScheduler = &[_]ScxScheduler{};
|
||||
var allocator: std.mem.Allocator = undefined;
|
||||
|
||||
pub fn init(alloc: std.mem.Allocator) !void {
|
||||
@ -182,10 +183,19 @@ pub fn storePreviousState(alloc: std.mem.Allocator) !void {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn activateScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ScxSchedModes) ScxError!void {
|
||||
fn isSchedulerSupported(scheduler: ScxScheduler) bool {
|
||||
if (scheduler == .none) return true;
|
||||
|
||||
for (supported_schedulers) |s| {
|
||||
if (s == scheduler) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
pub fn activateScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ?ScxSchedModes) ScxError!void {
|
||||
var dbus_conn = dbus.DBus.init(alloc, SCX_NAME, SCX_PATH, SCX_IFACE);
|
||||
|
||||
const mode_str = try std.fmt.allocPrint(alloc, "{d}", .{modeToInt(mode)});
|
||||
const mode_str = try std.fmt.allocPrint(alloc, "{d}", .{modeToInt(mode orelse .default)});
|
||||
defer alloc.free(mode_str);
|
||||
|
||||
const args = [_][]const u8{
|
||||
@ -197,11 +207,33 @@ pub fn activateScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode
|
||||
try dbus_conn.callMethod("SwitchScheduler", &args);
|
||||
}
|
||||
|
||||
pub fn applyScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ScxSchedModes) ScxError!void {
|
||||
std.log.info("Applying scheduler {s} with mode {s}", .{ scheduler.toScxName(), @tagName(mode) });
|
||||
pub fn applyScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ?ScxSchedModes) void {
|
||||
storePreviousState(alloc) catch |err| {
|
||||
std.log.err("Failed to store previous state: {}", .{err});
|
||||
};
|
||||
|
||||
try storePreviousState(alloc);
|
||||
try activateScheduler(alloc, scheduler, mode);
|
||||
if (scheduler == .none) {
|
||||
std.log.info("No scheduler to apply for this profile", .{});
|
||||
deactivateScheduler(alloc) catch |err| {
|
||||
std.log.err("Failed to deactivate scheduler: {}", .{err});
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isSchedulerSupported(scheduler)) {
|
||||
std.log.info("Scheduler {s} not supported by system", .{scheduler.toScxName()});
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode) |m| {
|
||||
std.log.info("Applying scheduler {s} with mode {s}", .{ scheduler.toScxName(), @tagName(m) });
|
||||
} else {
|
||||
std.log.info("Applying scheduler {s} with default mode", .{scheduler.toScxName()});
|
||||
}
|
||||
|
||||
activateScheduler(alloc, scheduler, mode orelse .default) catch |err| {
|
||||
std.log.err("Failed to activate scheduler {s}: {}", .{ scheduler.toScxName(), err });
|
||||
};
|
||||
}
|
||||
|
||||
pub fn deactivateScheduler(alloc: std.mem.Allocator) ScxError!void {
|
||||
@ -209,16 +241,20 @@ pub fn deactivateScheduler(alloc: std.mem.Allocator) ScxError!void {
|
||||
try dbus_conn.callMethod("StopScheduler", &[_][]const u8{});
|
||||
}
|
||||
|
||||
pub fn restorePreviousState(alloc: std.mem.Allocator) ScxError!void {
|
||||
pub fn restorePreviousState(alloc: std.mem.Allocator) void {
|
||||
if (previous_state.scheduler) |scheduler| {
|
||||
if (scheduler == .none) {
|
||||
std.log.info("Previous state was none, stopping scheduler", .{});
|
||||
try deactivateScheduler(alloc);
|
||||
} else {
|
||||
std.log.info("Restoring previous scheduler: {s}", .{scheduler.toScxName()});
|
||||
try activateScheduler(alloc, scheduler, previous_state.mode orelse .default);
|
||||
if (previous_state.mode) |mode| {
|
||||
std.log.info("Restoring previous scheduler {s} with mode {s}", .{ scheduler.toScxName(), @tagName(mode) });
|
||||
activateScheduler(alloc, scheduler, mode) catch |err| {
|
||||
std.log.err("Failed to restore previous scheduler: {}", .{err});
|
||||
};
|
||||
}
|
||||
previous_state.scheduler = null;
|
||||
previous_state.mode = null;
|
||||
} else {
|
||||
std.log.info("Previous state was none, stopping scheduler", .{});
|
||||
deactivateScheduler(alloc) catch |err| {
|
||||
std.log.err("Failed to stop scheduler: {}", .{err});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -12,31 +12,45 @@ const vcache_path = "/sys/bus/platform/drivers/amd_x3d_vcache/AMDI0101:00/amd_x3
|
||||
var previous_mode: ?[]const u8 = null;
|
||||
var previous_mode_buffer: [10]u8 = undefined;
|
||||
|
||||
pub fn applyVCacheMode(vcache_mode: VCacheMode) !void {
|
||||
pub fn applyVCacheMode(vcache_mode: VCacheMode) void {
|
||||
const file = fs.openFileAbsolute(vcache_path, .{ .mode = .read_write }) catch |err| switch (err) {
|
||||
error.FileNotFound => return,
|
||||
else => return err,
|
||||
else => {
|
||||
std.log.err("Failed to open vcache file: {}", .{err});
|
||||
return;
|
||||
},
|
||||
};
|
||||
defer file.close();
|
||||
|
||||
if (vcache_mode == .none) {
|
||||
if (previous_mode) |mode| {
|
||||
try file.writeAll(mode);
|
||||
file.writeAll(mode) catch |err| {
|
||||
std.log.err("Failed to restore previous vcache mode: {}", .{err});
|
||||
};
|
||||
previous_mode = null;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const bytes_read = try file.readAll(previous_mode_buffer[0..]);
|
||||
const bytes_read = file.readAll(previous_mode_buffer[0..]) catch |err| {
|
||||
std.log.err("Failed to read current vcache mode: {}", .{err});
|
||||
return;
|
||||
};
|
||||
if (bytes_read > 0) {
|
||||
previous_mode = previous_mode_buffer[0..bytes_read];
|
||||
}
|
||||
|
||||
try file.seekTo(0);
|
||||
file.seekTo(0) catch |err| {
|
||||
std.log.err("Failed to seek vcache file: {}", .{err});
|
||||
return;
|
||||
};
|
||||
|
||||
try file.writeAll(switch (vcache_mode) {
|
||||
const mode_str = switch (vcache_mode) {
|
||||
.freq => "frequency",
|
||||
.cache => "cache",
|
||||
.none => unreachable,
|
||||
});
|
||||
};
|
||||
file.writeAll(mode_str) catch |err| {
|
||||
std.log.err("Failed to write vcache mode: {}", .{err});
|
||||
};
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user