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
|
* Initial release
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ override_dh_install:
|
|||||||
cp -r falcond-profiles/usr/share/falcond/profiles debian/falcond/usr/share/falcond/
|
cp -r falcond-profiles/usr/share/falcond/profiles debian/falcond/usr/share/falcond/
|
||||||
|
|
||||||
override_dh_installsystemd:
|
override_dh_installsystemd:
|
||||||
dh_installsystemd --name=falcond --restart-after-upgrade
|
dh_installsystemd --name=falcond --restart-after-upgrade --start
|
||||||
|
|
||||||
override_dh_clean:
|
override_dh_clean:
|
||||||
dh_clean
|
dh_clean
|
||||||
|
@ -7,7 +7,7 @@ const scx_scheds = @import("scx_scheds.zig");
|
|||||||
pub const Config = struct {
|
pub const Config = struct {
|
||||||
enable_performance_mode: bool = true,
|
enable_performance_mode: bool = true,
|
||||||
scx_sched: scx_scheds.ScxScheduler = .none,
|
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,
|
vcache_mode: vcache_setting.VCacheMode = .none,
|
||||||
|
|
||||||
pub fn load(allocator: std.mem.Allocator) !Config {
|
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("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 = {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)});
|
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| {
|
.pointer => |ptr_info| {
|
||||||
if (ptr_info.size != .Slice) return error.InvalidSyntax;
|
if (ptr_info.size != .Slice) return error.InvalidSyntax;
|
||||||
switch (ptr_info.child) {
|
switch (ptr_info.child) {
|
||||||
|
@ -101,24 +101,30 @@ pub const PowerProfiles = struct {
|
|||||||
return result.toOwnedSlice();
|
return result.toOwnedSlice();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enablePerformanceMode(self: *PowerProfiles) !void {
|
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 {
|
|
||||||
if (!self.has_performance) return;
|
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| {
|
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.allocator.free(profile);
|
||||||
self.original_profile = null;
|
self.original_profile = null;
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ pub const Profile = struct {
|
|||||||
name: []const u8,
|
name: []const u8,
|
||||||
performance_mode: bool = false,
|
performance_mode: bool = false,
|
||||||
scx_sched: scx_scheds.ScxScheduler = .none,
|
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,
|
vcache_mode: vcache_setting.VCacheMode = .cache,
|
||||||
|
|
||||||
pub fn matches(self: *const Profile, process_name: []const u8) bool {
|
pub fn matches(self: *const Profile, process_name: []const u8) bool {
|
||||||
@ -67,6 +67,7 @@ pub const ProfileManager = struct {
|
|||||||
"REDEngineErrorReporter.exe",
|
"REDEngineErrorReporter.exe",
|
||||||
"REDprelauncher.exe",
|
"REDprelauncher.exe",
|
||||||
"SteamService.exe",
|
"SteamService.exe",
|
||||||
|
"UnityCrashHandler64.exe",
|
||||||
"start.exe",
|
"start.exe",
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -88,25 +89,26 @@ pub const ProfileManager = struct {
|
|||||||
|
|
||||||
if (profile.performance_mode and self.power_profiles.isPerformanceAvailable()) {
|
if (profile.performance_mode and self.power_profiles.isPerformanceAvailable()) {
|
||||||
std.log.info("Enabling performance mode for profile: {s}", .{profile.name});
|
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)
|
const effective_mode = if (self.config.vcache_mode != .none)
|
||||||
self.config.vcache_mode
|
self.config.vcache_mode
|
||||||
else
|
else
|
||||||
profile.vcache_mode;
|
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)
|
const effective_sched = if (self.config.scx_sched != .none)
|
||||||
self.config.scx_sched
|
self.config.scx_sched
|
||||||
else
|
else
|
||||||
profile.scx_sched;
|
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
|
self.config.scx_sched_props
|
||||||
else
|
else
|
||||||
profile.scx_sched_props;
|
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 {
|
} else {
|
||||||
std.log.info("Queueing profile: {s} (active: {s})", .{ profile.name, self.active_profile.?.name });
|
std.log.info("Queueing profile: {s} (active: {s})", .{ profile.name, self.active_profile.?.name });
|
||||||
try self.queued_profiles.append(profile);
|
try self.queued_profiles.append(profile);
|
||||||
@ -120,12 +122,11 @@ pub const ProfileManager = struct {
|
|||||||
|
|
||||||
if (profile.performance_mode) {
|
if (profile.performance_mode) {
|
||||||
std.log.info("Disabling performance mode for profile: {s}", .{profile.name});
|
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);
|
vcache_setting.applyVCacheMode(.none);
|
||||||
try scx_scheds.restorePreviousState(self.allocator);
|
scx_scheds.restorePreviousState(self.allocator);
|
||||||
|
|
||||||
if (self.queued_profiles.items.len > 0) {
|
if (self.queued_profiles.items.len > 0) {
|
||||||
const next_profile = self.queued_profiles.orderedRemove(0);
|
const next_profile = self.queued_profiles.orderedRemove(0);
|
||||||
std.log.info("Activating next queued profile: {s}", .{next_profile.name});
|
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 {
|
pub fn deinit(self: *ProfileManager) void {
|
||||||
if (self.active_profile) |profile| {
|
if (self.active_profile) |profile| {
|
||||||
if (profile.performance_mode) {
|
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_simple")) return .simple;
|
||||||
if (std.mem.eql(u8, str, "scx_userland")) return .userland;
|
if (std.mem.eql(u8, str, "scx_userland")) return .userland;
|
||||||
if (std.mem.eql(u8, str, "scx_vder")) return .vder;
|
if (std.mem.eql(u8, str, "scx_vder")) return .vder;
|
||||||
|
|
||||||
return error.InvalidValue;
|
return error.InvalidValue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -61,13 +62,13 @@ pub const ScxSchedModes = enum {
|
|||||||
server,
|
server,
|
||||||
};
|
};
|
||||||
|
|
||||||
const PreviousState = struct {
|
const State = struct {
|
||||||
scheduler: ?ScxScheduler = null,
|
scheduler: ?ScxScheduler = null,
|
||||||
mode: ?ScxSchedModes = null,
|
mode: ?ScxSchedModes = null,
|
||||||
};
|
};
|
||||||
|
|
||||||
var previous_state: PreviousState = .{};
|
var previous_state = State{};
|
||||||
var supported_schedulers: []ScxScheduler = undefined;
|
var supported_schedulers: []ScxScheduler = &[_]ScxScheduler{};
|
||||||
var allocator: std.mem.Allocator = undefined;
|
var allocator: std.mem.Allocator = undefined;
|
||||||
|
|
||||||
pub fn init(alloc: std.mem.Allocator) !void {
|
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);
|
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);
|
defer alloc.free(mode_str);
|
||||||
|
|
||||||
const args = [_][]const u8{
|
const args = [_][]const u8{
|
||||||
@ -197,11 +207,33 @@ pub fn activateScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode
|
|||||||
try dbus_conn.callMethod("SwitchScheduler", &args);
|
try dbus_conn.callMethod("SwitchScheduler", &args);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn applyScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ScxSchedModes) ScxError!void {
|
pub fn applyScheduler(alloc: std.mem.Allocator, scheduler: ScxScheduler, mode: ?ScxSchedModes) void {
|
||||||
std.log.info("Applying scheduler {s} with mode {s}", .{ scheduler.toScxName(), @tagName(mode) });
|
storePreviousState(alloc) catch |err| {
|
||||||
|
std.log.err("Failed to store previous state: {}", .{err});
|
||||||
|
};
|
||||||
|
|
||||||
try storePreviousState(alloc);
|
if (scheduler == .none) {
|
||||||
try activateScheduler(alloc, scheduler, mode);
|
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 {
|
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{});
|
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 (previous_state.scheduler) |scheduler| {
|
||||||
if (scheduler == .none) {
|
if (previous_state.mode) |mode| {
|
||||||
std.log.info("Previous state was none, stopping scheduler", .{});
|
std.log.info("Restoring previous scheduler {s} with mode {s}", .{ scheduler.toScxName(), @tagName(mode) });
|
||||||
try deactivateScheduler(alloc);
|
activateScheduler(alloc, scheduler, mode) catch |err| {
|
||||||
} else {
|
std.log.err("Failed to restore previous scheduler: {}", .{err});
|
||||||
std.log.info("Restoring previous scheduler: {s}", .{scheduler.toScxName()});
|
};
|
||||||
try activateScheduler(alloc, scheduler, previous_state.mode orelse .default);
|
|
||||||
}
|
}
|
||||||
previous_state.scheduler = null;
|
previous_state.scheduler = null;
|
||||||
previous_state.mode = 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: ?[]const u8 = null;
|
||||||
var previous_mode_buffer: [10]u8 = undefined;
|
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) {
|
const file = fs.openFileAbsolute(vcache_path, .{ .mode = .read_write }) catch |err| switch (err) {
|
||||||
error.FileNotFound => return,
|
error.FileNotFound => return,
|
||||||
else => return err,
|
else => {
|
||||||
|
std.log.err("Failed to open vcache file: {}", .{err});
|
||||||
|
return;
|
||||||
|
},
|
||||||
};
|
};
|
||||||
defer file.close();
|
defer file.close();
|
||||||
|
|
||||||
if (vcache_mode == .none) {
|
if (vcache_mode == .none) {
|
||||||
if (previous_mode) |mode| {
|
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;
|
previous_mode = null;
|
||||||
}
|
}
|
||||||
return;
|
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) {
|
if (bytes_read > 0) {
|
||||||
previous_mode = previous_mode_buffer[0..bytes_read];
|
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",
|
.freq => "frequency",
|
||||||
.cache => "cache",
|
.cache => "cache",
|
||||||
.none => unreachable,
|
.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