no bug - Bumping Firefox l10n changesets r=release a=l10n-bump DONTBUILD CLOSED TREE
[gecko.git] / tools / power / mach_commands.py
blob117a96e1c71565c88f7ad985615774a71e09d867
1 # This Source Code Form is subject to the terms of the Mozilla Public
2 # License, v. 2.0. If a copy of the MPL was not distributed with this
3 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
5 from mach.decorators import Command, CommandArgument
6 from packaging.version import Version
9 def is_osx_10_10_or_greater(cls):
10 import platform
12 release = platform.mac_ver()[0]
13 return release and Version(release) >= Version("10.10")
16 # Get system power consumption and related measurements.
17 @Command(
18 "power",
19 category="misc",
20 conditions=[is_osx_10_10_or_greater],
21 description="Get system power consumption and related measurements for "
22 "all running browsers. Available only on Mac OS X 10.10 and above. "
23 "Requires root access.",
25 @CommandArgument(
26 "-i",
27 "--interval",
28 type=int,
29 default=30000,
30 help="The sample period, measured in milliseconds. Defaults to 30000.",
32 def power(command_context, interval):
33 """
34 Get system power consumption and related measurements.
35 """
36 import os
37 import re
38 import subprocess
40 rapl = os.path.join(command_context.topobjdir, "dist", "bin", "rapl")
42 interval = str(interval)
44 # Run a trivial command with |sudo| to gain temporary root privileges
45 # before |rapl| and |powermetrics| are called. This ensures that |rapl|
46 # doesn't start measuring while |powermetrics| is waiting for the root
47 # password to be entered.
48 try:
49 subprocess.check_call(["sudo", "true"])
50 except Exception:
51 print("\nsudo failed; aborting")
52 return 1
54 # This runs rapl in the background because nothing in this script
55 # depends on the output. This is good because we want |rapl| and
56 # |powermetrics| to run at the same time.
57 subprocess.Popen([rapl, "-n", "1", "-i", interval])
59 lines = subprocess.check_output(
61 "sudo",
62 "powermetrics",
63 "--samplers",
64 "tasks",
65 "--show-process-coalition",
66 "--show-process-gpu",
67 "-n",
68 "1",
69 "-i",
70 interval,
72 universal_newlines=True,
75 # When run with --show-process-coalition, |powermetrics| groups outputs
76 # into process coalitions, each of which has a leader.
78 # For example, when Firefox runs from the dock, its coalition looks
79 # like this:
81 # org.mozilla.firefox
82 # firefox
83 # plugin-container
85 # When Safari runs from the dock:
87 # com.apple.Safari
88 # Safari
89 # com.apple.WebKit.Networking
90 # com.apple.WebKit.WebContent
91 # com.apple.WebKit.WebContent
93 # When Chrome runs from the dock:
95 # com.google.Chrome
96 # Google Chrome
97 # Google Chrome Helper
98 # Google Chrome Helper
100 # In these cases, we want to print the whole coalition.
102 # Also, when you run any of them from the command line, things are the
103 # same except that the leader is com.apple.Terminal and there may be
104 # non-browser processes in the coalition, e.g.:
106 # com.apple.Terminal
107 # firefox
108 # plugin-container
109 # <and possibly other, non-browser processes>
111 # Also, the WindowServer and kernel coalitions and processes are often
112 # relevant.
114 # We want to print all these but omit uninteresting coalitions. We
115 # could do this by properly parsing powermetrics output, but it's
116 # simpler and more robust to just grep for a handful of identifying
117 # strings.
119 print() # blank line between |rapl| output and |powermetrics| output
121 for line in lines.splitlines():
122 # Search for the following things.
124 # - '^Name' is for the columns headings line.
126 # - 'firefox' and 'plugin-container' are for Firefox
128 # - 'Safari\b' and 'WebKit' are for Safari. The '\b' excludes
129 # SafariCloudHistoryPush, which is a process that always
130 # runs, even when Safari isn't open.
132 # - 'Chrome' is for Chrome.
134 # - 'Terminal' is for the terminal. If no browser is running from
135 # within the terminal, it will show up unnecessarily. This is a
136 # minor disadvantage of this very simple parsing strategy.
138 # - 'WindowServer' is for the WindowServer.
140 # - 'kernel' is for the kernel.
142 if re.search(
143 r"(^Name|firefox|plugin-container|Safari\b|WebKit|Chrome|Terminal|WindowServer|kernel)", # NOQA: E501
144 line,
146 print(line)
148 return 0