• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef INCLUDE_PERFETTO_PUBLIC_ABI_DATA_SOURCE_ABI_H_
18 #define INCLUDE_PERFETTO_PUBLIC_ABI_DATA_SOURCE_ABI_H_
19 
20 #include <stdbool.h>
21 #include <stdint.h>
22 
23 #include "perfetto/public/abi/atomic.h"
24 #include "perfetto/public/abi/export.h"
25 #include "perfetto/public/abi/stream_writer_abi.h"
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 // Internal representation of a data source type.
32 struct PerfettoDsImpl;
33 
34 // Internal thread local state of a data source type.
35 struct PerfettoDsTlsImpl;
36 
37 // Internal thread local state of a data source instance used for tracing.
38 struct PerfettoDsTracerImpl;
39 
40 // A global atomic boolean that's always false.
41 extern PERFETTO_SDK_EXPORT PERFETTO_ATOMIC(bool) perfetto_atomic_false;
42 
43 // There can be more than one data source instance for each data source type.
44 // This index identifies one of them.
45 typedef uint32_t PerfettoDsInstanceIndex;
46 
47 // Creates a data source type.
48 //
49 // The data source type needs to be registered later with
50 // PerfettoDsImplRegister().
51 PERFETTO_SDK_EXPORT struct PerfettoDsImpl* PerfettoDsImplCreate(void);
52 
53 // Opaque handle used to perform operations from the OnSetup callback. Unused
54 // for now.
55 struct PerfettoDsOnSetupArgs;
56 
57 // Called when a data source instance of a specific type is created. `ds_config`
58 // points to a serialized perfetto.protos.DataSourceConfig message,
59 // `ds_config_size` bytes long. `user_arg` is the value passed to
60 // PerfettoDsSetCbUserArg(). The return value of this is passed to all other
61 // callbacks (for this data source instance) as `inst_ctx` and can be accessed
62 // during tracing with PerfettoDsImplGetInstanceLocked().
63 //
64 // Can be called from any thread.
65 typedef void* (*PerfettoDsOnSetupCb)(struct PerfettoDsImpl*,
66                                      PerfettoDsInstanceIndex inst_id,
67                                      void* ds_config,
68                                      size_t ds_config_size,
69                                      void* user_arg,
70                                      struct PerfettoDsOnSetupArgs* args);
71 
72 // Opaque handle used to perform operations from the OnSetup callback. Unused
73 // for now.
74 struct PerfettoDsOnStartArgs;
75 
76 // Called when tracing starts for a data source instance. `user_arg` is the
77 // value passed to PerfettoDsSetCbUserArg(). `inst_ctx` is the return
78 // value of PerfettoDsOnSetupCb.
79 //
80 // Can be called from any thread.
81 typedef void (*PerfettoDsOnStartCb)(struct PerfettoDsImpl*,
82                                     PerfettoDsInstanceIndex inst_id,
83                                     void* user_arg,
84                                     void* inst_ctx,
85                                     struct PerfettoDsOnStartArgs* args);
86 
87 // Opaque handle used to perform operations from the OnStop callback.
88 struct PerfettoDsOnStopArgs;
89 
90 // Opaque handle used to signal when the data source stop operation is
91 // complete.
92 struct PerfettoDsAsyncStopper;
93 
94 // Tells the tracing service to postpone the stopping of a data source instance.
95 // The returned handle can be used to signal the tracing service when the data
96 // source instance can be stopped.
97 PERFETTO_SDK_EXPORT struct PerfettoDsAsyncStopper* PerfettoDsOnStopArgsPostpone(
98     struct PerfettoDsOnStopArgs*);
99 
100 // Tells the tracing service to stop a data source instance (whose stop
101 // operation was previously postponed with PerfettoDsOnStopArgsPostpone).
102 PERFETTO_SDK_EXPORT void PerfettoDsStopDone(struct PerfettoDsAsyncStopper*);
103 
104 // Called when tracing stops for a data source instance. `user_arg` is the value
105 // passed to PerfettoDsSetCbUserArg(). `inst_ctx` is the return value of
106 // PerfettoDsOnSetupCb.`args` can be used to postpone stopping this data source
107 // instance. Note that, in general, it's not a good idea to destroy `inst_ctx`
108 // here: PerfettoDsOnDestroyCb should be used instead.
109 //
110 // Can be called from any thread. Blocking this for too long it's not a good
111 // idea and can cause deadlocks. Use PerfettoDsOnStopArgsPostpone() to postpone
112 // disabling the data source instance.
113 typedef void (*PerfettoDsOnStopCb)(struct PerfettoDsImpl*,
114                                    PerfettoDsInstanceIndex inst_id,
115                                    void* user_arg,
116                                    void* inst_ctx,
117                                    struct PerfettoDsOnStopArgs* args);
118 
119 // Called after tracing has been stopped for a data source instance, to signal
120 // that `inst_ctx` (which is the return value of PerfettoDsOnSetupCb) can
121 // potentially be destroyed. `user_arg` is the value passed to
122 // PerfettoDsSetCbUserArg().
123 //
124 // Can be called from any thread.
125 typedef void (*PerfettoDsOnDestroyCb)(struct PerfettoDsImpl*,
126                                       void* user_arg,
127                                       void* inst_ctx);
128 
129 // Opaque handle used to perform operations from the OnFlush callback.
130 struct PerfettoDsOnFlushArgs;
131 
132 // Opaque handle used to signal when the data source flush operation is
133 // complete.
134 struct PerfettoDsAsyncFlusher;
135 
136 // Tells the tracing service to postpone acknowledging the flushing of a data
137 // source instance. The returned handle can be used to signal the tracing
138 // service when the data source instance flushing has completed.
139 PERFETTO_SDK_EXPORT struct PerfettoDsAsyncFlusher*
140 PerfettoDsOnFlushArgsPostpone(struct PerfettoDsOnFlushArgs*);
141 
142 // Tells the tracing service that the flush operation is complete for a data
143 // source instance (whose stop operation was previously postponed with
144 // PerfettoDsOnFlushArgsPostpone).
145 PERFETTO_SDK_EXPORT void PerfettoDsFlushDone(struct PerfettoDsAsyncFlusher*);
146 
147 // Called when the tracing service requires all the pending tracing data to be
148 // flushed for a data source instance. `user_arg` is the value passed to
149 // PerfettoDsSetCbUserArg(). `inst_ctx` is the return value of
150 // PerfettoDsOnSetupCb. `args` can be used to postpone stopping this data source
151 // instance.
152 //
153 // Can be called from any thread. Blocking this for too long it's not a good
154 // idea and can cause deadlocks. Use PerfettoDsOnFlushArgsPostpone() to postpone
155 // disabling the data source instance.
156 typedef void (*PerfettoDsOnFlushCb)(struct PerfettoDsImpl*,
157                                     PerfettoDsInstanceIndex inst_id,
158                                     void* user_arg,
159                                     void* inst_ctx,
160                                     struct PerfettoDsOnFlushArgs* args);
161 
162 // Creates custom state (either thread local state or incremental state) for
163 // instance `inst_id`. `user_arg` is the value passed to
164 // PerfettoDsSetCbUserArg().
165 typedef void* (*PerfettoDsOnCreateCustomState)(
166     struct PerfettoDsImpl*,
167     PerfettoDsInstanceIndex inst_id,
168     struct PerfettoDsTracerImpl* tracer,
169     void* user_arg);
170 
171 // Deletes the previously created custom state `obj`.
172 typedef void (*PerfettoDsOnDeleteCustomState)(void* obj);
173 
174 // Setters for callbacks: can not be called after PerfettoDsImplRegister().
175 
176 PERFETTO_SDK_EXPORT void PerfettoDsSetOnSetupCallback(struct PerfettoDsImpl*,
177                                                       PerfettoDsOnSetupCb);
178 
179 PERFETTO_SDK_EXPORT void PerfettoDsSetOnStartCallback(struct PerfettoDsImpl*,
180                                                       PerfettoDsOnStartCb);
181 
182 PERFETTO_SDK_EXPORT void PerfettoDsSetOnStopCallback(struct PerfettoDsImpl*,
183                                                      PerfettoDsOnStopCb);
184 
185 PERFETTO_SDK_EXPORT void PerfettoDsSetOnDestroyCallback(struct PerfettoDsImpl*,
186                                                         PerfettoDsOnDestroyCb);
187 
188 PERFETTO_SDK_EXPORT void PerfettoDsSetOnFlushCallback(struct PerfettoDsImpl*,
189                                                       PerfettoDsOnFlushCb);
190 
191 // Callbacks for custom per instance thread local state.
192 //
193 // Called from inside a trace point. Trace points inside these will be
194 // ignored.
195 PERFETTO_SDK_EXPORT void PerfettoDsSetOnCreateTls(
196     struct PerfettoDsImpl*,
197     PerfettoDsOnCreateCustomState);
198 PERFETTO_SDK_EXPORT void PerfettoDsSetOnDeleteTls(
199     struct PerfettoDsImpl*,
200     PerfettoDsOnDeleteCustomState);
201 
202 // Callbacks for custom per instance thread local incremental state.
203 //
204 // Called from inside a trace point. Trace points inside these will be
205 // ignored.
206 PERFETTO_SDK_EXPORT void PerfettoDsSetOnCreateIncr(
207     struct PerfettoDsImpl*,
208     PerfettoDsOnCreateCustomState);
209 PERFETTO_SDK_EXPORT void PerfettoDsSetOnDeleteIncr(
210     struct PerfettoDsImpl*,
211     PerfettoDsOnDeleteCustomState);
212 
213 // Stores the `user_arg` that's going to be passed later to the callbacks for
214 // this data source type.
215 PERFETTO_SDK_EXPORT void PerfettoDsSetCbUserArg(struct PerfettoDsImpl*,
216                                                 void* user_arg);
217 
218 enum PerfettoDsBufferExhaustedPolicy {
219   // If the data source runs out of space when trying to acquire a new chunk,
220   // it will drop data.
221   PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP = 0,
222   // If the data source runs out of space when trying to acquire a new chunk,
223   // it will stall, retry and eventually abort if a free chunk is not acquired
224   // after a while.
225   PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT = 1,
226 };
227 
228 // If the data source doesn't find an empty chunk when trying to emit tracing
229 // data, it will behave according to `policy` (which is a `enum
230 // PerfettoDsBufferExhaustedPolicy`).
231 //
232 // Should not be called after PerfettoDsImplRegister().
233 //
234 // Returns true if successful, false otherwise.
235 PERFETTO_SDK_EXPORT bool PerfettoDsSetBufferExhaustedPolicy(
236     struct PerfettoDsImpl*,
237     uint32_t policy);
238 
239 // Registers the `*ds_impl` data source type.
240 //
241 // `ds_impl` must be obtained via a call to `PerfettoDsImplCreate()`.
242 //
243 // `**enabled_ptr` will be set to true when the data source type has been
244 // enabled.
245 //
246 // `descriptor` should point to a serialized
247 // perfetto.protos.DataSourceDescriptor message, `descriptor_size` bytes long.
248 //
249 // Returns `true` in case of success, `false` in case of failure (in which case
250 // `ds_impl is invalid`).
251 PERFETTO_SDK_EXPORT bool PerfettoDsImplRegister(struct PerfettoDsImpl* ds_impl,
252                                                 PERFETTO_ATOMIC(bool) *
253                                                     *enabled_ptr,
254                                                 const void* descriptor,
255                                                 size_t descriptor_size);
256 
257 // Updates the descriptor the `*ds_impl` data source type.
258 //
259 // `descriptor` should point to a serialized
260 // perfetto.protos.DataSourceDescriptor message, `descriptor_size` bytes long.
261 PERFETTO_SDK_EXPORT void PerfettoDsImplUpdateDescriptor(
262     struct PerfettoDsImpl* ds_impl,
263     const void* descriptor,
264     size_t descriptor_size);
265 
266 // Tries to get the `inst_ctx` returned by PerfettoDsOnSetupCb() for the
267 // instance with index `inst_id`.
268 //
269 // If successful, returns a non-null pointer and acquires a lock, which must be
270 // released with PerfettoDsImplReleaseInstanceLocked.
271 //
272 // If unsuccessful (because the instance was destroyed in the meantime) or if
273 // PerfettoDsOnSetupCb() returned a null value, returns null and does not
274 // acquire any lock.
275 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetInstanceLocked(
276     struct PerfettoDsImpl* ds_impl,
277     PerfettoDsInstanceIndex inst_id);
278 
279 // Releases a lock previouly acquired by a PerfettoDsImplGetInstanceLocked()
280 // call, which must have returned a non null value.
281 PERFETTO_SDK_EXPORT void PerfettoDsImplReleaseInstanceLocked(
282     struct PerfettoDsImpl* ds_impl,
283     PerfettoDsInstanceIndex inst_id);
284 
285 // Gets the data source thread local instance custom state created by
286 // the callback passed to `PerfettoDsSetOnCreateTls`.
287 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetCustomTls(
288     struct PerfettoDsImpl* ds_impl,
289     struct PerfettoDsTracerImpl* tracer,
290     PerfettoDsInstanceIndex inst_id);
291 
292 // Gets the data source thread local instance incremental state created by
293 // the callback passed to `PerfettoDsSetOnCreateIncr`.
294 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetIncrementalState(
295     struct PerfettoDsImpl* ds_impl,
296     struct PerfettoDsTracerImpl* tracer,
297     PerfettoDsInstanceIndex inst_id);
298 
299 // Iterator for all the active instances (on this thread) of a data source type.
300 struct PerfettoDsImplTracerIterator {
301   // Instance id.
302   PerfettoDsInstanceIndex inst_id;
303   // Caches a pointer to the internal thread local state of the data source
304   // type.
305   struct PerfettoDsTlsImpl* tls;
306   // Pointer to the object used to output trace packets. When nullptr, the
307   // iteration is over.
308   struct PerfettoDsTracerImpl* tracer;
309 };
310 
311 // Start iterating over all the active instances of the data source type
312 // (`ds_impl`).
313 //
314 // If the returned tracer is not nullptr, the user must continue the iteration
315 // with PerfettoDsImplTraceIterateNext(), until it is. The iteration can
316 // only be interrupted early by calling PerfettoDsImplTraceIterateBreak().
317 PERFETTO_SDK_EXPORT struct PerfettoDsImplTracerIterator
318 PerfettoDsImplTraceIterateBegin(struct PerfettoDsImpl* ds_impl);
319 
320 // Advances the iterator to the next active instance of the data source type
321 // (`ds_impl`).
322 //
323 // The user must call PerfettoDsImplTraceIterateNext(), until it returns a
324 // nullptr tracer. The iteration can only be interrupted early by calling
325 // PerfettoDsImplTraceIterateBreak().
326 PERFETTO_SDK_EXPORT void PerfettoDsImplTraceIterateNext(
327     struct PerfettoDsImpl* ds_impl,
328     struct PerfettoDsImplTracerIterator* iterator);
329 
330 // Prematurely interrupts iteration over all the active instances of the data
331 // source type (`ds_impl`).
332 PERFETTO_SDK_EXPORT void PerfettoDsImplTraceIterateBreak(
333     struct PerfettoDsImpl* ds_impl,
334     struct PerfettoDsImplTracerIterator* iterator);
335 
336 // Creates a new trace packet on `tracer`. Returns a stream writer that can be
337 // used to write data to the packet. The caller must use
338 // PerfettoDsTracerImplPacketEnd() when done.
339 PERFETTO_SDK_EXPORT struct PerfettoStreamWriter PerfettoDsTracerImplPacketBegin(
340     struct PerfettoDsTracerImpl* tracer);
341 
342 // Signals that the trace packets created previously on `tracer` with
343 // PerfettoDsTracerImplBeginPacket(), has been fully written.
344 //
345 // `writer` should point to the writer returned by
346 // PerfettoDsTracerImplBeginPacket() and cannot be used anymore after this call.
347 PERFETTO_SDK_EXPORT void PerfettoDsTracerImplPacketEnd(
348     struct PerfettoDsTracerImpl* tracer,
349     struct PerfettoStreamWriter* writer);
350 
351 // Called when a flush request is complete.
352 typedef void (*PerfettoDsTracerOnFlushCb)(void* user_arg);
353 
354 // Forces a commit of the thread-local tracing data written so far to the
355 // service.
356 //
357 // If `cb` is not NULL, it is called on a dedicated internal thread (with
358 // `user_arg`), when flushing is complete. It may never be called (e.g. if the
359 // tracing service disconnects).
360 //
361 // This is almost never required (tracing data is periodically committed as
362 // trace pages are filled up) and has a non-negligible performance hit.
363 PERFETTO_SDK_EXPORT void PerfettoDsTracerImplFlush(
364     struct PerfettoDsTracerImpl* tracer,
365     PerfettoDsTracerOnFlushCb cb,
366     void* user_arg);
367 
368 #ifdef __cplusplus
369 }
370 #endif
371 
372 #endif  // INCLUDE_PERFETTO_PUBLIC_ABI_DATA_SOURCE_ABI_H_
373