Skip to content

Commit

Permalink
The word is "aggregated"
Browse files Browse the repository at this point in the history
  • Loading branch information
walles committed Mar 28, 2024
1 parent e7d5de7 commit 2c81d80
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 41 deletions.
17 changes: 7 additions & 10 deletions px/px_process.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def __init__(
memory_percent: Optional[float] = None,
cpu_percent: Optional[float] = None,
cpu_time: Optional[float] = None,
cumulative_cpu_time: Optional[float] = None,
aggregated_cpu_time: Optional[float] = None,
) -> None:
self.pid: int = pid
self.ppid: Optional[int] = ppid
Expand Down Expand Up @@ -142,7 +142,7 @@ def __init__(
self.cpu_percent_s = f"{cpu_percent:.0f}%"

self.set_cpu_time_seconds(cpu_time)
self.set_cumulative_cpu_time_seconds(cumulative_cpu_time)
self.set_aggregated_cpu_time_seconds(aggregated_cpu_time)

self.children: List[PxProcess] = []
self.parent: Optional[PxProcess] = None
Expand Down Expand Up @@ -178,12 +178,12 @@ def set_cpu_time_seconds(self, seconds: Optional[float]) -> None:
self.cpu_time_s = seconds_to_str(seconds)
self.cpu_time_seconds = seconds

def set_cumulative_cpu_time_seconds(self, seconds: Optional[float]) -> None:
self.cumulative_cpu_time_s: str = "--"
self.cumulative_cpu_time_seconds = None
def set_aggregated_cpu_time_seconds(self, seconds: Optional[float]) -> None:
self.aggregated_cpu_time_s: str = "--"
self.aggregated_cpu_time_seconds = None
if seconds is not None:
self.cumulative_cpu_time_s = seconds_to_str(seconds)
self.cumulative_cpu_time_seconds = seconds
self.aggregated_cpu_time_s = seconds_to_str(seconds)
self.aggregated_cpu_time_seconds = seconds

def match(self, string, require_exact_user=True):
"""
Expand Down Expand Up @@ -408,9 +408,6 @@ def resolve_links(processes: Dict[int, PxProcess], now: datetime.datetime) -> No
process.parent.children.append(process)


# FIXME: Make the tree look like a tree in cumulative CPU time mode


def remove_process_and_descendants(processes: Dict[int, PxProcess], pid: int) -> None:
process = processes[pid]
if process.parent is not None:
Expand Down
4 changes: 2 additions & 2 deletions px/px_sort_order.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
class SortOrder(enum.Enum):
CPU = 1
MEMORY = 2
CUMULATIVE_CPU = 3
AGGREGATED_CPU = 3

def next(self):
if self == SortOrder.CPU:
return SortOrder.MEMORY
if self == SortOrder.MEMORY:
return SortOrder.CUMULATIVE_CPU
return SortOrder.AGGREGATED_CPU
return SortOrder.CPU
24 changes: 12 additions & 12 deletions px/px_terminal.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ def to_screen_lines(
"""

cputime_name = "CPUTIME"
if sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
cputime_name = "CUMLCPU"
if sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
cputime_name = "AGGRCPU"
headings = [
"PID",
"COMMAND",
Expand All @@ -342,9 +342,9 @@ def to_screen_lines(
highlight_column = 5 # "RAM"
elif sort_order in [
px_sort_order.SortOrder.CPU,
px_sort_order.SortOrder.CUMULATIVE_CPU,
px_sort_order.SortOrder.AGGREGATED_CPU,
]:
highlight_column = 4 # "CPUTIME" or "CUMLCPU"
highlight_column = 4 # "CPUTIME" or "AGGRCPU"

# Compute widest width for pid, command, user, cpu and memory usage columns
pid_width = len(headings[0])
Expand All @@ -360,8 +360,8 @@ def to_screen_lines(
cpu_width = max(cpu_width, len(proc.cpu_percent_s))

cputime_s = proc.cpu_time_s
if sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
cputime_s = proc.cumulative_cpu_time_s
if sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
cputime_s = proc.aggregated_cpu_time_s
cputime_width = max(cputime_width, len(cputime_s))

mem_width = max(mem_width, len(proc.memory_percent_s))
Expand Down Expand Up @@ -406,14 +406,14 @@ def to_screen_lines(
max_memory_percent_s = proc.memory_percent_s

cpu_time_seconds = proc.cpu_time_seconds
if sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
if sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
if proc.pid <= 1:
# Both the kernel (PID 0) and the init process (PID 1) will just
# have contain the total time of all other processes. Since we
# only use this max value for highlighting (see below), if we
# include these only they will be highlighted. So we skip them.
continue
cpu_time_seconds = proc.cumulative_cpu_time_seconds
cpu_time_seconds = proc.aggregated_cpu_time_seconds
if cpu_time_seconds is not None and cpu_time_seconds > max_cpu_time_seconds:
max_cpu_time_seconds = cpu_time_seconds

Expand All @@ -433,9 +433,9 @@ def to_screen_lines(

cpu_time_s = proc.cpu_time_s
cpu_time_seconds = proc.cpu_time_seconds
if sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
cpu_time_s = proc.cumulative_cpu_time_s
cpu_time_seconds = proc.cumulative_cpu_time_seconds
if sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
cpu_time_s = proc.aggregated_cpu_time_s
cpu_time_seconds = proc.aggregated_cpu_time_seconds

if not cpu_time_seconds:
# Zero or undefined
Expand All @@ -455,7 +455,7 @@ def to_screen_lines(
owner = bold(owner)

indent = ""
if sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
if sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
indent = " " * proc.level * 2

columns = [
Expand Down
30 changes: 15 additions & 15 deletions px/px_top.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,9 @@ def adjust_cpu_times(
return list(pid2proc.values())


def compute_cumulative_cpu_times(toplist: List[px_process.PxProcess]) -> None:
def compute_aggregated_cpu_times(toplist: List[px_process.PxProcess]) -> None:
"""
Compute cumulative CPU times for all processes in the toplist.
Compute aggregated CPU times for all processes in the toplist.
This function modifies the toplist in place.
"""
Expand All @@ -108,12 +108,12 @@ def compute_cumulative_cpu_times(toplist: List[px_process.PxProcess]) -> None:
while root_process.parent is not None:
root_process = root_process.parent

# Now, walk the process tree and compute cumulative CPU times
# Now, walk the process tree and compute aggregated CPU times
def walk_tree(proc: px_process.PxProcess) -> float:
sum = proc.cpu_time_seconds or 0
for child in proc.children:
sum += walk_tree(child)
proc.set_cumulative_cpu_time_seconds(sum)
proc.set_aggregated_cpu_time_seconds(sum)
return sum

walk_tree(root_process)
Expand All @@ -126,8 +126,8 @@ def get_notnone_cpu_time_seconds(proc: px_process.PxProcess) -> float:
return 0


def get_notnone_cumulative_cpu_time_seconds(proc: px_process.PxProcess) -> float:
seconds = proc.cumulative_cpu_time_seconds
def get_notnone_aggregated_cpu_time_seconds(proc: px_process.PxProcess) -> float:
seconds = proc.aggregated_cpu_time_seconds
if seconds is not None:
return seconds
return 0
Expand Down Expand Up @@ -166,15 +166,15 @@ def sort_by_cpu_usage_tree(
toplist: List[px_process.PxProcess],
) -> List[px_process.PxProcess]:
"""
Sort the process list by cumulative CPU time, but keep the tree structure.
Sort the process list by aggregated CPU time, but keep the tree structure.
"""
root_process = toplist[0]
while root_process.parent is not None:
root_process = root_process.parent

def sort_children(proc: px_process.PxProcess) -> None:
proc.children = sorted(
proc.children, key=get_notnone_cumulative_cpu_time_seconds, reverse=True
proc.children, key=get_notnone_aggregated_cpu_time_seconds, reverse=True
)
for child in proc.children:
sort_children(child)
Expand All @@ -201,15 +201,15 @@ def get_toplist(
sort_order=px_sort_order.SortOrder.CPU,
) -> List[px_process.PxProcess]:
toplist = adjust_cpu_times(baseline, current)
compute_cumulative_cpu_times(toplist)
compute_aggregated_cpu_times(toplist)

# Sort by interestingness last
toplist = px_process.order_best_first(toplist)
if sort_order == px_sort_order.SortOrder.MEMORY:
toplist = sorted(toplist, key=get_notnone_memory_percent, reverse=True)
elif sort_order == px_sort_order.SortOrder.CPU:
toplist = sort_by_cpu_usage(toplist)
elif sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
elif sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
toplist = sort_by_cpu_usage_tree(toplist)

return toplist
Expand Down Expand Up @@ -425,12 +425,12 @@ def get_screen_lines(
# number of processes
toplist_table_lines += screen_rows * [""]

top_what = "CPU"
top_line = "Top processes by CPU usage"
if sort_order == px_sort_order.SortOrder.MEMORY:
top_what = "memory"
elif sort_order == px_sort_order.SortOrder.CUMULATIVE_CPU:
top_what = "cumulative CPU"
lines += [px_terminal.bold("Top " + top_what + " using processes")]
top_line = "Top processes by memory usage"
elif sort_order == px_sort_order.SortOrder.AGGREGATED_CPU:
top_line = "Process tree ordered by aggregated CPU time"
lines += [px_terminal.bold(top_line)]

if top_mode == MODE_SEARCH:
lines += [SEARCH_PROMPT_ACTIVE + px_terminal.bold(search or "") + SEARCH_CURSOR]
Expand Down
4 changes: 2 additions & 2 deletions tests/px_top_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,8 @@ def test_get_toplist():
baseline = {p.pid: (p.start_time, p.cpu_time_seconds or 0.0) for p in current}
toplist = px_top.get_toplist(baseline, px_process.get_all())
for process in toplist:
assert process.cumulative_cpu_time_seconds is not None
assert process.cumulative_cpu_time_s != "--"
assert process.aggregated_cpu_time_seconds is not None
assert process.aggregated_cpu_time_s != "--"


def test_get_command():
Expand Down

0 comments on commit 2c81d80

Please sign in to comment.