/trappy/dynamic.py
https://github.com/ARM-software/trappy · Python · 157 lines · 113 code · 13 blank · 31 comment · 2 complexity · e7efc4d6c66ff82782c4efd6a5cfb924 MD5 · raw file
- # Copyright 2015-2017 ARM Limited
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- #
- """The idea is to create a wrapper class that
- returns a Type of a Class dynamically created based
- on the input parameters. Similar to a factory design
- pattern
- """
- from __future__ import unicode_literals
- from __future__ import division
- from __future__ import print_function
- from trappy.base import Base
- import re
- from trappy.ftrace import GenericFTrace
- def default_init(self):
- """Default Constructor for the
- Dynamic MetaClass. This is used for
- the dynamic object creation in
- :mod:`trappy.dynamic.DynamicTypeFactory`
- """
- kwords = {}
- try:
- kwords["parse_raw"] = self.parse_raw
- except AttributeError:
- pass
- super(type(self), self).__init__(**kwords)
- class DynamicTypeFactory(type):
- """Override the type class to create
- a dynamic type on the fly. This Factory
- class is used internally by
- :mod:`trappy.dynamic.register_dynamic_ftrace`
- """
- def __new__(mcs, name, bases, dct):
- """Override the new method"""
- return type.__new__(mcs, str(name), bases, dct)
- def __init__(cls, name, bases, dct):
- """Override the constructor"""
- super(DynamicTypeFactory, cls).__init__(name, bases, dct)
- def _get_name(name):
- """Internal Method to Change camelcase to
- underscores. CamelCase -> camel_case
- """
- return re.sub('(?!^)([A-Z]+)', r'_\1', name).lower()
- def register_dynamic_ftrace(class_name, unique_word, scope="all",
- parse_raw=False, pivot=None):
- """Create a Dynamic FTrace parser and register it with any FTrace parsing classes
- :param class_name: The name of the class to be registered
- (Should be in CamelCase)
- :type class_name: str
- :param unique_word: The unique_word to be matched in the
- trace
- :type unique_word: str
- :param scope: Registry Scope (Can be used to constrain
- the parsing of events and group them together)
- :type scope: str
- :param parse_raw: If, true, raw trace output (-r flag)
- will be used
- :type parse_raw: bool
- :param pivot: The data column about which the data can be grouped
- :type pivot: str
- For example if a new unique word :code:`my_unique_word` has
- to be registered with TRAPpy:
- ::
- import trappy
- custom_class = trappy.register_dynamic_ftrace("MyEvent", "my_unique_word")
- trace = trappy.FTrace("/path/to/trace_file")
- # New data member created in the ftrace object
- trace.my_event
- .. note:: The name of the member is :code:`my_event` from **MyEvent**
- :return: A class object of type :mod:`trappy.base.Base`
- """
- kwords = {
- "__init__": default_init,
- "unique_word": unique_word,
- "name": _get_name(class_name),
- "parse_raw" : parse_raw,
- }
- if pivot:
- kwords["pivot"] = pivot
- dyn_class = DynamicTypeFactory(class_name, (Base,), kwords)
- GenericFTrace.register_parser(dyn_class, scope)
- return dyn_class
- def register_ftrace_parser(cls, scope="all"):
- """Register a new FTrace parser class implementation
- Should be used when the class has complex helper methods and does
- not expect to use the default constructor.
- :param cls: The class to be registered for
- enabling the parsing of an event in trace
- :type cls: :mod:`trappy.base.Base`
- :param scope: scope of this parser class. The scope can be used
- to restrict the parsing done on an individual file. Currently
- the only scopes available are "sched", "thermal" or "all"
- :type scope: string
- """
- # Check the argspec of the class
- GenericFTrace.register_parser(cls, scope)
- def unregister_ftrace_parser(ftrace_parser):
- """Unregister an ftrace parser
- :param ftrace_parser: An ftrace parser class that was registered
- with register_ftrace_parser() or register_dynamic_ftrace().
- If done with the latter, the cls parameter is the return value
- of register_dynamic_ftrace()
- :type ftrace_parser: class derived from :mod:`trappy.base.Base`
- """
- GenericFTrace.unregister_parser(ftrace_parser)