Commit | Line | Data |
---|---|---|
cce547fa PP |
1 | --- |
2 | id: using-tracepoint-classes | |
3 | --- | |
4 | ||
5 | In LTTng-UST, a _tracepoint class_ is a class of tracepoints sharing the | |
6 | same field types and names. A _tracepoint instance_ is one instance of | |
7 | such a declared tracepoint class, with its own event name and tracepoint | |
8 | provider name. | |
9 | ||
10 | What is documented in [Defining tracepoints](#doc-defining-tracepoints) | |
11 | is actually how to declare a _tracepoint class_ and define a | |
12 | _tracepoint instance_ at the same time. Without revealing the internals | |
13 | of LTTng-UST too much, it has to be noted that one serialization | |
14 | function is created for each tracepoint class. A serialization | |
15 | function is responsible for serializing the fields of a tracepoint | |
16 | into a sub-buffer when tracing. For various performance reasons, when | |
17 | your situation requires multiple tracepoints with different names, but | |
18 | with the same fields layout, the best practice is to manually create | |
19 | a tracepoint class and instantiate as many tracepoint instances as | |
20 | needed. One positive effect of such a design, amongst other advantages, | |
47bfcb75 | 21 | is that all tracepoint instances of the same tracepoint class |
cce547fa PP |
22 | reuse the same serialization function, thus reducing cache pollution. |
23 | ||
24 | As an example, here are three tracepoint definitions as we know them: | |
25 | ||
26 | ~~~ c | |
27 | TRACEPOINT_EVENT( | |
28 | my_app, | |
29 | get_account, | |
30 | TP_ARGS( | |
31 | int, userid, | |
32 | size_t, len | |
33 | ), | |
34 | TP_FIELDS( | |
35 | ctf_integer(int, userid, userid) | |
36 | ctf_integer(size_t, len, len) | |
37 | ) | |
38 | ) | |
39 | ||
40 | TRACEPOINT_EVENT( | |
41 | my_app, | |
42 | get_settings, | |
43 | TP_ARGS( | |
44 | int, userid, | |
45 | size_t, len | |
46 | ), | |
47 | TP_FIELDS( | |
48 | ctf_integer(int, userid, userid) | |
49 | ctf_integer(size_t, len, len) | |
50 | ) | |
51 | ) | |
52 | ||
53 | TRACEPOINT_EVENT( | |
54 | my_app, | |
55 | get_transaction, | |
56 | TP_ARGS( | |
57 | int, userid, | |
58 | size_t, len | |
59 | ), | |
60 | TP_FIELDS( | |
61 | ctf_integer(int, userid, userid) | |
62 | ctf_integer(size_t, len, len) | |
63 | ) | |
64 | ) | |
65 | ~~~ | |
66 | ||
67 | In this case, three tracepoint classes are created, with one tracepoint | |
68 | instance for each of them: `get_account`, `get_settings` and | |
69 | `get_transaction`. However, they all share the same field names and | |
70 | types. Declaring one tracepoint class and three tracepoint instances of | |
71 | the latter is a better design choice: | |
72 | ||
73 | ~~~ c | |
74 | /* the tracepoint class */ | |
75 | TRACEPOINT_EVENT_CLASS( | |
76 | /* tracepoint provider name */ | |
77 | my_app, | |
78 | ||
79 | /* tracepoint class name */ | |
80 | my_class, | |
81 | ||
82 | /* arguments */ | |
83 | TP_ARGS( | |
84 | int, userid, | |
85 | size_t, len | |
86 | ), | |
87 | ||
88 | /* fields */ | |
89 | TP_FIELDS( | |
90 | ctf_integer(int, userid, userid) | |
91 | ctf_integer(size_t, len, len) | |
92 | ) | |
93 | ) | |
94 | ||
95 | /* the tracepoint instances */ | |
96 | TRACEPOINT_EVENT_INSTANCE( | |
97 | /* tracepoint provider name */ | |
98 | my_app, | |
99 | ||
100 | /* tracepoint class name */ | |
101 | my_class, | |
102 | ||
103 | /* tracepoint/event name */ | |
104 | get_account, | |
105 | ||
106 | /* arguments */ | |
107 | TP_ARGS( | |
108 | int, userid, | |
109 | size_t, len | |
110 | ) | |
111 | ) | |
112 | TRACEPOINT_EVENT_INSTANCE( | |
113 | my_app, | |
114 | my_class, | |
115 | get_settings, | |
116 | TP_ARGS( | |
117 | int, userid, | |
118 | size_t, len | |
119 | ) | |
120 | ) | |
121 | TRACEPOINT_EVENT_INSTANCE( | |
122 | my_app, | |
123 | my_class, | |
124 | get_transaction, | |
125 | TP_ARGS( | |
126 | int, userid, | |
127 | size_t, len | |
128 | ) | |
129 | ) | |
130 | ~~~ | |
131 | ||
132 | Of course, all those names and `TP_ARGS()` invocations are redundant, | |
133 | but some C preprocessor magic can solve this: | |
134 | ||
135 | ~~~ c | |
136 | #define MY_TRACEPOINT_ARGS \ | |
137 | TP_ARGS( \ | |
138 | int, userid, \ | |
139 | size_t, len \ | |
140 | ) | |
141 | ||
142 | TRACEPOINT_EVENT_CLASS( | |
143 | my_app, | |
144 | my_class, | |
145 | MY_TRACEPOINT_ARGS, | |
146 | TP_FIELDS( | |
147 | ctf_integer(int, userid, userid) | |
148 | ctf_integer(size_t, len, len) | |
149 | ) | |
150 | ) | |
151 | ||
152 | #define MY_APP_TRACEPOINT_INSTANCE(name) \ | |
153 | TRACEPOINT_EVENT_INSTANCE( \ | |
154 | my_app, \ | |
155 | my_class, \ | |
156 | name, \ | |
157 | MY_TRACEPOINT_ARGS \ | |
158 | ) | |
159 | ||
160 | MY_APP_TRACEPOINT_INSTANCE(get_account) | |
161 | MY_APP_TRACEPOINT_INSTANCE(get_settings) | |
162 | MY_APP_TRACEPOINT_INSTANCE(get_transaction) | |
163 | ~~~ |