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