From ea988279a87568689e6cd797e91ef3aa64c54700 Mon Sep 17 00:00:00 2001 From: "Luke D. Jones" Date: Sat, 18 May 2024 12:59:17 +1200 Subject: [PATCH] Fix GUI taking 100% of CPU core Closes #480 --- CHANGELOG.md | 4 + rog-control-center/Cargo.toml | 7 +- rog-control-center/src/main.rs | 1 + rog-control-center/src/notify.rs | 196 ++++++++++-------- rog-control-center/src/ui/setup_aura.rs | 6 +- .../translations/en/rog-control-center.po | 2 +- 6 files changed, 121 insertions(+), 95 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65d082b1..94d203c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Rename and recreate the default Anime config if cache setup fails +### Fixed + +- Nuke the issue of GUI taking 100% of a CPU core + ## [v6.0.8] ### Added diff --git a/rog-control-center/Cargo.toml b/rog-control-center/Cargo.toml index 2a1302ac..8142ad04 100644 --- a/rog-control-center/Cargo.toml +++ b/rog-control-center/Cargo.toml @@ -12,12 +12,11 @@ edition.workspace = true default = [] mocking = [] x11 = ["slint/backend-winit-x11"] - -[build] -rustflags = ["--cfg", "tokio_unstable"] +# Requires RUSTFLAGS="--cfg tokio_unstable" +tokio-debug = ["console-subscriber"] [dependencies] -console-subscriber = "0.2.0" +console-subscriber = { version = "0.2.0", optional = true } nix = { version = "^0.28.0", features = ["fs"] } tempfile = "3.3.0" diff --git a/rog-control-center/src/main.rs b/rog-control-center/src/main.rs index 9665a088..357bb1c3 100644 --- a/rog-control-center/src/main.rs +++ b/rog-control-center/src/main.rs @@ -25,6 +25,7 @@ use tokio::runtime::Runtime; #[tokio::main] async fn main() -> Result<()> { + #[cfg(feature = "tokio-debug")] console_subscriber::init(); let self_version = env!("CARGO_PKG_VERSION"); diff --git a/rog-control-center/src/notify.rs b/rog-control-center/src/notify.rs index addfd18c..f194b459 100644 --- a/rog-control-center/src/notify.rs +++ b/rog-control-center/src/notify.rs @@ -45,6 +45,44 @@ impl Default for EnabledNotifications { } } +fn start_dpu_status_mon(config: Arc>) { + use supergfxctl::pci_device::Device; + let dev = Device::find().unwrap_or_default(); + let mut found_dgpu = false; // just for logging + for dev in dev { + if dev.is_dgpu() { + let enabled_notifications_copy = config.clone(); + // Plain old thread is perfectly fine since most of this is potentially blocking + std::thread::spawn(move || { + let mut last_status = GfxPower::Unknown; + loop { + std::thread::sleep(Duration::from_millis(1000)); + if let Ok(status) = dev.get_runtime_status() { + if status != GfxPower::Unknown && status != last_status { + if let Ok(config) = enabled_notifications_copy.lock() { + if !config.notifications.receive_notify_gfx_status + || !config.notifications.enabled + { + continue; + } + } + // Required check because status cycles through + // active/unknown/suspended + do_gpu_status_notif("dGPU status changed:", &status).ok(); + } + last_status = status; + } + } + }); + found_dgpu = true; + break; + } + } + if !found_dgpu { + warn!("Did not find a dGPU on this system, dGPU status won't be avilable"); + } +} + pub fn start_notifications( config: Arc>, rt: &Runtime, @@ -103,20 +141,14 @@ pub fn start_notifications( // GPU MUX Mode notif let enabled_notifications_copy = config.clone(); tokio::spawn(async move { - let conn = zbus::Connection::system() - .await - .map_err(|e| { - error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); - e - }) - .unwrap(); - let proxy = PlatformProxy::new(&conn) - .await - .map_err(|e| { - error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); - e - }) - .unwrap(); + let conn = zbus::Connection::system().await.map_err(|e| { + error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); + e + })?; + let proxy = PlatformProxy::new(&conn).await.map_err(|e| { + error!("zbus signal: receive_notify_gpu_mux_mode: {e}"); + e + })?; let mut actual_mux_mode = GpuMode::Error; if let Ok(mode) = proxy.gpu_mux_mode().await { @@ -138,87 +170,75 @@ pub fn start_notifications( do_mux_notification("Reboot required. BIOS GPU MUX mode set to", &mode).ok(); } } + Ok::<(), zbus::Error>(()) }); - use supergfxctl::pci_device::Device; - let dev = Device::find().unwrap_or_default(); - let mut found_dgpu = false; // just for logging - for dev in dev { - if dev.is_dgpu() { - let enabled_notifications_copy = config.clone(); - // Plain old thread is perfectly fine since most of this is potentially blocking - rt.spawn_blocking(move || { - let mut last_status = GfxPower::Unknown; - loop { - if let Ok(status) = dev.get_runtime_status() { - if status != GfxPower::Unknown && status != last_status { - if let Ok(config) = enabled_notifications_copy.lock() { - if !config.notifications.receive_notify_gfx_status - || !config.notifications.enabled - { - continue; - } - } - // Required check because status cycles through - // active/unknown/suspended - do_gpu_status_notif("dGPU status changed:", &status).ok(); - } - last_status = status; - } - std::thread::sleep(Duration::from_millis(500)); - } - }); - found_dgpu = true; - break; - } - } - if !found_dgpu { - warn!("Did not find a dGPU on this system, dGPU status won't be avilable"); - } - + let enabled_notifications_copy = config.clone(); // GPU Mode change/action notif tokio::spawn(async move { - let conn = zbus::Connection::system() - .await - .map_err(|e| { - error!("zbus signal: receive_notify_action: {e}"); - e - }) - .unwrap(); - let proxy = SuperProxy::builder(&conn) - .build() - .await - .map_err(|e| { - error!("zbus signal: receive_notify_action: {e}"); - e - }) - .unwrap(); + if let Err(e) = { + let conn = zbus::Connection::system().await?; + let proxy = SuperProxy::builder(&conn).build().await?; + let _ = proxy.mode().await?; - if proxy.mode().await.is_err() { - info!("supergfxd not running or not responding"); - return; - } - - if let Ok(mut p) = proxy.receive_notify_action().await { - info!("Started zbus signal thread: receive_notify_action"); - while let Some(e) = p.next().await { - if let Ok(out) = e.args() { - let action = out.action(); - let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default()); - match action { - supergfxctl::actions::UserActionRequired::Reboot => { - do_mux_notification("Graphics mode change requires reboot", &mode) + let proxy_copy = proxy.clone(); + if let Ok(mut p) = proxy.receive_notify_action().await { + tokio::spawn(async move { + info!("Started zbus signal thread: receive_notify_action"); + while let Some(e) = p.next().await { + if let Ok(out) = e.args() { + let action = out.action(); + let mode = convert_gfx_mode(proxy.mode().await.unwrap_or_default()); + match action { + supergfxctl::actions::UserActionRequired::Reboot => { + do_mux_notification( + "Graphics mode change requires reboot", + &mode, + ) + } + _ => do_gfx_action_notif(<&str>::from(action), *action, mode), + } + .map_err(|e| { + error!("zbus signal: do_gfx_action_notif: {e}"); + e + }) + .ok(); } - _ => do_gfx_action_notif(<&str>::from(action), *action, mode), } - .map_err(|e| { - error!("zbus signal: do_gfx_action_notif: {e}"); - e - }) - .ok(); - } - } - }; + }); + }; + + if let Ok(mut p) = proxy_copy.receive_notify_gfx_status().await { + tokio::spawn(async move { + info!("Started zbus signal thread: receive_notify_gfx_status"); + let mut last_status = GfxPower::Unknown; + while let Some(e) = p.next().await { + if let Ok(out) = e.args() { + let status = out.status; + if status != GfxPower::Unknown && status != last_status { + if let Ok(config) = enabled_notifications_copy.lock() { + if !config.notifications.receive_notify_gfx_status + || !config.notifications.enabled + { + continue; + } + } + // Required check because status cycles through + // active/unknown/suspended + do_gpu_status_notif("dGPU status changed:", &status).ok(); + } + last_status = status; + } + } + }); + }; + Ok::<(), zbus::Error>(()) + } { + error!("zbus signal: receive_notify_gfx_status: {e}"); + info!("Attempting to start plain dgpu status monitor"); + start_dpu_status_mon(config.clone()); + } + Ok::<(), zbus::Error>(()) }); Ok(vec![blocking]) diff --git a/rog-control-center/src/ui/setup_aura.rs b/rog-control-center/src/ui/setup_aura.rs index 7f300156..4565d791 100644 --- a/rog-control-center/src/ui/setup_aura.rs +++ b/rog-control-center/src/ui/setup_aura.rs @@ -1,6 +1,6 @@ use std::sync::{Arc, Mutex}; -use log::{error, info}; +use log::{debug, error, info}; use rog_aura::keyboard::LaptopAuraPower; use rog_aura::{AuraDeviceType, PowerZones}; use rog_dbus::zbus_aura::AuraProxy; @@ -76,7 +76,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc>) { tokio::spawn(async move { let Ok(aura) = find_aura_iface().await else { info!("This device appears to have no aura interfaces"); - return; + return Ok::<(), zbus::Error>(()); }; set_ui_props_async!(handle, aura, AuraPageData, brightness); @@ -226,5 +226,7 @@ pub fn setup_aura_page(ui: &MainWindow, _states: Arc>) { } } }); + debug!("Aura setup tasks complete"); + Ok(()) }); } diff --git a/rog-control-center/translations/en/rog-control-center.po b/rog-control-center/translations/en/rog-control-center.po index bae9f149..a3657882 100644 --- a/rog-control-center/translations/en/rog-control-center.po +++ b/rog-control-center/translations/en/rog-control-center.po @@ -2,7 +2,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2024-05-17 10:31+0000\n" +"POT-Creation-Date: 2024-05-17 23:21+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n"