114209Sandreas.sandberg@arm.com# Copyright (c) 2017-2019 ARM Limited 211878Sandreas.sandberg@arm.com# All rights reserved. 311878Sandreas.sandberg@arm.com# 411878Sandreas.sandberg@arm.com# The license below extends only to copyright in the software and shall 511878Sandreas.sandberg@arm.com# not be construed as granting a license to any other intellectual 611878Sandreas.sandberg@arm.com# property including but not limited to intellectual property relating 711878Sandreas.sandberg@arm.com# to a hardware implementation of the functionality of the software 811878Sandreas.sandberg@arm.com# licensed hereunder. You may use the software subject to the license 911878Sandreas.sandberg@arm.com# terms below provided that you ensure that this notice is replicated 1011878Sandreas.sandberg@arm.com# unmodified and in its entirety in all distributions of the software, 1111878Sandreas.sandberg@arm.com# modified or unmodified, in source code or in binary form. 1211878Sandreas.sandberg@arm.com# 134126SN/A# Copyright (c) 2007 The Regents of The University of Michigan 148295Snate@binkert.org# Copyright (c) 2010 The Hewlett-Packard Development Company 154126SN/A# All rights reserved. 164126SN/A# 174126SN/A# Redistribution and use in source and binary forms, with or without 184126SN/A# modification, are permitted provided that the following conditions are 194126SN/A# met: redistributions of source code must retain the above copyright 204126SN/A# notice, this list of conditions and the following disclaimer; 214126SN/A# redistributions in binary form must reproduce the above copyright 224126SN/A# notice, this list of conditions and the following disclaimer in the 234126SN/A# documentation and/or other materials provided with the distribution; 244126SN/A# neither the name of the copyright holders nor the names of its 254126SN/A# contributors may be used to endorse or promote products derived from 264126SN/A# this software without specific prior written permission. 274126SN/A# 284126SN/A# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 294126SN/A# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 304126SN/A# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 314126SN/A# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 324126SN/A# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 334126SN/A# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 344126SN/A# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 354126SN/A# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 364126SN/A# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 374126SN/A# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 384126SN/A# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 394126SN/A# 404126SN/A# Authors: Nathan Binkert 4111878Sandreas.sandberg@arm.com# Andreas Sandberg 424126SN/A 4314213Sandreas.sandberg@arm.comfrom __future__ import print_function 4414213Sandreas.sandberg@arm.comfrom __future__ import absolute_import 4514213Sandreas.sandberg@arm.com 468296Snate@binkert.orgimport m5 478296Snate@binkert.org 4811802Sandreas.sandberg@arm.comimport _m5.stats 498295Snate@binkert.orgfrom m5.objects import Root 5014286Sgabeblack@google.comfrom m5.params import isNullPointer 518296Snate@binkert.orgfrom m5.util import attrdict, fatal 524126SN/A 5311766Sandreas.sandberg@arm.com# Stat exports 5411802Sandreas.sandberg@arm.comfrom _m5.stats import schedStatEvent as schedEvent 5511802Sandreas.sandberg@arm.comfrom _m5.stats import periodicStatDump 5611766Sandreas.sandberg@arm.com 578296Snate@binkert.orgoutputList = [] 5811878Sandreas.sandberg@arm.com 5914213Sandreas.sandberg@arm.com# Dictionary of stat visitor factories populated by the _url_factory 6014213Sandreas.sandberg@arm.com# visitor. 6114213Sandreas.sandberg@arm.comfactories = { } 6214213Sandreas.sandberg@arm.com 6314213Sandreas.sandberg@arm.com# List of all factories. Contains tuples of (factory, schemes, 6414213Sandreas.sandberg@arm.com# enabled). 6514213Sandreas.sandberg@arm.comall_factories = [] 6614213Sandreas.sandberg@arm.com 6714213Sandreas.sandberg@arm.comdef _url_factory(schemes, enable=True): 6811878Sandreas.sandberg@arm.com """Wrap a plain Python function with URL parsing helpers 6911878Sandreas.sandberg@arm.com 7011878Sandreas.sandberg@arm.com Wrap a plain Python function f(fn, **kwargs) to expect a URL that 7111878Sandreas.sandberg@arm.com has been split using urlparse.urlsplit. First positional argument 7211878Sandreas.sandberg@arm.com is assumed to be a filename, this is created as the concatenation 7311878Sandreas.sandberg@arm.com of the netloc (~hostname) and path in the parsed URL. Keyword 7411878Sandreas.sandberg@arm.com arguments are derived from the query values in the URL. 7511878Sandreas.sandberg@arm.com 7614213Sandreas.sandberg@arm.com Arguments: 7714213Sandreas.sandberg@arm.com schemes: A list of URL schemes to use for this function. 7814213Sandreas.sandberg@arm.com 7914213Sandreas.sandberg@arm.com Keyword arguments: 8014213Sandreas.sandberg@arm.com enable: Enable/disable this factory. Typically used when the 8114213Sandreas.sandberg@arm.com presence of a function depends on some runtime property. 8214213Sandreas.sandberg@arm.com 8311878Sandreas.sandberg@arm.com For example: 8411878Sandreas.sandberg@arm.com wrapped_f(urlparse.urlsplit("text://stats.txt?desc=False")) -> 8511878Sandreas.sandberg@arm.com f("stats.txt", desc=False) 8611878Sandreas.sandberg@arm.com 8711878Sandreas.sandberg@arm.com """ 8811878Sandreas.sandberg@arm.com 8911878Sandreas.sandberg@arm.com from functools import wraps 9011878Sandreas.sandberg@arm.com 9114213Sandreas.sandberg@arm.com def decorator(func): 9214213Sandreas.sandberg@arm.com @wraps(func) 9314213Sandreas.sandberg@arm.com def wrapper(url): 9414213Sandreas.sandberg@arm.com try: 9514213Sandreas.sandberg@arm.com from urllib.parse import parse_qs 9614213Sandreas.sandberg@arm.com except ImportError: 9714213Sandreas.sandberg@arm.com # Python 2 fallback 9814213Sandreas.sandberg@arm.com from urlparse import parse_qs 9914213Sandreas.sandberg@arm.com from ast import literal_eval 10011878Sandreas.sandberg@arm.com 10114213Sandreas.sandberg@arm.com qs = parse_qs(url.query, keep_blank_values=True) 10211878Sandreas.sandberg@arm.com 10314213Sandreas.sandberg@arm.com # parse_qs returns a list of values for each parameter. Only 10414213Sandreas.sandberg@arm.com # use the last value since kwargs don't allow multiple values 10514213Sandreas.sandberg@arm.com # per parameter. Use literal_eval to transform string param 10614213Sandreas.sandberg@arm.com # values into proper Python types. 10714213Sandreas.sandberg@arm.com def parse_value(key, values): 10814213Sandreas.sandberg@arm.com if len(values) == 0 or (len(values) == 1 and not values[0]): 10914213Sandreas.sandberg@arm.com fatal("%s: '%s' doesn't have a value." % ( 11014213Sandreas.sandberg@arm.com url.geturl(), key)) 11114213Sandreas.sandberg@arm.com elif len(values) > 1: 11214213Sandreas.sandberg@arm.com fatal("%s: '%s' has multiple values." % ( 11314213Sandreas.sandberg@arm.com url.geturl(), key)) 11414213Sandreas.sandberg@arm.com else: 11514213Sandreas.sandberg@arm.com try: 11614213Sandreas.sandberg@arm.com return key, literal_eval(values[0]) 11714213Sandreas.sandberg@arm.com except ValueError: 11814213Sandreas.sandberg@arm.com fatal("%s: %s isn't a valid Python literal" \ 11914213Sandreas.sandberg@arm.com % (url.geturl(), values[0])) 12011878Sandreas.sandberg@arm.com 12114213Sandreas.sandberg@arm.com kwargs = dict([ parse_value(k, v) for k, v in qs.items() ]) 12211878Sandreas.sandberg@arm.com 12314213Sandreas.sandberg@arm.com try: 12414213Sandreas.sandberg@arm.com return func("%s%s" % (url.netloc, url.path), **kwargs) 12514213Sandreas.sandberg@arm.com except TypeError: 12614213Sandreas.sandberg@arm.com fatal("Illegal stat visitor parameter specified") 12711878Sandreas.sandberg@arm.com 12814213Sandreas.sandberg@arm.com all_factories.append((wrapper, schemes, enable)) 12914213Sandreas.sandberg@arm.com for scheme in schemes: 13014213Sandreas.sandberg@arm.com assert scheme not in factories 13114213Sandreas.sandberg@arm.com factories[scheme] = wrapper if enable else None 13214213Sandreas.sandberg@arm.com return wrapper 13311878Sandreas.sandberg@arm.com 13414213Sandreas.sandberg@arm.com return decorator 13514213Sandreas.sandberg@arm.com 13614213Sandreas.sandberg@arm.com@_url_factory([ None, "", "text", "file", ]) 13711878Sandreas.sandberg@arm.comdef _textFactory(fn, desc=True): 13811878Sandreas.sandberg@arm.com """Output stats in text format. 13911878Sandreas.sandberg@arm.com 14011878Sandreas.sandberg@arm.com Text stat files contain one stat per line with an optional 14111878Sandreas.sandberg@arm.com description. The description is enabled by default, but can be 14211878Sandreas.sandberg@arm.com disabled by setting the desc parameter to False. 14311878Sandreas.sandberg@arm.com 14414213Sandreas.sandberg@arm.com Parameters: 14514213Sandreas.sandberg@arm.com * desc (bool): Output stat descriptions (default: True) 14614213Sandreas.sandberg@arm.com 14714213Sandreas.sandberg@arm.com Example: 14814213Sandreas.sandberg@arm.com text://stats.txt?desc=False 14911878Sandreas.sandberg@arm.com 15011878Sandreas.sandberg@arm.com """ 15111878Sandreas.sandberg@arm.com 15211878Sandreas.sandberg@arm.com return _m5.stats.initText(fn, desc) 15311878Sandreas.sandberg@arm.com 15414213Sandreas.sandberg@arm.com@_url_factory([ "h5", ], enable=hasattr(_m5.stats, "initHDF5")) 15514209Sandreas.sandberg@arm.comdef _hdf5Factory(fn, chunking=10, desc=True, formulas=True): 15614209Sandreas.sandberg@arm.com """Output stats in HDF5 format. 15714209Sandreas.sandberg@arm.com 15814209Sandreas.sandberg@arm.com The HDF5 file format is a structured binary file format. It has 15914209Sandreas.sandberg@arm.com the multiple benefits over traditional text stat files: 16014209Sandreas.sandberg@arm.com 16114209Sandreas.sandberg@arm.com * Efficient storage of time series (multiple stat dumps) 16214209Sandreas.sandberg@arm.com * Fast lookup of stats 16314209Sandreas.sandberg@arm.com * Plenty of existing tooling (e.g., Python libraries and graphical 16414209Sandreas.sandberg@arm.com viewers) 16514209Sandreas.sandberg@arm.com * File format can be used to store frame buffers together with 16614209Sandreas.sandberg@arm.com normal stats. 16714209Sandreas.sandberg@arm.com 16814209Sandreas.sandberg@arm.com There are some drawbacks compared to the default text format: 16914209Sandreas.sandberg@arm.com * Large startup cost (single stat dump larger than text equivalent) 17014209Sandreas.sandberg@arm.com * Stat dumps are slower than text 17114209Sandreas.sandberg@arm.com 17214209Sandreas.sandberg@arm.com 17314209Sandreas.sandberg@arm.com Known limitations: 17414209Sandreas.sandberg@arm.com * Distributions and histograms currently unsupported. 17514209Sandreas.sandberg@arm.com * No support for forking. 17614209Sandreas.sandberg@arm.com 17714209Sandreas.sandberg@arm.com 17814209Sandreas.sandberg@arm.com Parameters: 17914209Sandreas.sandberg@arm.com * chunking (unsigned): Number of time steps to pre-allocate (default: 10) 18014209Sandreas.sandberg@arm.com * desc (bool): Output stat descriptions (default: True) 18114209Sandreas.sandberg@arm.com * formulas (bool): Output derived stats (default: True) 18214209Sandreas.sandberg@arm.com 18314209Sandreas.sandberg@arm.com Example: 18414209Sandreas.sandberg@arm.com h5://stats.h5?desc=False;chunking=100;formulas=False 18514209Sandreas.sandberg@arm.com 18614209Sandreas.sandberg@arm.com """ 18714209Sandreas.sandberg@arm.com 18814213Sandreas.sandberg@arm.com return _m5.stats.initHDF5(fn, chunking, desc, formulas) 18914209Sandreas.sandberg@arm.com 19011878Sandreas.sandberg@arm.comdef addStatVisitor(url): 19111878Sandreas.sandberg@arm.com """Add a stat visitor specified using a URL string 19211878Sandreas.sandberg@arm.com 19311878Sandreas.sandberg@arm.com Stat visitors are specified using URLs on the following format: 19411878Sandreas.sandberg@arm.com format://path[?param=value[;param=value]] 19511878Sandreas.sandberg@arm.com 19611878Sandreas.sandberg@arm.com The available formats are listed in the factories list. Factories 19711878Sandreas.sandberg@arm.com are called with the path as the first positional parameter and the 19811878Sandreas.sandberg@arm.com parameters are keyword arguments. Parameter values must be valid 19911878Sandreas.sandberg@arm.com Python literals. 20011878Sandreas.sandberg@arm.com 20111878Sandreas.sandberg@arm.com """ 20211878Sandreas.sandberg@arm.com 20313712Sandreas.sandberg@arm.com try: 20413712Sandreas.sandberg@arm.com from urllib.parse import urlsplit 20513712Sandreas.sandberg@arm.com except ImportError: 20613712Sandreas.sandberg@arm.com # Python 2 fallback 20713712Sandreas.sandberg@arm.com from urlparse import urlsplit 20811878Sandreas.sandberg@arm.com 20911878Sandreas.sandberg@arm.com parsed = urlsplit(url) 21011878Sandreas.sandberg@arm.com 21111878Sandreas.sandberg@arm.com try: 21211878Sandreas.sandberg@arm.com factory = factories[parsed.scheme] 21311878Sandreas.sandberg@arm.com except KeyError: 21414213Sandreas.sandberg@arm.com fatal("Illegal stat file type '%s' specified." % parsed.scheme) 21514213Sandreas.sandberg@arm.com 21614213Sandreas.sandberg@arm.com if factory is None: 21714213Sandreas.sandberg@arm.com fatal("Stat type '%s' disabled at compile time" % parsed.scheme) 21811878Sandreas.sandberg@arm.com 21911878Sandreas.sandberg@arm.com outputList.append(factory(parsed)) 2204126SN/A 22114213Sandreas.sandberg@arm.comdef printStatVisitorTypes(): 22214213Sandreas.sandberg@arm.com """List available stat visitors and their documentation""" 22314213Sandreas.sandberg@arm.com 22414213Sandreas.sandberg@arm.com import inspect 22514213Sandreas.sandberg@arm.com 22614213Sandreas.sandberg@arm.com def print_doc(doc): 22714213Sandreas.sandberg@arm.com for line in doc.splitlines(): 22814213Sandreas.sandberg@arm.com print("| %s" % line) 22914213Sandreas.sandberg@arm.com print() 23014213Sandreas.sandberg@arm.com 23114213Sandreas.sandberg@arm.com enabled_visitors = [ x for x in all_factories if x[2] ] 23214213Sandreas.sandberg@arm.com for factory, schemes, _ in enabled_visitors: 23314213Sandreas.sandberg@arm.com print("%s:" % ", ".join(filter(lambda x: x is not None, schemes))) 23414213Sandreas.sandberg@arm.com 23514213Sandreas.sandberg@arm.com # Try to extract the factory doc string 23614213Sandreas.sandberg@arm.com print_doc(inspect.getdoc(factory)) 23714213Sandreas.sandberg@arm.com 2386001SN/Adef initSimStats(): 23911802Sandreas.sandberg@arm.com _m5.stats.initSimStats() 24011802Sandreas.sandberg@arm.com _m5.stats.registerPythonStatsHandlers() 2416001SN/A 24214206Sandreas.sandberg@arm.comdef _visit_groups(visitor, root=None): 24314206Sandreas.sandberg@arm.com if root is None: 24414206Sandreas.sandberg@arm.com root = Root.getInstance() 24514205Sandreas.sandberg@arm.com for group in root.getStatGroups().values(): 24614205Sandreas.sandberg@arm.com visitor(group) 24714206Sandreas.sandberg@arm.com _visit_groups(visitor, root=group) 24814205Sandreas.sandberg@arm.com 24914206Sandreas.sandberg@arm.comdef _visit_stats(visitor, root=None): 25014205Sandreas.sandberg@arm.com def for_each_stat(g): 25114205Sandreas.sandberg@arm.com for stat in g.getStats(): 25214205Sandreas.sandberg@arm.com visitor(g, stat) 25314206Sandreas.sandberg@arm.com _visit_groups(for_each_stat, root=root) 25414205Sandreas.sandberg@arm.com 25514205Sandreas.sandberg@arm.comdef _bindStatHierarchy(root): 25614205Sandreas.sandberg@arm.com def _bind_obj(name, obj): 25714286Sgabeblack@google.com if isNullPointer(obj): 25814286Sgabeblack@google.com return 25914205Sandreas.sandberg@arm.com if m5.SimObject.isSimObjectVector(obj): 26014205Sandreas.sandberg@arm.com for idx, obj in enumerate(obj): 26114205Sandreas.sandberg@arm.com _bind_obj("{}{}".format(name, idx), obj) 26214205Sandreas.sandberg@arm.com else: 26314265Schunchenhsu@google.com # We need this check because not all obj.getCCObject() is an 26414265Schunchenhsu@google.com # instance of Stat::Group. For example, sc_core::sc_module, the C++ 26514265Schunchenhsu@google.com # class of SystemC_ScModule, is not a subclass of Stat::Group. So 26614265Schunchenhsu@google.com # it will cause a type error if obj is a SystemC_ScModule when 26714265Schunchenhsu@google.com # calling addStatGroup(). 26814265Schunchenhsu@google.com if isinstance(obj.getCCObject(), _m5.stats.Group): 26914265Schunchenhsu@google.com parent = root 27014265Schunchenhsu@google.com while parent: 27114265Schunchenhsu@google.com if hasattr(parent, 'addStatGroup'): 27214265Schunchenhsu@google.com parent.addStatGroup(name, obj.getCCObject()) 27314265Schunchenhsu@google.com break 27414265Schunchenhsu@google.com parent = parent.get_parent(); 27514265Schunchenhsu@google.com 27614205Sandreas.sandberg@arm.com _bindStatHierarchy(obj) 27714205Sandreas.sandberg@arm.com 27814205Sandreas.sandberg@arm.com for name, obj in root._children.items(): 27914205Sandreas.sandberg@arm.com _bind_obj(name, obj) 28014205Sandreas.sandberg@arm.com 2818295Snate@binkert.orgnames = [] 2828295Snate@binkert.orgstats_dict = {} 2838295Snate@binkert.orgstats_list = [] 2846001SN/Adef enable(): 2858295Snate@binkert.org '''Enable the statistics package. Before the statistics package is 2868295Snate@binkert.org enabled, all statistics must be created and initialized and once 2878295Snate@binkert.org the package is enabled, no more statistics can be created.''' 2888295Snate@binkert.org 28914205Sandreas.sandberg@arm.com def check_stat(group, stat): 2908296Snate@binkert.org if not stat.check() or not stat.baseCheck(): 29110169SCurtis.Dunham@arm.com fatal("statistic '%s' (%d) was not properly initialized " \ 29210169SCurtis.Dunham@arm.com "by a regStats() function\n", stat.name, stat.id) 2938296Snate@binkert.org 2948296Snate@binkert.org if not (stat.flags & flags.display): 2958296Snate@binkert.org stat.name = "__Stat%06d" % stat.id 2968296Snate@binkert.org 29714205Sandreas.sandberg@arm.com 29814205Sandreas.sandberg@arm.com # Legacy stat 29914205Sandreas.sandberg@arm.com global stats_list 30014205Sandreas.sandberg@arm.com stats_list = list(_m5.stats.statsList()) 30114205Sandreas.sandberg@arm.com 30214205Sandreas.sandberg@arm.com for stat in stats_list: 30314205Sandreas.sandberg@arm.com check_stat(None, stat) 30414205Sandreas.sandberg@arm.com 30513681Sandreas.sandberg@arm.com stats_list.sort(key=lambda s: s.name.split('.')) 3068295Snate@binkert.org for stat in stats_list: 3078295Snate@binkert.org stats_dict[stat.name] = stat 3088296Snate@binkert.org stat.enable() 3098295Snate@binkert.org 31014205Sandreas.sandberg@arm.com 31114205Sandreas.sandberg@arm.com # New stats 31214206Sandreas.sandberg@arm.com _visit_stats(check_stat) 31314206Sandreas.sandberg@arm.com _visit_stats(lambda g, s: s.enable()) 31414205Sandreas.sandberg@arm.com 31511802Sandreas.sandberg@arm.com _m5.stats.enable(); 3168986SAli.Saidi@ARM.com 3178296Snate@binkert.orgdef prepare(): 3188296Snate@binkert.org '''Prepare all stats for data access. This must be done before 3198296Snate@binkert.org dumping and serialization.''' 3206001SN/A 32114205Sandreas.sandberg@arm.com # Legacy stats 3228296Snate@binkert.org for stat in stats_list: 3238296Snate@binkert.org stat.prepare() 3248296Snate@binkert.org 32514205Sandreas.sandberg@arm.com # New stats 32614206Sandreas.sandberg@arm.com _visit_stats(lambda g, s: s.prepare()) 32714205Sandreas.sandberg@arm.com 32814206Sandreas.sandberg@arm.comdef _dump_to_visitor(visitor, root=None): 32914205Sandreas.sandberg@arm.com # Legacy stats 33014206Sandreas.sandberg@arm.com if root is None: 33114206Sandreas.sandberg@arm.com for stat in stats_list: 33214206Sandreas.sandberg@arm.com stat.visit(visitor) 33314205Sandreas.sandberg@arm.com 33414205Sandreas.sandberg@arm.com # New stats 33514205Sandreas.sandberg@arm.com def dump_group(group): 33614205Sandreas.sandberg@arm.com for stat in group.getStats(): 33714205Sandreas.sandberg@arm.com stat.visit(visitor) 33814205Sandreas.sandberg@arm.com 33914205Sandreas.sandberg@arm.com for n, g in group.getStatGroups().items(): 34014205Sandreas.sandberg@arm.com visitor.beginGroup(n) 34114205Sandreas.sandberg@arm.com dump_group(g) 34214205Sandreas.sandberg@arm.com visitor.endGroup() 34314205Sandreas.sandberg@arm.com 34414206Sandreas.sandberg@arm.com if root is not None: 34514206Sandreas.sandberg@arm.com for p in root.path_list(): 34614206Sandreas.sandberg@arm.com visitor.beginGroup(p) 34714206Sandreas.sandberg@arm.com dump_group(root if root is not None else Root.getInstance()) 34814206Sandreas.sandberg@arm.com if root is not None: 34914206Sandreas.sandberg@arm.com for p in reversed(root.path_list()): 35014206Sandreas.sandberg@arm.com visitor.endGroup() 35114205Sandreas.sandberg@arm.com 35214206Sandreas.sandberg@arm.comlastDump = 0 35314205Sandreas.sandberg@arm.com 35414206Sandreas.sandberg@arm.comdef dump(root=None): 3558296Snate@binkert.org '''Dump all statistics data to the registered outputs''' 3566001SN/A 35714206Sandreas.sandberg@arm.com now = m5.curTick() 35814206Sandreas.sandberg@arm.com global lastDump 35914206Sandreas.sandberg@arm.com assert lastDump <= now 36014206Sandreas.sandberg@arm.com new_dump = lastDump != now 36114206Sandreas.sandberg@arm.com lastDump = now 3628296Snate@binkert.org 36314206Sandreas.sandberg@arm.com # Don't allow multiple global stat dumps in the same tick. It's 36414206Sandreas.sandberg@arm.com # still possible to dump a multiple sub-trees. 36514206Sandreas.sandberg@arm.com if not new_dump and root is None: 3668296Snate@binkert.org return 3678296Snate@binkert.org 36814206Sandreas.sandberg@arm.com # Only prepare stats the first time we dump them in the same tick. 36914206Sandreas.sandberg@arm.com if new_dump: 37014206Sandreas.sandberg@arm.com _m5.stats.processDumpQueue() 37114206Sandreas.sandberg@arm.com prepare() 3728296Snate@binkert.org 3738296Snate@binkert.org for output in outputList: 3748296Snate@binkert.org if output.valid(): 3758296Snate@binkert.org output.begin() 37614206Sandreas.sandberg@arm.com _dump_to_visitor(output, root=root) 3778296Snate@binkert.org output.end() 3786001SN/A 3796001SN/Adef reset(): 3808296Snate@binkert.org '''Reset all statistics to the base state''' 3818296Snate@binkert.org 3827527SN/A # call reset stats on all SimObjects 3837527SN/A root = Root.getInstance() 3847802SN/A if root: 38514205Sandreas.sandberg@arm.com root.resetStats() 3867802SN/A 38714205Sandreas.sandberg@arm.com # call any other registered legacy stats reset callbacks 3888296Snate@binkert.org for stat in stats_list: 3898296Snate@binkert.org stat.reset() 3908296Snate@binkert.org 39111802Sandreas.sandberg@arm.com _m5.stats.processResetQueue() 3928295Snate@binkert.org 3938295Snate@binkert.orgflags = attrdict({ 3948295Snate@binkert.org 'none' : 0x0000, 3958295Snate@binkert.org 'init' : 0x0001, 3968295Snate@binkert.org 'display' : 0x0002, 3978295Snate@binkert.org 'total' : 0x0010, 3988295Snate@binkert.org 'pdf' : 0x0020, 3998295Snate@binkert.org 'cdf' : 0x0040, 4008295Snate@binkert.org 'dist' : 0x0080, 4018295Snate@binkert.org 'nozero' : 0x0100, 4028295Snate@binkert.org 'nonan' : 0x0200, 4038295Snate@binkert.org}) 404