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 // Called when a data source instance of a specific type is created. `ds_config` 54 // points to a serialized perfetto.protos.DataSourceConfig message, 55 // `ds_config_size` bytes long. `user_arg` is the value passed to 56 // PerfettoDsSetCbUserArg(). 57 typedef void* (*PerfettoDsOnSetupCb)(PerfettoDsInstanceIndex inst_id, 58 void* ds_config, 59 size_t ds_config_size, 60 void* user_arg); 61 62 // Called when tracing starts for a data source instance. `user_arg` is the 63 // value passed to PerfettoDsSetCbUserArg(). `inst_ctx` is the return 64 // value of PerfettoDsOnSetupCb. 65 typedef void (*PerfettoDsOnStartCb)(PerfettoDsInstanceIndex inst_id, 66 void* user_arg, 67 void* inst_ctx); 68 69 // Internal handle used to perform operations from the OnStop callback. 70 struct PerfettoDsOnStopArgs; 71 72 // Internal handle used to signal when the data source stop operation is 73 // complete. 74 struct PerfettoDsAsyncStopper; 75 76 // Tells the tracing service to postpone the stopping of a data source instance. 77 // The returned handle can be used to signal the tracing service when the data 78 // source instance can be stopped. 79 PERFETTO_SDK_EXPORT struct PerfettoDsAsyncStopper* PerfettoDsOnStopArgsPostpone( 80 struct PerfettoDsOnStopArgs*); 81 82 // Tells the tracing service to stop a data source instance (whose stop 83 // operation was previously postponed with PerfettoDsOnStopArgsPostpone). 84 PERFETTO_SDK_EXPORT void PerfettoDsStopDone(struct PerfettoDsAsyncStopper*); 85 86 // Called when tracing stops for a data source instance. `user_arg` is the value 87 // passed to PerfettoDsSetCbUserArg(). `inst_ctx` is the return value of 88 // PerfettoDsOnSetupCb. `args` can be used to postpone stopping this data source 89 // instance. 90 typedef void (*PerfettoDsOnStopCb)(PerfettoDsInstanceIndex inst_id, 91 void* user_arg, 92 void* inst_ctx, 93 struct PerfettoDsOnStopArgs* args); 94 95 // Creates custom state (either thread local state or incremental state) for 96 // instance `inst_id`. `user_arg` is the value passed to 97 // PerfettoDsSetCbUserArg(). 98 typedef void* (*PerfettoDsOnCreateCustomState)( 99 PerfettoDsInstanceIndex inst_id, 100 struct PerfettoDsTracerImpl* tracer, 101 void* user_arg); 102 103 // Deletes the previously created custom state `obj`. 104 typedef void (*PerfettoDsOnDeleteCustomState)(void* obj); 105 106 // Setters for callbacks: can not be called after PerfettoDsImplRegister(). 107 108 PERFETTO_SDK_EXPORT void PerfettoDsSetOnSetupCallback(struct PerfettoDsImpl*, 109 PerfettoDsOnSetupCb); 110 111 PERFETTO_SDK_EXPORT void PerfettoDsSetOnStartCallback(struct PerfettoDsImpl*, 112 PerfettoDsOnStartCb); 113 114 PERFETTO_SDK_EXPORT void PerfettoDsSetOnStopCallback(struct PerfettoDsImpl*, 115 PerfettoDsOnStopCb); 116 117 // Callbacks for custom per instance thread local state. 118 PERFETTO_SDK_EXPORT void PerfettoDsSetOnCreateTls( 119 struct PerfettoDsImpl*, 120 PerfettoDsOnCreateCustomState); 121 122 PERFETTO_SDK_EXPORT void PerfettoDsSetOnDeleteTls( 123 struct PerfettoDsImpl*, 124 PerfettoDsOnDeleteCustomState); 125 126 // Callbacks for custom per instance thread local incremental state. 127 PERFETTO_SDK_EXPORT void PerfettoDsSetOnCreateIncr( 128 struct PerfettoDsImpl*, 129 PerfettoDsOnCreateCustomState); 130 131 PERFETTO_SDK_EXPORT void PerfettoDsSetOnDeleteIncr( 132 struct PerfettoDsImpl*, 133 PerfettoDsOnDeleteCustomState); 134 135 // Stores the `user_arg` that's going to be passed later to the callbacks for 136 // this data source type. 137 PERFETTO_SDK_EXPORT void PerfettoDsSetCbUserArg(struct PerfettoDsImpl*, 138 void* user_arg); 139 140 // Registers the `*ds_impl` data source type. 141 // 142 // `ds_impl` must be obtained via a call to `PerfettoDsImplCreate()`. 143 // 144 // `**enabled_ptr` will be set to true when the data source type has been 145 // enabled. 146 // 147 // `descriptor` should point to a serialized 148 // perfetto.protos.DataSourceDescriptor message, `descriptor_size` bytes long. 149 // 150 // Returns `true` in case of success, `false` in case of failure (in which case 151 // `ds_impl is invalid`). 152 PERFETTO_SDK_EXPORT bool PerfettoDsImplRegister(struct PerfettoDsImpl* ds_impl, 153 PERFETTO_ATOMIC(bool) * 154 *enabled_ptr, 155 const void* descriptor, 156 size_t descriptor_size); 157 158 // Updates the descriptor the `*ds_impl` data source type. 159 // 160 // `descriptor` should point to a serialized 161 // perfetto.protos.DataSourceDescriptor message, `descriptor_size` bytes long. 162 PERFETTO_SDK_EXPORT void PerfettoDsImplUpdateDescriptor( 163 struct PerfettoDsImpl* ds_impl, 164 const void* descriptor, 165 size_t descriptor_size); 166 167 // Tries to get the `inst_ctx` returned by PerfettoDsOnSetupCb() for the 168 // instance with index `inst_id`. 169 // 170 // If successful, returns a non-null pointer and acquires a lock, which must be 171 // released with PerfettoDsImplReleaseInstanceLocked. 172 // 173 // If unsuccessful (because the instance was destroyed in the meantime) or if 174 // PerfettoDsOnSetupCb() returned a null value, returns null and does not 175 // acquire any lock. 176 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetInstanceLocked( 177 struct PerfettoDsImpl* ds_impl, 178 PerfettoDsInstanceIndex inst_id); 179 180 // Releases a lock previouly acquired by a PerfettoDsImplGetInstanceLocked() 181 // call, which must have returned a non null value. 182 PERFETTO_SDK_EXPORT void PerfettoDsImplReleaseInstanceLocked( 183 struct PerfettoDsImpl* ds_impl, 184 PerfettoDsInstanceIndex inst_id); 185 186 // Gets the data source thread local instance custom state created by 187 // the callback passed to `PerfettoDsSetOnCreateTls`. 188 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetCustomTls( 189 struct PerfettoDsImpl* ds_impl, 190 struct PerfettoDsTracerImpl* tracer, 191 PerfettoDsInstanceIndex inst_id); 192 193 // Gets the data source thread local instance incremental state created by 194 // the callback passed to `PerfettoDsSetOnCreateIncr`. 195 PERFETTO_SDK_EXPORT void* PerfettoDsImplGetIncrementalState( 196 struct PerfettoDsImpl* ds_impl, 197 struct PerfettoDsTracerImpl* tracer, 198 PerfettoDsInstanceIndex inst_id); 199 200 // Iterator for all the active instances (on this thread) of a data source type. 201 struct PerfettoDsImplTracerIterator { 202 // Instance id. 203 PerfettoDsInstanceIndex inst_id; 204 // Caches a pointer to the internal thread local state of the data source 205 // type. 206 struct PerfettoDsTlsImpl* tls; 207 // Pointer to the object used to output trace packets. When nullptr, the 208 // iteration is over. 209 struct PerfettoDsTracerImpl* tracer; 210 }; 211 212 // Start iterating over all the active instances of the data source type 213 // (`ds_impl`). 214 // 215 // If the returned tracer is not nullptr, the user must continue the iteration 216 // with PerfettoDsImplTraceIterateNext(), until it is. The iteration can 217 // only be interrupted early by calling PerfettoDsImplTraceIterateBreak(). 218 PERFETTO_SDK_EXPORT struct PerfettoDsImplTracerIterator 219 PerfettoDsImplTraceIterateBegin(struct PerfettoDsImpl* ds_impl); 220 221 // Advances the iterator to the next active instance of the data source type 222 // (`ds_impl`). 223 // 224 // The user must call PerfettoDsImplTraceIterateNext(), until it returns a 225 // nullptr tracer. The iteration can only be interrupted early by calling 226 // PerfettoDsImplTraceIterateBreak(). 227 PERFETTO_SDK_EXPORT void PerfettoDsImplTraceIterateNext( 228 struct PerfettoDsImpl* ds_impl, 229 struct PerfettoDsImplTracerIterator* iterator); 230 231 // Prematurely interrupts iteration over all the active instances of the data 232 // source type (`ds_impl`). 233 PERFETTO_SDK_EXPORT void PerfettoDsImplTraceIterateBreak( 234 struct PerfettoDsImpl* ds_impl, 235 struct PerfettoDsImplTracerIterator* iterator); 236 237 // Creates a new trace packet on `tracer`. Returns a stream writer that can be 238 // used to write data to the packet. The caller must use 239 // PerfettoDsTracerImplPacketEnd() when done. 240 PERFETTO_SDK_EXPORT struct PerfettoStreamWriter PerfettoDsTracerImplPacketBegin( 241 struct PerfettoDsTracerImpl* tracer); 242 243 // Signals that the trace packets created previously on `tracer` with 244 // PerfettoDsTracerImplBeginPacket(), has been fully written. 245 // 246 // `writer` should point to the writer returned by 247 // PerfettoDsTracerImplBeginPacket() and cannot be used anymore after this call. 248 PERFETTO_SDK_EXPORT void PerfettoDsTracerImplPacketEnd( 249 struct PerfettoDsTracerImpl* tracer, 250 struct PerfettoStreamWriter* writer); 251 252 // Called when a flush request is complete. 253 typedef void (*PerfettoDsTracerOnFlushCb)(void* user_arg); 254 255 // Forces a commit of the thread-local tracing data written so far to the 256 // service. 257 // 258 // If `cb` is not NULL, it is called on a dedicated internal thread (with 259 // `user_arg`), when flushing is complete. It may never be called (e.g. if the 260 // tracing service disconnects). 261 // 262 // This is almost never required (tracing data is periodically committed as 263 // trace pages are filled up) and has a non-negligible performance hit. 264 PERFETTO_SDK_EXPORT void PerfettoDsTracerImplFlush( 265 struct PerfettoDsTracerImpl* tracer, 266 PerfettoDsTracerOnFlushCb cb, 267 void* user_arg); 268 269 #ifdef __cplusplus 270 } 271 #endif 272 273 #endif // INCLUDE_PERFETTO_PUBLIC_ABI_DATA_SOURCE_ABI_H_ 274