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