master
py 140 lines 5.03 KB
Raw
1 # SPDX-License-Identifier: GPL-2.0-or-later
2
3 """
4 Backend management.
5
6
7 Creating new backends
8 ---------------------
9
10 A new backend named 'foo-bar' corresponds to Python module
11 'tracetool/backend/foo_bar.py'.
12
13 A backend module should provide a docstring, whose first non-empty line will be
14 considered its short description.
15
16 All backends must generate their contents through the 'tracetool.out' routine.
17
18
19 Backend attributes
20 ------------------
21
22 =========================== ====================================================
23 Attribute Description
24 =========================== ====================================================
25 PUBLIC If exists and is set to 'True', the backend is
26 considered "public".
27 CHECK_TRACE_EVENT_GET_STATE If exists and is set to 'True', the backend-specific
28 code inside the tracepoint is emitted within an
29 ``if trace_event_get_state()`` conditional.
30 =========================== ====================================================
31
32
33 Backend functions
34 -----------------
35
36 All the following functions are optional, and no output will be generated if
37 they do not exist.
38
39 =============================== ==============================================
40 Function Description
41 =============================== ==============================================
42 generate_<format>_begin(events) Generate backend- and format-specific file
43 header contents.
44 generate_<format>_end(events) Generate backend- and format-specific file
45 footer contents.
46 generate_<format>(event) Generate backend- and format-specific contents
47 for the given event.
48 =============================== ==============================================
49
50 """
51
52 __author__ = "Lluís Vilanova <vilanova@ac.upc.edu>"
53 __copyright__ = "Copyright 2012-2014, Lluís Vilanova <vilanova@ac.upc.edu>"
54 __license__ = "GPL version 2 or (at your option) any later version"
55
56 __maintainer__ = "Stefan Hajnoczi"
57 __email__ = "stefanha@redhat.com"
58
59
60 import os
61
62 import tracetool
63
64
65 def get_list(only_public = False):
66 """Get a list of (name, description) pairs."""
67 res = [("nop", "Tracing disabled.")]
68 modnames = []
69 for filename in os.listdir(tracetool.backend.__path__[0]):
70 if filename.endswith('.py') and filename != '__init__.py':
71 modnames.append(filename.rsplit('.', 1)[0])
72 for modname in sorted(modnames):
73 module = tracetool.try_import("tracetool.backend." + modname)
74
75 # just in case; should never fail unless non-module files are put there
76 if not module[0]:
77 continue
78 module = module[1]
79
80 public = getattr(module, "PUBLIC", False)
81 if only_public and not public:
82 continue
83
84 doc = module.__doc__
85 if doc is None:
86 doc = ""
87 doc = doc.strip().split("\n")[0]
88
89 name = modname.replace("_", "-")
90 res.append((name, doc))
91 return res
92
93
94 def exists(name):
95 """Return whether the given backend exists."""
96 if len(name) == 0:
97 return False
98 if name == "nop":
99 return True
100 name = name.replace("-", "_")
101 return tracetool.try_import("tracetool.backend." + name)[0]
102
103
104 class Wrapper:
105 def __init__(self, backends, format):
106 self._backends = [backend.replace("-", "_") for backend in backends]
107 self._format = format.replace("-", "_")
108 self.check_trace_event_get_state = False
109 for backend in self._backends:
110 assert exists(backend)
111 assert tracetool.format.exists(self._format)
112 for backend in self.backend_modules():
113 check_trace_event_get_state = getattr(backend, "CHECK_TRACE_EVENT_GET_STATE", False)
114 self.check_trace_event_get_state = self.check_trace_event_get_state or check_trace_event_get_state
115
116 def backend_modules(self):
117 for backend in self._backends:
118 module = tracetool.try_import("tracetool.backend." + backend)[1]
119 if module is not None:
120 yield module
121
122 def _run_function(self, name, *args, check_trace_event_get_state=None, **kwargs):
123 for backend in self.backend_modules():
124 func = getattr(backend, name % self._format, None)
125 if func is not None and \
126 (check_trace_event_get_state is None or
127 check_trace_event_get_state == getattr(backend, 'CHECK_TRACE_EVENT_GET_STATE', False)):
128 func(*args, **kwargs)
129
130 def generate_begin(self, events, group):
131 self._run_function("generate_%s_begin", events, group)
132
133 def generate(self, event, group, check_trace_event_get_state=None):
134 self._run_function("generate_%s", event, group, check_trace_event_get_state=check_trace_event_get_state)
135
136 def generate_backend_dstate(self, event, group):
137 self._run_function("generate_%s_backend_dstate", event, group)
138
139 def generate_end(self, events, group):
140 self._run_function("generate_%s_end", events, group)