78 lines
2.7 KiB
Python
78 lines
2.7 KiB
Python
from app_class import AppClass
|
|
from config import Config
|
|
from cpufreq import cpuFreq, cpufreq # type: ignore
|
|
from functools import cached_property
|
|
from exceptions import GovernorNotFound
|
|
from typing import Optional, NamedTuple
|
|
|
|
|
|
class Governor(NamedTuple):
|
|
name: str
|
|
priority: int
|
|
|
|
|
|
_governor_list: tuple[Governor, Governor, Governor, Governor, Governor, Governor] = (
|
|
Governor("performance", 0),
|
|
Governor("schedutil", 1),
|
|
Governor("ondemand", 2),
|
|
Governor("conservative", 3),
|
|
Governor("userspace", 4),
|
|
Governor("powersave", 5)
|
|
)
|
|
|
|
|
|
class GovernorControl(AppClass):
|
|
def __init__(self, _config: Config) -> None:
|
|
super().__init__(_config)
|
|
self.log.info("current governor is: %s", self.current_governor)
|
|
|
|
@cached_property
|
|
def _cpufreq(self) -> Optional[cpuFreq]:
|
|
try:
|
|
return cpuFreq()
|
|
except cpufreq.CPUFreqErrorInit:
|
|
self.log.warning("cpu architecture has no governor support")
|
|
return None
|
|
|
|
@property
|
|
def current_governor(self) -> Optional[Governor]:
|
|
if self._cpufreq is None:
|
|
return None
|
|
_governor = set(self._cpufreq.get_governors().values())
|
|
_governor_to_return = self._establish_governor(list(_governor)[0])
|
|
if len(_governor) == 0:
|
|
raise GovernorNotFound("Unable to retrieve current governor")
|
|
if len(_governor) > 1:
|
|
self.log.error("multiple governors have been set, which is not expected.")
|
|
# returning governor with highest priority based on performance
|
|
for gov in _governor:
|
|
t_gov = self._establish_governor(gov)
|
|
if t_gov.priority < _governor_to_return.priority:
|
|
_governor_to_return == t_gov
|
|
return _governor_to_return
|
|
|
|
def _establish_governor(self, governor_name: str) -> Governor:
|
|
governor = next((g for g in _governor_list if g.name == governor_name), None)
|
|
if governor is None:
|
|
raise RuntimeError("could not establish governor")
|
|
return governor
|
|
|
|
def set_governor(self, governor_name: str) -> None:
|
|
self.log.debug(
|
|
"setting cpu governor to %s by using command self._cpufreq.set_governors(%s)",
|
|
governor_name, governor_name
|
|
)
|
|
|
|
if self._config.testmode:
|
|
self.log.warning("application is running in testmode, cpu governor not set")
|
|
return None
|
|
|
|
if self._cpufreq is None:
|
|
return None
|
|
|
|
if governor_name not in self._cpufreq.available_governors:
|
|
self.log.error("governor %s not supported by cpu", governor_name)
|
|
return None
|
|
|
|
self._cpufreq.set_governors(governor_name)
|