Brendan Jackman | e81fdcb | 2017-01-04 17:10:29 +0000 | [diff] [blame] | 1 | # Copyright 2015-2017 ARM Limited |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 2 | # |
Javi Merino | aace7c0 | 2015-08-10 14:10:47 +0100 | [diff] [blame] | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | # you may not use this file except in compliance with the License. |
| 5 | # You may obtain a copy of the License at |
| 6 | # |
| 7 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | # |
| 9 | # Unless required by applicable law or agreed to in writing, software |
| 10 | # distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | # See the License for the specific language governing permissions and |
| 13 | # limitations under the License. |
| 14 | # |
| 15 | |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 16 | |
| 17 | """The idea is to create a wrapper class that |
| 18 | returns a Type of a Class dynamically created based |
| 19 | on the input parameters. Similar to a factory design |
| 20 | pattern |
| 21 | """ |
Javi Merino | 435457c | 2015-08-10 15:59:10 +0100 | [diff] [blame] | 22 | from trappy.base import Base |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 23 | import re |
Javi Merino | 299725a | 2016-03-22 12:29:11 +0000 | [diff] [blame] | 24 | from trappy.ftrace import GenericFTrace |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 25 | |
| 26 | |
Javi Merino | 6f34d90 | 2015-02-21 11:39:09 +0000 | [diff] [blame] | 27 | def default_init(self): |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 28 | """Default Constructor for the |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 29 | Dynamic MetaClass. This is used for |
| 30 | the dynamic object creation in |
| 31 | :mod:`trappy.dynamic.DynamicTypeFactory` |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 32 | """ |
| 33 | |
Javi Merino | c4fbc54 | 2015-11-26 10:20:01 +0000 | [diff] [blame] | 34 | kwords = {} |
| 35 | |
| 36 | try: |
| 37 | kwords["parse_raw"] = self.parse_raw |
| 38 | except AttributeError: |
| 39 | pass |
| 40 | |
| 41 | super(type(self), self).__init__(**kwords) |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 42 | |
| 43 | |
| 44 | class DynamicTypeFactory(type): |
| 45 | |
| 46 | """Override the type class to create |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 47 | a dynamic type on the fly. This Factory |
| 48 | class is used internally by |
Javi Merino | fecb267 | 2015-12-21 18:34:57 +0000 | [diff] [blame] | 49 | :mod:`trappy.dynamic.register_dynamic_ftrace` |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 50 | """ |
| 51 | |
| 52 | def __new__(mcs, name, bases, dct): |
| 53 | """Override the new method""" |
| 54 | return type.__new__(mcs, name, bases, dct) |
| 55 | |
| 56 | def __init__(cls, name, bases, dct): |
| 57 | """Override the constructor""" |
| 58 | super(DynamicTypeFactory, cls).__init__(name, bases, dct) |
| 59 | |
| 60 | |
| 61 | def _get_name(name): |
| 62 | """Internal Method to Change camelcase to |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 63 | underscores. CamelCase -> camel_case |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 64 | """ |
| 65 | return re.sub('(?!^)([A-Z]+)', r'_\1', name).lower() |
| 66 | |
| 67 | |
Javi Merino | fecb267 | 2015-12-21 18:34:57 +0000 | [diff] [blame] | 68 | def register_dynamic_ftrace(class_name, unique_word, scope="all", |
| 69 | parse_raw=False, pivot=None): |
Javi Merino | 299725a | 2016-03-22 12:29:11 +0000 | [diff] [blame] | 70 | """Create a Dynamic FTrace parser and register it with any FTrace parsing classes |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 71 | |
| 72 | :param class_name: The name of the class to be registered |
| 73 | (Should be in CamelCase) |
| 74 | :type class_name: str |
| 75 | |
| 76 | :param unique_word: The unique_word to be matched in the |
| 77 | trace |
| 78 | :type unique_word: str |
| 79 | |
| 80 | :param scope: Registry Scope (Can be used to constrain |
| 81 | the parsing of events and group them together) |
| 82 | :type scope: str |
| 83 | |
Chris Redpath | ef596e5 | 2017-06-17 17:24:12 +0100 | [diff] [blame] | 84 | :param parse_raw: If, true, raw trace output (-r flag) |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 85 | will be used |
| 86 | :type parse_raw: bool |
| 87 | |
Kapileshwar Singh | 8aab693 | 2015-11-19 14:51:22 +0000 | [diff] [blame] | 88 | :param pivot: The data column about which the data can be grouped |
| 89 | :type pivot: str |
| 90 | |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 91 | For example if a new unique word :code:`my_unique_word` has |
| 92 | to be registered with TRAPpy: |
| 93 | :: |
| 94 | |
| 95 | import trappy |
Javi Merino | fecb267 | 2015-12-21 18:34:57 +0000 | [diff] [blame] | 96 | custom_class = trappy.register_dynamic_ftrace("MyEvent", "my_unique_word") |
Javi Merino | c26a323 | 2015-12-11 18:00:30 +0000 | [diff] [blame] | 97 | trace = trappy.FTrace("/path/to/trace_file") |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 98 | |
Javi Merino | c26a323 | 2015-12-11 18:00:30 +0000 | [diff] [blame] | 99 | # New data member created in the ftrace object |
| 100 | trace.my_event |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 101 | |
| 102 | .. note:: The name of the member is :code:`my_event` from **MyEvent** |
| 103 | |
| 104 | |
| 105 | :return: A class object of type :mod:`trappy.base.Base` |
| 106 | """ |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 107 | |
Javi Merino | 1b4aa0c | 2015-12-02 12:24:18 +0000 | [diff] [blame] | 108 | kwords = { |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 109 | "__init__": default_init, |
| 110 | "unique_word": unique_word, |
Kapileshwar Singh | 7a70913 | 2015-03-27 17:45:22 +0000 | [diff] [blame] | 111 | "name": _get_name(class_name), |
Kapileshwar Singh | 8aab693 | 2015-11-19 14:51:22 +0000 | [diff] [blame] | 112 | "parse_raw" : parse_raw, |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 113 | } |
Javi Merino | 1b4aa0c | 2015-12-02 12:24:18 +0000 | [diff] [blame] | 114 | |
| 115 | if pivot: |
| 116 | kwords["pivot"] = pivot |
| 117 | |
| 118 | dyn_class = DynamicTypeFactory(class_name, (Base,), kwords) |
Javi Merino | 299725a | 2016-03-22 12:29:11 +0000 | [diff] [blame] | 119 | GenericFTrace.register_parser(dyn_class, scope) |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 120 | return dyn_class |
| 121 | |
| 122 | |
Javi Merino | 094e742 | 2016-03-22 11:53:55 +0000 | [diff] [blame] | 123 | def register_ftrace_parser(cls, scope="all"): |
Javi Merino | fecb267 | 2015-12-21 18:34:57 +0000 | [diff] [blame] | 124 | """Register a new FTrace parser class implementation |
| 125 | |
| 126 | Should be used when the class has complex helper methods and does |
| 127 | not expect to use the default constructor. |
Kapileshwar Singh | 46b361a | 2015-09-09 14:51:09 +0100 | [diff] [blame] | 128 | |
| 129 | :param cls: The class to be registered for |
| 130 | enabling the parsing of an event in trace |
| 131 | :type cls: :mod:`trappy.base.Base` |
Javi Merino | 094e742 | 2016-03-22 11:53:55 +0000 | [diff] [blame] | 132 | |
| 133 | :param scope: scope of this parser class. The scope can be used |
| 134 | to restrict the parsing done on an individual file. Currently |
| 135 | the only scopes available are "sched", "thermal" or "all" |
| 136 | :type scope: string |
| 137 | |
Kapileshwar Singh | fb8fa1a | 2015-02-11 17:21:04 +0000 | [diff] [blame] | 138 | """ |
| 139 | |
| 140 | # Check the argspec of the class |
Javi Merino | 299725a | 2016-03-22 12:29:11 +0000 | [diff] [blame] | 141 | GenericFTrace.register_parser(cls, scope) |
Javi Merino | b280b4f | 2015-12-22 14:53:24 +0000 | [diff] [blame] | 142 | |
| 143 | def unregister_ftrace_parser(ftrace_parser): |
| 144 | """Unregister an ftrace parser |
| 145 | |
| 146 | :param ftrace_parser: An ftrace parser class that was registered |
| 147 | with register_ftrace_parser() or register_dynamic_ftrace(). |
| 148 | If done with the latter, the cls parameter is the return value |
| 149 | of register_dynamic_ftrace() |
| 150 | :type ftrace_parser: class derived from :mod:`trappy.base.Base` |
| 151 | |
| 152 | """ |
Javi Merino | 299725a | 2016-03-22 12:29:11 +0000 | [diff] [blame] | 153 | GenericFTrace.unregister_parser(ftrace_parser) |