blob: 65a03e9aa2c943f56ce14e618e3f57128fdc602e [file] [log] [blame]
# Copyright (c) 2005 The Regents of The University of Michigan
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met: redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer;
# redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution;
# neither the name of the copyright holders nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
from orderdict import orderdict
import output
class ProfileData(object):
def __init__(self):
self.data = {}
self.total = {}
self.runs = orderdict()
self.runlist = []
def addvalue(self, run, cpu, symbol, value):
value = float(value)
self.data[run, cpu, symbol] = self.getvalue(run, cpu, symbol) + value
self.total[run, cpu] = self.gettotal(run, cpu) + value
if run not in self.runs:
self.runs[run] = orderdict()
if cpu not in self.runs[run]:
self.runs[run][cpu] = {}
if symbol not in self.runs[run][cpu]:
self.runs[run][cpu][symbol] = 0
self.runs[run][cpu][symbol] += value
def getvalue(self, run, cpu, symbol):
return self.data.get((run, cpu, symbol), 0)
def gettotal(self, run, cpu):
return self.total.get((run, cpu), 0)
class Profile(object):
default_order = ['ste', 'hte', 'htd', 'ocm', 'occ', 'ocp']
# This list controls the order of values in stacked bar data output
default_categories = [ 'interrupt',
'driver',
'stack',
'bufmgt',
'copy',
'user',
'other',
'idle']
def __init__(self, run_order=[], categories=[], stacknames=[]):
if not run_order:
run_order = Profile.default_order
if not categories:
categories = Profile.default_categories
self.run_order = run_order
self.categories = categories
self.rcategories = []
self.rcategories.extend(categories)
self.rcategories.reverse()
self.stacknames = stacknames
self.prof = ProfileData()
self.categorize = True
self.showidle = True
self.maxsymlen = 0
def category(self, symbol):
from categories import categories, categories_re
if categories.has_key(symbol):
return categories[symbol]
for regexp, cat in categories_re:
if regexp.match(symbol):
return cat
return 'other'
# Parse input file and put the results in the given run and cpu
def parsefile(self, run, cpu, filename):
fd = file(filename)
for line in fd:
(symbol, count) = line.split()
if symbol == "0x0":
continue
count = int(count)
if self.categorize:
symbol = self.category(symbol)
if symbol == 'idle' and not self.showidle:
continue
if symbol not in self.categories:
symbol = 'other'
self.maxsymlen = max(self.maxsymlen, len(symbol))
self.prof.addvalue(run, cpu, symbol, count)
fd.close()
# Read in files
def inputdir(self, directory):
import os, os.path, re
from os.path import expanduser, join as joinpath
directory = expanduser(directory)
label_ex = re.compile(r'm5prof\.(.*)')
for root,dirs,files in os.walk(directory):
for name in files:
match = label_ex.match(name)
if not match:
continue
filename = joinpath(root, name)
prefix = os.path.commonprefix([root, directory])
dirname = root[len(prefix)+1:]
self.parsefile(dirname, match.group(1), filename)
def get(self, job, stat):
if job.system is None:
raise AttributeError, 'The job must have a system set'
cpu = '%s.full0' % job.system
values = []
for cat in self.categories:
values.append(self.prof.getvalue(job.name, cpu, cat))
return values