xref: /aosp_15_r20/external/autotest/client/profilers/top/top.py (revision 9c5db1993ded3edbeafc8092d69fe5de2ee02df7)
1*9c5db199SXin Li"""top prints out CPU stats"""
2*9c5db199SXin Li
3*9c5db199SXin Liimport os, subprocess, signal
4*9c5db199SXin Liimport logging
5*9c5db199SXin Lifrom autotest_lib.client.bin import profiler
6*9c5db199SXin Li
7*9c5db199SXin Li
8*9c5db199SXin Liclass top(profiler.profiler):
9*9c5db199SXin Li    """
10*9c5db199SXin Li    Starts top on the DUT and polls every 5 seconds. Any processes with a
11*9c5db199SXin Li    %cpu of zero will be stripped from the output.
12*9c5db199SXin Li    """
13*9c5db199SXin Li
14*9c5db199SXin Li    version = 1
15*9c5db199SXin Li
16*9c5db199SXin Li    SCRIPT = "top -b -c -w 200 -d 5 -o '%CPU' -H | " \
17*9c5db199SXin Li             "awk '$1 ~ /[0-9]+/ && $9 == '0.0' {next} {print}'"
18*9c5db199SXin Li
19*9c5db199SXin Li    def start(self, test):
20*9c5db199SXin Li        self._output = open(os.path.join(test.profdir, "top"), "wb")
21*9c5db199SXin Li
22*9c5db199SXin Li        logging.debug("Starting top")
23*9c5db199SXin Li
24*9c5db199SXin Li        # Log the start time so a complete datetime can be computed later
25*9c5db199SXin Li        subprocess.call(["date", "-Iseconds"], stdout=self._output)
26*9c5db199SXin Li
27*9c5db199SXin Li        self._process = subprocess.Popen(
28*9c5db199SXin Li                self.SCRIPT,
29*9c5db199SXin Li                stderr=self._output,
30*9c5db199SXin Li                stdout=self._output,
31*9c5db199SXin Li                shell=True,
32*9c5db199SXin Li                # We need to start a process group so we can kill the script's
33*9c5db199SXin Li                # children.
34*9c5db199SXin Li                preexec_fn=os.setpgrp,
35*9c5db199SXin Li                close_fds=True)
36*9c5db199SXin Li
37*9c5db199SXin Li    def stop(self, test):
38*9c5db199SXin Li        logging.debug("Stopping top")
39*9c5db199SXin Li
40*9c5db199SXin Li        # Kill the whole process group so top and awk die
41*9c5db199SXin Li        os.killpg(self._process.pid, signal.SIGTERM)
42*9c5db199SXin Li
43*9c5db199SXin Li        self._process.wait()
44*9c5db199SXin Li
45*9c5db199SXin Li        logging.debug("Stopped top")
46*9c5db199SXin Li
47*9c5db199SXin Li        self._output.close()
48*9c5db199SXin Li
49*9c5db199SXin Li    def report(self, test):
50*9c5db199SXin Li        pass
51