import gdb
from . import utils
PM_COUNT = utils.get_field_nitems("struct pm_domain_s", "wakelock")
class PMStateInfo:
def __init__(self, wake_time, sleep_time):
self.wake_time = wake_time
self.sleep_time = sleep_time
self.total_time = wake_time + sleep_time
def has_inferior():
inferior = gdb.selected_inferior()
return inferior is not None and inferior.is_valid()
def get_pm_state_info_list(domain):
state_info_list = []
sum_time = 0
for state in range(PM_COUNT):
wake_time = int(domain["wake"][state]["tv_sec"])
sleep_time = int(domain["sleep"][state]["tv_sec"])
sum_time += wake_time + sleep_time
state_info_list.append(PMStateInfo(wake_time, sleep_time))
sum_time = sum_time if sum_time > 0 else 1
return state_info_list, sum_time
class Pmconfig(gdb.Command):
"""Display power management configuration information
Usage: pmconfig
"""
state_formatter = "{:<12} {:<12} {:<12} {:<12}"
state_header = ("WAKE", "SLEEP", "TOTAL")
def __init__(self):
if PM_COUNT:
super().__init__("pmconfig", gdb.COMMAND_USER)
def get_time_str(self, time_val, sum_time):
percentage = (time_val / sum_time) * 100 if sum_time > 0 else 0
return f"{int(time_val)}s {int(percentage):02}%"
def print_state_info(self, domain_name, domain):
state_path = f"/proc/pm/state{domain_name[-1]}"
gdb.write(f"{state_path}:\n")
gdb.write(self.state_formatter.format(domain_name, *self.state_header) + "\n")
state_info_list, sum_time = get_pm_state_info_list(domain)
pm_state = utils.parse_and_eval("g_pm_state")
for state in range(PM_COUNT):
state_info = state_info_list[state]
wake_str = self.get_time_str(state_info.wake_time, sum_time)
sleep_str = self.get_time_str(state_info.sleep_time, sum_time)
total_str = self.get_time_str(state_info.total_time, sum_time)
state_name = pm_state[state].string()
gdb.write(
self.state_formatter.format(state_name, wake_str, sleep_str, total_str)
+ "\n"
)
@utils.dont_repeat_decorator
def invoke(self, arg: str, from_tty: bool) -> None:
if not has_inferior():
return
pmdomains = utils.parse_and_eval("g_pmdomains")
ndomains = utils.nitems(pmdomains)
domains = [f"DOMAIN{i}" for i in range(ndomains)]
for i, domain_name in enumerate(domains):
domain = pmdomains[i]
self.print_state_info(domain_name, domain)
def diagnose(self, *args, **kwargs):
return {
"title": "Power Manager Information",
"summary": "Power manager information",
"command": "pmconfig",
"result": "info",
"category": utils.DiagnoseCategory.power,
"message": gdb.execute("pmconfig", to_string=True),
}