From ca439a206b92c62463e4a1380c5a47317366c004 Mon Sep 17 00:00:00 2001 From: GuoHui <767428+guohui85@users.noreply.github.com> Date: Thu, 12 Nov 2026 16:00:45 +0800 Subject: [PATCH] perf(network): poll Wi-Fi status only while it can be seen - The status worker started two nmcli processes every 3 s for the launcher's lifetime, also while the screen was locked or another app owned the display. Each round costs ~0.2 s of CPU on the device, plus work in NetworkManager and the system bus. - It now refreshes every 3 s only while the launcher is in the foreground (LVGL_RUN_FLAGE == 1) and the backlight is on, and every 60 s otherwise. The worker still wakes every 3 s, so the status catches up within one interval after the screen comes back. - test_wifi_connection defines LVGL_RUN_FLAGE, as the keyboard tests do. - Measured on a CardputerZero (screen locked, on battery, on top of the system-sound idle fix): 212 -> 204 mA mean (median 203 -> 202 mA), context switches 818/s -> 516/s, no nmcli process seen in 30 one-second samples while locked. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0135vUaG2FpgpGRJfB9LEPvZ --- .../cp0_lvgl/src/cp0/cp0_lvgl_network.cpp | 28 +++++++++++++++++-- .../cp0_lvgl/tests/test_wifi_connection.cpp | 4 +++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/ext_components/cp0_lvgl/src/cp0/cp0_lvgl_network.cpp b/ext_components/cp0_lvgl/src/cp0/cp0_lvgl_network.cpp index 3ad4782c..434fd827 100644 --- a/ext_components/cp0_lvgl/src/cp0/cp0_lvgl_network.cpp +++ b/ext_components/cp0_lvgl/src/cp0/cp0_lvgl_network.cpp @@ -5,6 +5,7 @@ */ #include "cp0_lvgl_app.h" +#include "keyboard_input.h" // LVGL_RUN_FLAGE #include "hal_lvgl_bsp.h" #include "../cp0_app_internal_utils.h" #include "../cp0_network_api_contract.hpp" @@ -480,12 +481,35 @@ class WifiSystem std::condition_variable wake_; std::mutex wake_mutex_; + // Each refresh starts two nmcli processes (~0.2 s of CPU on the device, plus work in + // NetworkManager and the system bus). Refresh every 3 s only while the status can be + // seen: the launcher in the foreground and the backlight on. Otherwise every 60 s. + static constexpr auto kVisiblePollInterval = std::chrono::seconds(3); + static constexpr auto kHiddenPollInterval = std::chrono::seconds(60); + + static bool status_visible() + { + if (LVGL_RUN_FLAGE != 1) return false; // another app owns the screen + FILE *fp = std::fopen("/sys/class/backlight/backlight/brightness", "r"); + if (!fp) return true; + int level = 1; + if (std::fscanf(fp, "%d", &level) != 1) level = 1; + std::fclose(fp); + return level > 0; + } + void poll_loop() { + auto last_refresh = std::chrono::steady_clock::time_point{}; while (running_.load()) { - update_status_cache(); + const auto now = std::chrono::steady_clock::now(); + if (last_refresh == std::chrono::steady_clock::time_point{} || status_visible() || + now - last_refresh >= kHiddenPollInterval) { + update_status_cache(); + last_refresh = std::chrono::steady_clock::now(); + } std::unique_lock lock(wake_mutex_); - wake_.wait_for(lock, std::chrono::seconds(3), + wake_.wait_for(lock, kVisiblePollInterval, [this] { return !running_.load(); }); } } diff --git a/ext_components/cp0_lvgl/tests/test_wifi_connection.cpp b/ext_components/cp0_lvgl/tests/test_wifi_connection.cpp index 44cb6a3d..5b15bdf9 100644 --- a/ext_components/cp0_lvgl/tests/test_wifi_connection.cpp +++ b/ext_components/cp0_lvgl/tests/test_wifi_connection.cpp @@ -10,6 +10,10 @@ #include #include +// Normally defined by the keyboard backend; the status poll reads it to tell whether the +// launcher owns the screen. +volatile int LVGL_RUN_FLAGE = 1; + decltype(cp0_signal_wifi_api) cp0_signal_wifi_api; namespace {