| # 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 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, 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) |