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