• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""
2perf is a tool included in the linux kernel tree that
3supports functionality similar to oprofile and more.
4
5@see: http://lwn.net/Articles/310260/
6"""
7
8import time, os, stat, subprocess, signal
9import logging
10from autotest_lib.client.bin import profiler, os_dep, utils
11
12
13class perf(profiler.profiler):
14    version = 1
15
16    def initialize(self, events=["cycles","instructions"], trace=False):
17        if type(events) == str:
18            self.events = [events]
19        else:
20            self.events = events
21        self.trace = trace
22        self.perf_bin = os_dep.command('perf')
23        perf_help = utils.run('%s report help' % self.perf_bin,
24                              ignore_status=True).stderr
25        self.sort_keys = None
26        for line in perf_help.split('\n'):
27            a = "sort by key(s):"
28            if a in line:
29                line = line.replace(a, "")
30                self.sort_keys = [k.rstrip(",") for k in line.split() if
31                                  k.rstrip(",") != 'dso']
32        if not self.sort_keys:
33            self.sort_keys = ['comm', 'cpu']
34
35
36    def start(self, test):
37        self.logfile = os.path.join(test.profdir, "perf")
38        cmd = ("exec %s record -a -o %s" %
39               (self.perf_bin, self.logfile))
40        if "parent" in self.sort_keys:
41            cmd += " -g"
42        if self.trace:
43            cmd += " -R"
44        for event in self.events:
45            cmd += " -e %s" % event
46        self._process = subprocess.Popen(cmd, shell=True,
47                                         stderr=subprocess.STDOUT)
48
49
50    def stop(self, test):
51        os.kill(self._process.pid, signal.SIGINT)
52        self._process.wait()
53
54
55    def report(self, test):
56        for key in self.sort_keys:
57            reportfile = os.path.join(test.profdir, '%s.comm' % key)
58            cmd = ("%s report -i %s --sort %s,dso" % (self.perf_bin,
59                                                      self.logfile,
60                                                      key))
61            outfile = open(reportfile, 'w')
62            p = subprocess.Popen(cmd, shell=True, stdout=outfile,
63                                 stderr=subprocess.STDOUT)
64            p.wait()
65
66        if self.trace:
67            tracefile = os.path.join(test.profdir, 'trace')
68            cmd = ("%s script -i %s" % (self.perf_bin, self.logfile,))
69
70            outfile = open(tracefile, 'w')
71            p = subprocess.Popen(cmd, shell=True, stdout=outfile,
72                                 stderr=subprocess.STDOUT)
73            p.wait()
74
75        # The raw detailed perf output is HUGE.  We cannot store it by default.
76        perf_log_size = os.stat(self.logfile)[stat.ST_SIZE]
77        logging.info('Removing %s after generating reports (saving %s bytes).',
78                     self.logfile, perf_log_size)
79        os.unlink(self.logfile)
80