mirror of
https://github.com/RGBCube/superfreq
synced 2025-07-27 17:07:44 +00:00
core: init daemon mode for persistent operations
This commit is contained in:
parent
e6e46e18a8
commit
48bf7508aa
6 changed files with 259 additions and 24 deletions
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -64,6 +64,12 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cfg_aliases"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.38"
|
version = "4.5.38"
|
||||||
|
@ -110,6 +116,25 @@ version = "1.0.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ctrlc"
|
||||||
|
version = "3.4.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "46f93780a459b7d656ef7f071fe699c4d3d2cb201c4b24d085b6ddc505276e73"
|
||||||
|
dependencies = [
|
||||||
|
"nix",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "daemonize"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ab8bfdaacb3c887a54d41bdf48d3af8873b3f5566469f8ba21b92057509f116e"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "6.0.0"
|
version = "6.0.0"
|
||||||
|
@ -204,6 +229,18 @@ version = "2.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.30.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags",
|
||||||
|
"cfg-if",
|
||||||
|
"cfg_aliases",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -295,6 +332,8 @@ name = "superfreq"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"ctrlc",
|
||||||
|
"daemonize",
|
||||||
"dirs",
|
"dirs",
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
|
@ -9,3 +9,4 @@ toml = "0.8"
|
||||||
dirs = "6.0"
|
dirs = "6.0"
|
||||||
clap = { version = "4.0", features = ["derive"] }
|
clap = { version = "4.0", features = ["derive"] }
|
||||||
num_cpus = "1.16"
|
num_cpus = "1.16"
|
||||||
|
ctrlc = "3.4"
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
use serde::Deserialize;
|
|
||||||
use std::path::{Path, PathBuf};
|
|
||||||
use std::fs;
|
|
||||||
use crate::core::{OperationalMode, TurboSetting};
|
use crate::core::{OperationalMode, TurboSetting};
|
||||||
|
use serde::Deserialize;
|
||||||
|
use std::fs;
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
// Structs for configuration using serde::Deserialize
|
// Structs for configuration using serde::Deserialize
|
||||||
#[derive(Deserialize, Debug, Clone)]
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
pub struct ProfileConfig {
|
pub struct ProfileConfig {
|
||||||
pub governor: Option<String>,
|
pub governor: Option<String>,
|
||||||
pub turbo: Option<TurboSetting>,
|
pub turbo: Option<TurboSetting>,
|
||||||
pub epp: Option<String>, // Energy Performance Preference (EPP)
|
pub epp: Option<String>, // Energy Performance Preference (EPP)
|
||||||
pub epb: Option<String>, // Energy Performance Bias (EPB) - usually an integer, but string for flexibility from sysfs
|
pub epb: Option<String>, // Energy Performance Bias (EPB) - usually an integer, but string for flexibility from sysfs
|
||||||
pub min_freq_mhz: Option<u32>,
|
pub min_freq_mhz: Option<u32>,
|
||||||
pub max_freq_mhz: Option<u32>,
|
pub max_freq_mhz: Option<u32>,
|
||||||
pub platform_profile: Option<String>,
|
pub platform_profile: Option<String>,
|
||||||
|
pub turbo_auto_settings: Option<TurboAutoSettings>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for ProfileConfig {
|
impl Default for ProfileConfig {
|
||||||
|
@ -20,11 +21,12 @@ impl Default for ProfileConfig {
|
||||||
ProfileConfig {
|
ProfileConfig {
|
||||||
governor: Some("schedutil".to_string()), // common sensible default (?)
|
governor: Some("schedutil".to_string()), // common sensible default (?)
|
||||||
turbo: Some(TurboSetting::Auto),
|
turbo: Some(TurboSetting::Auto),
|
||||||
epp: None, // defaults depend on governor and system
|
epp: None, // defaults depend on governor and system
|
||||||
epb: None, // defaults depend on governor and system
|
epb: None, // defaults depend on governor and system
|
||||||
min_freq_mhz: None, // no override
|
min_freq_mhz: None, // no override
|
||||||
max_freq_mhz: None, // no override
|
max_freq_mhz: None, // no override
|
||||||
platform_profile: None, // no override
|
platform_profile: None, // no override
|
||||||
|
turbo_auto_settings: Some(TurboAutoSettings::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -90,7 +92,9 @@ pub fn load_config() -> Result<AppConfig, ConfigError> {
|
||||||
let user_config_path = home_dir.join(".config/auto_cpufreq_rs/config.toml");
|
let user_config_path = home_dir.join(".config/auto_cpufreq_rs/config.toml");
|
||||||
config_paths.push(user_config_path);
|
config_paths.push(user_config_path);
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Warning: Could not determine home directory. User-specific config will not be loaded.");
|
eprintln!(
|
||||||
|
"Warning: Could not determine home directory. User-specific config will not be loaded."
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// System-wide path
|
// System-wide path
|
||||||
|
@ -108,7 +112,8 @@ pub fn load_config() -> Result<AppConfig, ConfigError> {
|
||||||
let app_config = AppConfig {
|
let app_config = AppConfig {
|
||||||
charger: ProfileConfig::from(toml_app_config.charger),
|
charger: ProfileConfig::from(toml_app_config.charger),
|
||||||
battery: ProfileConfig::from(toml_app_config.battery),
|
battery: ProfileConfig::from(toml_app_config.battery),
|
||||||
battery_charge_thresholds: toml_app_config.battery_charge_thresholds,
|
battery_charge_thresholds: toml_app_config
|
||||||
|
.battery_charge_thresholds,
|
||||||
ignored_power_supplies: toml_app_config.ignored_power_supplies,
|
ignored_power_supplies: toml_app_config.ignored_power_supplies,
|
||||||
poll_interval_sec: toml_app_config.poll_interval_sec,
|
poll_interval_sec: toml_app_config.poll_interval_sec,
|
||||||
};
|
};
|
||||||
|
@ -176,22 +181,59 @@ impl Default for ProfileConfigToml {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone)]
|
||||||
|
pub struct TurboAutoSettings {
|
||||||
|
#[serde(default = "default_load_threshold_high")]
|
||||||
|
pub load_threshold_high: f32,
|
||||||
|
#[serde(default = "default_load_threshold_low")]
|
||||||
|
pub load_threshold_low: f32,
|
||||||
|
#[serde(default = "default_temp_threshold_high")]
|
||||||
|
pub temp_threshold_high: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default thresholds for Auto turbo mode
|
||||||
|
pub const DEFAULT_LOAD_THRESHOLD_HIGH: f32 = 70.0; // Enable turbo if load is above this
|
||||||
|
pub const DEFAULT_LOAD_THRESHOLD_LOW: f32 = 30.0; // Disable turbo if load is below this
|
||||||
|
pub const DEFAULT_TEMP_THRESHOLD_HIGH: f32 = 75.0; // Disable turbo if temperature is above this
|
||||||
|
|
||||||
|
fn default_load_threshold_high() -> f32 {
|
||||||
|
DEFAULT_LOAD_THRESHOLD_HIGH
|
||||||
|
}
|
||||||
|
fn default_load_threshold_low() -> f32 {
|
||||||
|
DEFAULT_LOAD_THRESHOLD_LOW
|
||||||
|
}
|
||||||
|
fn default_temp_threshold_high() -> f32 {
|
||||||
|
DEFAULT_TEMP_THRESHOLD_HIGH
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for TurboAutoSettings {
|
||||||
|
fn default() -> Self {
|
||||||
|
TurboAutoSettings {
|
||||||
|
load_threshold_high: DEFAULT_LOAD_THRESHOLD_HIGH,
|
||||||
|
load_threshold_low: DEFAULT_LOAD_THRESHOLD_LOW,
|
||||||
|
temp_threshold_high: DEFAULT_TEMP_THRESHOLD_HIGH,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<ProfileConfigToml> for ProfileConfig {
|
impl From<ProfileConfigToml> for ProfileConfig {
|
||||||
fn from(toml_config: ProfileConfigToml) -> Self {
|
fn from(toml_config: ProfileConfigToml) -> Self {
|
||||||
ProfileConfig {
|
ProfileConfig {
|
||||||
governor: toml_config.governor,
|
governor: toml_config.governor,
|
||||||
turbo: toml_config.turbo.and_then(|s| match s.to_lowercase().as_str() {
|
turbo: toml_config
|
||||||
"always" => Some(TurboSetting::Always),
|
.turbo
|
||||||
"auto" => Some(TurboSetting::Auto),
|
.and_then(|s| match s.to_lowercase().as_str() {
|
||||||
"never" => Some(TurboSetting::Never),
|
"always" => Some(TurboSetting::Always),
|
||||||
_ => None,
|
"auto" => Some(TurboSetting::Auto),
|
||||||
}),
|
"never" => Some(TurboSetting::Never),
|
||||||
|
_ => None,
|
||||||
|
}),
|
||||||
epp: toml_config.epp,
|
epp: toml_config.epp,
|
||||||
epb: toml_config.epb,
|
epb: toml_config.epb,
|
||||||
min_freq_mhz: toml_config.min_freq_mhz,
|
min_freq_mhz: toml_config.min_freq_mhz,
|
||||||
max_freq_mhz: toml_config.max_freq_mhz,
|
max_freq_mhz: toml_config.max_freq_mhz,
|
||||||
platform_profile: toml_config.platform_profile,
|
platform_profile: toml_config.platform_profile,
|
||||||
|
turbo_auto_settings: Some(TurboAutoSettings::default()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
61
src/daemon.rs
Normal file
61
src/daemon.rs
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
use crate::config::AppConfig;
|
||||||
|
use crate::engine;
|
||||||
|
use crate::monitor;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
use std::time::{Duration, Instant};
|
||||||
|
|
||||||
|
/// Run the daemon in foreground mode
|
||||||
|
pub fn run_background(config: AppConfig) -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
println!("Starting superfreq daemon in foreground mode...");
|
||||||
|
|
||||||
|
// Create a flag that will be set to true when a signal is received
|
||||||
|
let running = Arc::new(AtomicBool::new(true));
|
||||||
|
let r = running.clone();
|
||||||
|
|
||||||
|
// Set up signal handlers
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
println!("Received shutdown signal, exiting...");
|
||||||
|
r.store(false, Ordering::SeqCst);
|
||||||
|
})
|
||||||
|
.expect("Error setting Ctrl-C handler");
|
||||||
|
|
||||||
|
println!(
|
||||||
|
"Daemon initialized with poll interval: {}s",
|
||||||
|
config.poll_interval_sec
|
||||||
|
);
|
||||||
|
|
||||||
|
// Main loop
|
||||||
|
while running.load(Ordering::SeqCst) {
|
||||||
|
let start_time = Instant::now();
|
||||||
|
|
||||||
|
match monitor::collect_system_report(&config) {
|
||||||
|
Ok(report) => {
|
||||||
|
println!("Collected system report, applying settings...");
|
||||||
|
match engine::determine_and_apply_settings(&report, &config, None) {
|
||||||
|
Ok(()) => {
|
||||||
|
println!("Successfully applied system settings");
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error applying system settings: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
eprintln!("Error collecting system report: {}", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sleep for the remaining time in the poll interval
|
||||||
|
let elapsed = start_time.elapsed();
|
||||||
|
let poll_duration = Duration::from_secs(config.poll_interval_sec);
|
||||||
|
if elapsed < poll_duration {
|
||||||
|
let sleep_time = poll_duration - elapsed;
|
||||||
|
println!("Sleeping for {}s until next cycle", sleep_time.as_secs());
|
||||||
|
std::thread::sleep(sleep_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
println!("Daemon stopped");
|
||||||
|
Ok(())
|
||||||
|
}
|
100
src/engine.rs
100
src/engine.rs
|
@ -1,5 +1,5 @@
|
||||||
use crate::core::{SystemReport, OperationalMode, TurboSetting};
|
use crate::config::{AppConfig, ProfileConfig, TurboAutoSettings};
|
||||||
use crate::config::{AppConfig, ProfileConfig};
|
use crate::core::{OperationalMode, SystemReport, TurboSetting};
|
||||||
use crate::cpu::{self, ControlError};
|
use crate::cpu::{self, ControlError};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -57,8 +57,8 @@ pub fn determine_and_apply_settings(
|
||||||
// If no batteries, assume AC power (desktop).
|
// If no batteries, assume AC power (desktop).
|
||||||
// Otherwise, check the ac_connected status from the (first) battery.
|
// Otherwise, check the ac_connected status from the (first) battery.
|
||||||
// XXX: This relies on the setting ac_connected in BatteryInfo being set correctly.
|
// XXX: This relies on the setting ac_connected in BatteryInfo being set correctly.
|
||||||
let on_ac_power = report.batteries.is_empty() ||
|
let on_ac_power = report.batteries.is_empty()
|
||||||
report.batteries.first().map_or(false, |b| b.ac_connected);
|
|| report.batteries.first().map_or(false, |b| b.ac_connected);
|
||||||
|
|
||||||
if on_ac_power {
|
if on_ac_power {
|
||||||
println!("Engine: On AC power, selecting Charger profile.");
|
println!("Engine: On AC power, selecting Charger profile.");
|
||||||
|
@ -80,7 +80,13 @@ pub fn determine_and_apply_settings(
|
||||||
|
|
||||||
if let Some(turbo_setting) = selected_profile_config.turbo {
|
if let Some(turbo_setting) = selected_profile_config.turbo {
|
||||||
println!("Engine: Setting turbo to '{:?}'", turbo_setting);
|
println!("Engine: Setting turbo to '{:?}'", turbo_setting);
|
||||||
cpu::set_turbo(turbo_setting)?;
|
match turbo_setting {
|
||||||
|
TurboSetting::Auto => {
|
||||||
|
println!("Engine: Managing turbo in auto mode based on system conditions");
|
||||||
|
manage_auto_turbo(report, selected_profile_config)?;
|
||||||
|
}
|
||||||
|
_ => cpu::set_turbo(turbo_setting)?,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(epp) = &selected_profile_config.epp {
|
if let Some(epp) = &selected_profile_config.epp {
|
||||||
|
@ -89,7 +95,7 @@ pub fn determine_and_apply_settings(
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(epb) = &selected_profile_config.epb {
|
if let Some(epb) = &selected_profile_config.epb {
|
||||||
println!("Engine: Setting EPB to '{}'", epb);
|
println!("Engine: Setting EPB to '{}'", epb);
|
||||||
cpu::set_epb(epb, None)?;
|
cpu::set_epb(epb, None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,3 +118,85 @@ pub fn determine_and_apply_settings(
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn manage_auto_turbo(report: &SystemReport, config: &ProfileConfig) -> Result<(), EngineError> {
|
||||||
|
// Get the auto turbo settings from the config, or use defaults
|
||||||
|
let turbo_settings = config.turbo_auto_settings.clone().unwrap_or_default();
|
||||||
|
|
||||||
|
// Get average CPU temperature and CPU load
|
||||||
|
let cpu_temp = report.cpu_global.average_temperature_celsius;
|
||||||
|
|
||||||
|
// Check if we have CPU usage data available
|
||||||
|
let avg_cpu_usage = if !report.cpu_cores.is_empty() {
|
||||||
|
let sum: f32 = report
|
||||||
|
.cpu_cores
|
||||||
|
.iter()
|
||||||
|
.filter_map(|core| core.usage_percent)
|
||||||
|
.sum();
|
||||||
|
let count = report
|
||||||
|
.cpu_cores
|
||||||
|
.iter()
|
||||||
|
.filter(|core| core.usage_percent.is_some())
|
||||||
|
.count();
|
||||||
|
|
||||||
|
if count > 0 {
|
||||||
|
Some(sum / count as f32)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
// Decision logic for enabling/disabling turbo
|
||||||
|
let enable_turbo = match (cpu_temp, avg_cpu_usage) {
|
||||||
|
// If temperature is too high, disable turbo regardless of load
|
||||||
|
(Some(temp), _) if temp >= turbo_settings.temp_threshold_high => {
|
||||||
|
println!(
|
||||||
|
"Engine: Auto Turbo: Disabled due to high temperature ({:.1}°C >= {:.1}°C)",
|
||||||
|
temp, turbo_settings.temp_threshold_high
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
// If load is high enough, enable turbo (unless temp already caused it to disable)
|
||||||
|
(_, Some(usage)) if usage >= turbo_settings.load_threshold_high => {
|
||||||
|
println!(
|
||||||
|
"Engine: Auto Turbo: Enabled due to high CPU load ({:.1}% >= {:.1}%)",
|
||||||
|
usage, turbo_settings.load_threshold_high
|
||||||
|
);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
// If load is low, disable turbo
|
||||||
|
(_, Some(usage)) if usage <= turbo_settings.load_threshold_low => {
|
||||||
|
println!(
|
||||||
|
"Engine: Auto Turbo: Disabled due to low CPU load ({:.1}% <= {:.1}%)",
|
||||||
|
usage, turbo_settings.load_threshold_low
|
||||||
|
);
|
||||||
|
false
|
||||||
|
}
|
||||||
|
// In intermediate load scenarios or if we can't determine, leave turbo in current state
|
||||||
|
// For now, we'll disable it as a safe default
|
||||||
|
_ => {
|
||||||
|
println!("Engine: Auto Turbo: Disabled (default for indeterminate state)");
|
||||||
|
false
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Apply the turbo setting
|
||||||
|
let turbo_setting = if enable_turbo {
|
||||||
|
TurboSetting::Always
|
||||||
|
} else {
|
||||||
|
TurboSetting::Never
|
||||||
|
};
|
||||||
|
|
||||||
|
match cpu::set_turbo(turbo_setting) {
|
||||||
|
Ok(_) => {
|
||||||
|
println!(
|
||||||
|
"Engine: Auto Turbo: Successfully set turbo to {}",
|
||||||
|
if enable_turbo { "enabled" } else { "disabled" }
|
||||||
|
);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
Err(e) => Err(EngineError::ControlError(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
mod config;
|
mod config;
|
||||||
mod core;
|
mod core;
|
||||||
mod cpu;
|
mod cpu;
|
||||||
|
mod daemon;
|
||||||
mod engine;
|
mod engine;
|
||||||
mod monitor;
|
mod monitor;
|
||||||
|
|
||||||
|
@ -19,6 +20,8 @@ struct Cli {
|
||||||
enum Commands {
|
enum Commands {
|
||||||
/// Display current system information
|
/// Display current system information
|
||||||
Info,
|
Info,
|
||||||
|
/// Run as a daemon in the background
|
||||||
|
Daemon,
|
||||||
/// Set CPU governor
|
/// Set CPU governor
|
||||||
SetGovernor {
|
SetGovernor {
|
||||||
governor: String,
|
governor: String,
|
||||||
|
@ -183,6 +186,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
Some(Commands::SetPlatformProfile { profile }) => cpu::set_platform_profile(&profile)
|
Some(Commands::SetPlatformProfile { profile }) => cpu::set_platform_profile(&profile)
|
||||||
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>),
|
.map_err(|e| Box::new(e) as Box<dyn std::error::Error>),
|
||||||
|
Some(Commands::Daemon) => daemon::run_background(config),
|
||||||
None => {
|
None => {
|
||||||
println!("Welcome to superfreq! Use --help for commands.");
|
println!("Welcome to superfreq! Use --help for commands.");
|
||||||
println!("Current effective configuration: {:?}", config);
|
println!("Current effective configuration: {:?}", config);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue