Home | History | Annotate | Download | only in cros_perf
      1 # Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
      2 # Use of this source code is governed by a BSD-style license that can be
      3 # found in the LICENSE file.
      4 
      5 """
      6 This is a profiler class for the perf profiler in ChromeOS. It differs from
      7 the existing perf profiler in autotset by directly substituting the options
      8 passed to the initialize function into the "perf" command line. It allows one
      9 to specify which perf command to run and thus what type of profile to collect
     10 (e.g. "perf record" or "perf stat"). It also does not produce a perf report
     11 on the client (where there are no debug symbols) but instead copies
     12 the perf.data file back to the server for analysis.
     13 """
     14 
     15 import os, signal, subprocess
     16 from autotest_lib.client.bin import profiler, os_dep
     17 from autotest_lib.client.common_lib import error
     18 
     19 
     20 class cros_perf(profiler.profiler):
     21     version = 1
     22 
     23     def initialize(self, options='-e cycles', profile_type='record'):
     24         # The two supported options for profile_type are 'record' and 'stat'.
     25         self.options = options
     26         self.perf_bin = os_dep.command('perf')
     27         self.profile_type = profile_type
     28 
     29 
     30     def start(self, test):
     31         if self.profile_type == 'record':
     32             # perf record allows you to specify where to place the output.
     33             # perf stat does not.
     34             logfile = os.path.join(test.profdir, 'perf.data')
     35             self.options += ' -o %s' % logfile
     36 
     37         if self.profile_type == 'stat':
     38             # Unfortunately we need to give perf stat a command or process even
     39             # when running in system-wide mode.
     40             self.options += ' -p 1'
     41 
     42         outfile = os.path.join(test.profdir, 'perf.out')
     43 
     44         cmd = ('exec %s %s -a %s > %s 2>&1' %
     45                (self.perf_bin, self.profile_type, self.options, outfile))
     46 
     47         self._process = subprocess.Popen(cmd, shell=True,
     48                                          stderr=subprocess.STDOUT)
     49 
     50 
     51     def stop(self, test):
     52         ret_code = self._process.poll()
     53         if ret_code is not None:
     54             raise error.AutotestError('perf terminated early with return code: '
     55                                       '%d. Please check your logs.' % ret_code)
     56 
     57         self._process.send_signal(signal.SIGINT)
     58         self._process.wait()
     59