diff --git a/system/power1/manager.go b/system/power1/manager.go index cba67efe3..0df7cee04 100644 --- a/system/power1/manager.go +++ b/system/power1/manager.go @@ -10,9 +10,11 @@ import ( "io/ioutil" "os" "path/filepath" + "strings" "sync" "time" + "github.com/fsnotify/fsnotify" dbus "github.com/godbus/dbus/v5" "github.com/linuxdeepin/dde-api/powersupply" "github.com/linuxdeepin/dde-api/powersupply/battery" @@ -33,6 +35,11 @@ const ( amdGPUPath = "/sys/class/drm/card0/device/power_dpm_force_performance_level" ) +const ( + pstateConfPath = "/sys/devices/system/cpu/cpufreq/policy0/energy_performance_preference" + scalingConfPath = "/sys/devices/system/cpu/cpufreq/policy0/scaling_governor" +) + func init() { if arch.Get() == arch.Sunway { noUEvent = true @@ -150,6 +157,67 @@ func newManager(service *dbusutil.Service) (*Manager, error) { return nil, err } + go func() { + watcher, err := fsnotify.NewWatcher() + defer watcher.Close() + + if err != nil { + logger.Warning("power fswatcher error:", err) + return + } + + e := watcher.Add("/sys/devices/system/cpu/cpufreq/policy0") + if e != nil { + logger.Warning("power fswatcher error:", e) + return + } + + for { + select { + case event, ok := <-watcher.Events : + if !ok { + return + } + if event.Has(fsnotify.Write) { + if m.hasPstate && strings.HasSuffix(event.Name, "energy_performance_preference") { + data, err := os.ReadFile(pstateConfPath) + if err == nil { + status := strings.TrimSpace(string(data)) + if status == m.balanceScalingGovernor { + m.emitPropChangedMode("balance") + } else if status == "performance" { + m.emitPropChangedMode("performance") + } else if status == "power" { + m.emitPropChangedMode("powersave") + } else { + logger.Debug("Unknown status:", status) + } + } + } else if strings.HasSuffix(event.Name, "scaling_governor") { + data, err := os.ReadFile(scalingConfPath) + if err == nil { + status := strings.TrimSpace(string(data)) + if status == m.balanceScalingGovernor { + m.emitPropChangedMode("balance") + } else if status == "high" { + m.emitPropChangedMode("performance") + } else if status == "powersave" { + m.emitPropChangedMode("powersave") + } else { + logger.Debug("Unknown status:", status) + } + } + } + } + case err, ok := <-watcher.Errors : + if !ok { + return + } + logger.Warning("power fswatcher error:", err) + } + } + }() + return m, nil }