xref: /aosp_15_r20/external/perfetto/src/shared_lib/data_source.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1*6dbdd20aSAndroid Build Coastguard Worker /*
2*6dbdd20aSAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
3*6dbdd20aSAndroid Build Coastguard Worker  *
4*6dbdd20aSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*6dbdd20aSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*6dbdd20aSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*6dbdd20aSAndroid Build Coastguard Worker  *
8*6dbdd20aSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*6dbdd20aSAndroid Build Coastguard Worker  *
10*6dbdd20aSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*6dbdd20aSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*6dbdd20aSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6dbdd20aSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*6dbdd20aSAndroid Build Coastguard Worker  * limitations under the License.
15*6dbdd20aSAndroid Build Coastguard Worker  */
16*6dbdd20aSAndroid Build Coastguard Worker 
17*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/public/abi/data_source_abi.h"
18*6dbdd20aSAndroid Build Coastguard Worker 
19*6dbdd20aSAndroid Build Coastguard Worker #include <bitset>
20*6dbdd20aSAndroid Build Coastguard Worker 
21*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/base/thread_annotations.h"
22*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/buffer_exhausted_policy.h"
23*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/data_source.h"
24*6dbdd20aSAndroid Build Coastguard Worker #include "perfetto/tracing/internal/basic_types.h"
25*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/common/data_source_descriptor.gen.h"
26*6dbdd20aSAndroid Build Coastguard Worker #include "protos/perfetto/config/data_source_config.gen.h"
27*6dbdd20aSAndroid Build Coastguard Worker #include "src/shared_lib/reset_for_testing.h"
28*6dbdd20aSAndroid Build Coastguard Worker #include "src/shared_lib/stream_writer.h"
29*6dbdd20aSAndroid Build Coastguard Worker 
30*6dbdd20aSAndroid Build Coastguard Worker namespace {
31*6dbdd20aSAndroid Build Coastguard Worker 
32*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::internal::DataSourceInstanceThreadLocalState;
33*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::internal::DataSourceThreadLocalState;
34*6dbdd20aSAndroid Build Coastguard Worker using ::perfetto::internal::DataSourceType;
35*6dbdd20aSAndroid Build Coastguard Worker 
36*6dbdd20aSAndroid Build Coastguard Worker thread_local DataSourceThreadLocalState*
37*6dbdd20aSAndroid Build Coastguard Worker     g_tls_cache[perfetto::internal::kMaxDataSources];
38*6dbdd20aSAndroid Build Coastguard Worker 
39*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
40*6dbdd20aSAndroid Build Coastguard Worker 
41*6dbdd20aSAndroid Build Coastguard Worker // Implementation of a shared library data source type (there's one of these per
42*6dbdd20aSAndroid Build Coastguard Worker // type, not per instance).
43*6dbdd20aSAndroid Build Coastguard Worker //
44*6dbdd20aSAndroid Build Coastguard Worker // Returned to the C side when invoking PerfettoDsCreateImpl(). The C side only
45*6dbdd20aSAndroid Build Coastguard Worker // has an opaque pointer to this.
46*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoDsImpl {
47*6dbdd20aSAndroid Build Coastguard Worker   // Instance lifecycle callbacks.
48*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnSetupCb on_setup_cb = nullptr;
49*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnStartCb on_start_cb = nullptr;
50*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnStopCb on_stop_cb = nullptr;
51*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnDestroyCb on_destroy_cb = nullptr;
52*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnFlushCb on_flush_cb = nullptr;
53*6dbdd20aSAndroid Build Coastguard Worker 
54*6dbdd20aSAndroid Build Coastguard Worker   // These are called to create/delete custom thread-local instance state.
55*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnCreateCustomState on_create_tls_cb = nullptr;
56*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnDeleteCustomState on_delete_tls_cb = nullptr;
57*6dbdd20aSAndroid Build Coastguard Worker 
58*6dbdd20aSAndroid Build Coastguard Worker   // These are called to create/delete custom thread-local instance incremental
59*6dbdd20aSAndroid Build Coastguard Worker   // state.
60*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnCreateCustomState on_create_incr_cb = nullptr;
61*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsOnDeleteCustomState on_delete_incr_cb = nullptr;
62*6dbdd20aSAndroid Build Coastguard Worker 
63*6dbdd20aSAndroid Build Coastguard Worker   // Passed to all the callbacks as the `user_arg` param.
64*6dbdd20aSAndroid Build Coastguard Worker   void* cb_user_arg;
65*6dbdd20aSAndroid Build Coastguard Worker 
66*6dbdd20aSAndroid Build Coastguard Worker   perfetto::BufferExhaustedPolicy buffer_exhausted_policy =
67*6dbdd20aSAndroid Build Coastguard Worker       perfetto::BufferExhaustedPolicy::kDrop;
68*6dbdd20aSAndroid Build Coastguard Worker 
69*6dbdd20aSAndroid Build Coastguard Worker   DataSourceType cpp_type;
70*6dbdd20aSAndroid Build Coastguard Worker   std::atomic<bool> enabled{false};
71*6dbdd20aSAndroid Build Coastguard Worker   std::mutex mu;
72*6dbdd20aSAndroid Build Coastguard Worker   std::bitset<perfetto::internal::kMaxDataSourceInstances> enabled_instances
73*6dbdd20aSAndroid Build Coastguard Worker       PERFETTO_GUARDED_BY(mu);
74*6dbdd20aSAndroid Build Coastguard Worker 
IsRegisteredPerfettoDsImpl75*6dbdd20aSAndroid Build Coastguard Worker   bool IsRegistered() {
76*6dbdd20aSAndroid Build Coastguard Worker     return cpp_type.static_state()->index !=
77*6dbdd20aSAndroid Build Coastguard Worker            perfetto::internal::kMaxDataSources;
78*6dbdd20aSAndroid Build Coastguard Worker   }
79*6dbdd20aSAndroid Build Coastguard Worker };
80*6dbdd20aSAndroid Build Coastguard Worker 
81*6dbdd20aSAndroid Build Coastguard Worker namespace perfetto {
82*6dbdd20aSAndroid Build Coastguard Worker namespace shlib {
83*6dbdd20aSAndroid Build Coastguard Worker 
84*6dbdd20aSAndroid Build Coastguard Worker // These are only exposed to tests.
85*6dbdd20aSAndroid Build Coastguard Worker 
ResetDataSourceTls()86*6dbdd20aSAndroid Build Coastguard Worker void ResetDataSourceTls() {
87*6dbdd20aSAndroid Build Coastguard Worker   memset(g_tls_cache, 0, sizeof(g_tls_cache));
88*6dbdd20aSAndroid Build Coastguard Worker }
89*6dbdd20aSAndroid Build Coastguard Worker 
DsImplDestroy(struct PerfettoDsImpl * ds_impl)90*6dbdd20aSAndroid Build Coastguard Worker void DsImplDestroy(struct PerfettoDsImpl* ds_impl) {
91*6dbdd20aSAndroid Build Coastguard Worker   delete ds_impl;
92*6dbdd20aSAndroid Build Coastguard Worker }
93*6dbdd20aSAndroid Build Coastguard Worker 
94*6dbdd20aSAndroid Build Coastguard Worker }  // namespace shlib
95*6dbdd20aSAndroid Build Coastguard Worker }  // namespace perfetto
96*6dbdd20aSAndroid Build Coastguard Worker 
97*6dbdd20aSAndroid Build Coastguard Worker namespace {
98*6dbdd20aSAndroid Build Coastguard Worker 
99*6dbdd20aSAndroid Build Coastguard Worker // Represents a global data source instance (there can be more than one of these
100*6dbdd20aSAndroid Build Coastguard Worker // for a single data source type).
101*6dbdd20aSAndroid Build Coastguard Worker class ShlibDataSource : public perfetto::DataSourceBase {
102*6dbdd20aSAndroid Build Coastguard Worker  public:
ShlibDataSource(PerfettoDsImpl * type)103*6dbdd20aSAndroid Build Coastguard Worker   explicit ShlibDataSource(PerfettoDsImpl* type) : type_(*type) {}
104*6dbdd20aSAndroid Build Coastguard Worker 
OnSetup(const SetupArgs & args)105*6dbdd20aSAndroid Build Coastguard Worker   void OnSetup(const SetupArgs& args) override {
106*6dbdd20aSAndroid Build Coastguard Worker     if (type_.on_setup_cb) {
107*6dbdd20aSAndroid Build Coastguard Worker       std::vector<uint8_t> serialized_config = args.config->SerializeAsArray();
108*6dbdd20aSAndroid Build Coastguard Worker       inst_ctx_ = type_.on_setup_cb(
109*6dbdd20aSAndroid Build Coastguard Worker           &type_, args.internal_instance_index, serialized_config.data(),
110*6dbdd20aSAndroid Build Coastguard Worker           serialized_config.size(), type_.cb_user_arg, nullptr);
111*6dbdd20aSAndroid Build Coastguard Worker     }
112*6dbdd20aSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(type_.mu);
113*6dbdd20aSAndroid Build Coastguard Worker     const bool was_enabled = type_.enabled_instances.any();
114*6dbdd20aSAndroid Build Coastguard Worker     type_.enabled_instances.set(args.internal_instance_index);
115*6dbdd20aSAndroid Build Coastguard Worker     if (!was_enabled && type_.enabled_instances.any()) {
116*6dbdd20aSAndroid Build Coastguard Worker       type_.enabled.store(true, std::memory_order_release);
117*6dbdd20aSAndroid Build Coastguard Worker     }
118*6dbdd20aSAndroid Build Coastguard Worker   }
119*6dbdd20aSAndroid Build Coastguard Worker 
OnStart(const StartArgs & args)120*6dbdd20aSAndroid Build Coastguard Worker   void OnStart(const StartArgs& args) override {
121*6dbdd20aSAndroid Build Coastguard Worker     if (type_.on_start_cb) {
122*6dbdd20aSAndroid Build Coastguard Worker       type_.on_start_cb(&type_, args.internal_instance_index, type_.cb_user_arg,
123*6dbdd20aSAndroid Build Coastguard Worker                         inst_ctx_, nullptr);
124*6dbdd20aSAndroid Build Coastguard Worker     }
125*6dbdd20aSAndroid Build Coastguard Worker   }
126*6dbdd20aSAndroid Build Coastguard Worker 
OnStop(const StopArgs & args)127*6dbdd20aSAndroid Build Coastguard Worker   void OnStop(const StopArgs& args) override {
128*6dbdd20aSAndroid Build Coastguard Worker     if (type_.on_stop_cb) {
129*6dbdd20aSAndroid Build Coastguard Worker       type_.on_stop_cb(
130*6dbdd20aSAndroid Build Coastguard Worker           &type_, args.internal_instance_index, type_.cb_user_arg, inst_ctx_,
131*6dbdd20aSAndroid Build Coastguard Worker           const_cast<PerfettoDsOnStopArgs*>(
132*6dbdd20aSAndroid Build Coastguard Worker               reinterpret_cast<const PerfettoDsOnStopArgs*>(&args)));
133*6dbdd20aSAndroid Build Coastguard Worker     }
134*6dbdd20aSAndroid Build Coastguard Worker 
135*6dbdd20aSAndroid Build Coastguard Worker     std::lock_guard<std::mutex> lock(type_.mu);
136*6dbdd20aSAndroid Build Coastguard Worker     type_.enabled_instances.reset(args.internal_instance_index);
137*6dbdd20aSAndroid Build Coastguard Worker     if (type_.enabled_instances.none()) {
138*6dbdd20aSAndroid Build Coastguard Worker       type_.enabled.store(false, std::memory_order_release);
139*6dbdd20aSAndroid Build Coastguard Worker     }
140*6dbdd20aSAndroid Build Coastguard Worker   }
141*6dbdd20aSAndroid Build Coastguard Worker 
~ShlibDataSource()142*6dbdd20aSAndroid Build Coastguard Worker   ~ShlibDataSource() override {
143*6dbdd20aSAndroid Build Coastguard Worker     if (type_.on_destroy_cb) {
144*6dbdd20aSAndroid Build Coastguard Worker       type_.on_destroy_cb(&type_, type_.cb_user_arg, inst_ctx_);
145*6dbdd20aSAndroid Build Coastguard Worker     }
146*6dbdd20aSAndroid Build Coastguard Worker   }
147*6dbdd20aSAndroid Build Coastguard Worker 
OnFlush(const FlushArgs & args)148*6dbdd20aSAndroid Build Coastguard Worker   void OnFlush(const FlushArgs& args) override {
149*6dbdd20aSAndroid Build Coastguard Worker     if (type_.on_flush_cb) {
150*6dbdd20aSAndroid Build Coastguard Worker       type_.on_flush_cb(
151*6dbdd20aSAndroid Build Coastguard Worker           &type_, args.internal_instance_index, type_.cb_user_arg, inst_ctx_,
152*6dbdd20aSAndroid Build Coastguard Worker           const_cast<PerfettoDsOnFlushArgs*>(
153*6dbdd20aSAndroid Build Coastguard Worker               reinterpret_cast<const PerfettoDsOnFlushArgs*>(&args)));
154*6dbdd20aSAndroid Build Coastguard Worker     }
155*6dbdd20aSAndroid Build Coastguard Worker   }
156*6dbdd20aSAndroid Build Coastguard Worker 
type() const157*6dbdd20aSAndroid Build Coastguard Worker   const PerfettoDsImpl& type() const { return type_; }
158*6dbdd20aSAndroid Build Coastguard Worker 
inst_ctx() const159*6dbdd20aSAndroid Build Coastguard Worker   void* inst_ctx() const { return inst_ctx_; }
160*6dbdd20aSAndroid Build Coastguard Worker 
161*6dbdd20aSAndroid Build Coastguard Worker  private:
162*6dbdd20aSAndroid Build Coastguard Worker   PerfettoDsImpl& type_;
163*6dbdd20aSAndroid Build Coastguard Worker   void* inst_ctx_ = nullptr;
164*6dbdd20aSAndroid Build Coastguard Worker };
165*6dbdd20aSAndroid Build Coastguard Worker 
166*6dbdd20aSAndroid Build Coastguard Worker struct DataSourceTraits {
GetDataSourceTLS__anon6a750b700211::DataSourceTraits167*6dbdd20aSAndroid Build Coastguard Worker   static DataSourceThreadLocalState* GetDataSourceTLS(
168*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::DataSourceStaticState* static_state,
169*6dbdd20aSAndroid Build Coastguard Worker       perfetto::internal::TracingTLS* root_tls) {
170*6dbdd20aSAndroid Build Coastguard Worker     auto* ds_tls = &root_tls->data_sources_tls[static_state->index];
171*6dbdd20aSAndroid Build Coastguard Worker     // ds_tls->static_state can be:
172*6dbdd20aSAndroid Build Coastguard Worker     // * nullptr
173*6dbdd20aSAndroid Build Coastguard Worker     // * equal to static_state
174*6dbdd20aSAndroid Build Coastguard Worker     // * equal to the static state of a different data source, in tests (when
175*6dbdd20aSAndroid Build Coastguard Worker     //   ResetForTesting() has been used)
176*6dbdd20aSAndroid Build Coastguard Worker     // In any case, there's no need to do anything, the caller will reinitialize
177*6dbdd20aSAndroid Build Coastguard Worker     // static_state.
178*6dbdd20aSAndroid Build Coastguard Worker     return ds_tls;
179*6dbdd20aSAndroid Build Coastguard Worker   }
180*6dbdd20aSAndroid Build Coastguard Worker };
181*6dbdd20aSAndroid Build Coastguard Worker 
182*6dbdd20aSAndroid Build Coastguard Worker struct TracePointTraits {
183*6dbdd20aSAndroid Build Coastguard Worker   using TracePointData = DataSourceType*;
GetActiveInstances__anon6a750b700211::TracePointTraits184*6dbdd20aSAndroid Build Coastguard Worker   static std::atomic<uint32_t>* GetActiveInstances(TracePointData s) {
185*6dbdd20aSAndroid Build Coastguard Worker     return s->valid_instances();
186*6dbdd20aSAndroid Build Coastguard Worker   }
187*6dbdd20aSAndroid Build Coastguard Worker };
188*6dbdd20aSAndroid Build Coastguard Worker 
CreateShlibTls(DataSourceInstanceThreadLocalState * tls_inst,uint32_t inst_idx,void * ctx)189*6dbdd20aSAndroid Build Coastguard Worker DataSourceInstanceThreadLocalState::ObjectWithDeleter CreateShlibTls(
190*6dbdd20aSAndroid Build Coastguard Worker     DataSourceInstanceThreadLocalState* tls_inst,
191*6dbdd20aSAndroid Build Coastguard Worker     uint32_t inst_idx,
192*6dbdd20aSAndroid Build Coastguard Worker     void* ctx) {
193*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_impl = reinterpret_cast<PerfettoDsImpl*>(ctx);
194*6dbdd20aSAndroid Build Coastguard Worker 
195*6dbdd20aSAndroid Build Coastguard Worker   void* custom_state = ds_impl->on_create_tls_cb(
196*6dbdd20aSAndroid Build Coastguard Worker       ds_impl, inst_idx, reinterpret_cast<PerfettoDsTracerImpl*>(tls_inst),
197*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->cb_user_arg);
198*6dbdd20aSAndroid Build Coastguard Worker   return DataSourceInstanceThreadLocalState::ObjectWithDeleter(
199*6dbdd20aSAndroid Build Coastguard Worker       custom_state, ds_impl->on_delete_tls_cb);
200*6dbdd20aSAndroid Build Coastguard Worker }
201*6dbdd20aSAndroid Build Coastguard Worker 
202*6dbdd20aSAndroid Build Coastguard Worker DataSourceInstanceThreadLocalState::ObjectWithDeleter
CreateShlibIncrementalState(DataSourceInstanceThreadLocalState * tls_inst,uint32_t inst_idx,void * ctx)203*6dbdd20aSAndroid Build Coastguard Worker CreateShlibIncrementalState(DataSourceInstanceThreadLocalState* tls_inst,
204*6dbdd20aSAndroid Build Coastguard Worker                             uint32_t inst_idx,
205*6dbdd20aSAndroid Build Coastguard Worker                             void* ctx) {
206*6dbdd20aSAndroid Build Coastguard Worker   auto* ds_impl = reinterpret_cast<PerfettoDsImpl*>(ctx);
207*6dbdd20aSAndroid Build Coastguard Worker 
208*6dbdd20aSAndroid Build Coastguard Worker   void* custom_state = ds_impl->on_create_incr_cb(
209*6dbdd20aSAndroid Build Coastguard Worker       ds_impl, inst_idx, reinterpret_cast<PerfettoDsTracerImpl*>(tls_inst),
210*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->cb_user_arg);
211*6dbdd20aSAndroid Build Coastguard Worker   return DataSourceInstanceThreadLocalState::ObjectWithDeleter(
212*6dbdd20aSAndroid Build Coastguard Worker       custom_state, ds_impl->on_delete_incr_cb);
213*6dbdd20aSAndroid Build Coastguard Worker }
214*6dbdd20aSAndroid Build Coastguard Worker 
215*6dbdd20aSAndroid Build Coastguard Worker }  // namespace
216*6dbdd20aSAndroid Build Coastguard Worker 
217*6dbdd20aSAndroid Build Coastguard Worker // Exposed through data_source_abi.h
218*6dbdd20aSAndroid Build Coastguard Worker std::atomic<bool> perfetto_atomic_false{false};
219*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplCreate()220*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoDsImpl* PerfettoDsImplCreate() {
221*6dbdd20aSAndroid Build Coastguard Worker   return new PerfettoDsImpl();
222*6dbdd20aSAndroid Build Coastguard Worker }
223*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnSetupCallback(struct PerfettoDsImpl * ds_impl,PerfettoDsOnSetupCb cb)224*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnSetupCallback(struct PerfettoDsImpl* ds_impl,
225*6dbdd20aSAndroid Build Coastguard Worker                                   PerfettoDsOnSetupCb cb) {
226*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
227*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_setup_cb = cb;
228*6dbdd20aSAndroid Build Coastguard Worker }
229*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnStartCallback(struct PerfettoDsImpl * ds_impl,PerfettoDsOnStartCb cb)230*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnStartCallback(struct PerfettoDsImpl* ds_impl,
231*6dbdd20aSAndroid Build Coastguard Worker                                   PerfettoDsOnStartCb cb) {
232*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
233*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_start_cb = cb;
234*6dbdd20aSAndroid Build Coastguard Worker }
235*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnStopCallback(struct PerfettoDsImpl * ds_impl,PerfettoDsOnStopCb cb)236*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnStopCallback(struct PerfettoDsImpl* ds_impl,
237*6dbdd20aSAndroid Build Coastguard Worker                                  PerfettoDsOnStopCb cb) {
238*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
239*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_stop_cb = cb;
240*6dbdd20aSAndroid Build Coastguard Worker }
241*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnDestroyCallback(struct PerfettoDsImpl * ds_impl,PerfettoDsOnDestroyCb cb)242*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnDestroyCallback(struct PerfettoDsImpl* ds_impl,
243*6dbdd20aSAndroid Build Coastguard Worker                                     PerfettoDsOnDestroyCb cb) {
244*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
245*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_destroy_cb = cb;
246*6dbdd20aSAndroid Build Coastguard Worker }
247*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnFlushCallback(struct PerfettoDsImpl * ds_impl,PerfettoDsOnFlushCb cb)248*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnFlushCallback(struct PerfettoDsImpl* ds_impl,
249*6dbdd20aSAndroid Build Coastguard Worker                                   PerfettoDsOnFlushCb cb) {
250*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
251*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_flush_cb = cb;
252*6dbdd20aSAndroid Build Coastguard Worker }
253*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnCreateTls(struct PerfettoDsImpl * ds_impl,PerfettoDsOnCreateCustomState cb)254*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnCreateTls(struct PerfettoDsImpl* ds_impl,
255*6dbdd20aSAndroid Build Coastguard Worker                               PerfettoDsOnCreateCustomState cb) {
256*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
257*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_create_tls_cb = cb;
258*6dbdd20aSAndroid Build Coastguard Worker }
259*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnDeleteTls(struct PerfettoDsImpl * ds_impl,PerfettoDsOnDeleteCustomState cb)260*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnDeleteTls(struct PerfettoDsImpl* ds_impl,
261*6dbdd20aSAndroid Build Coastguard Worker                               PerfettoDsOnDeleteCustomState cb) {
262*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
263*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_delete_tls_cb = cb;
264*6dbdd20aSAndroid Build Coastguard Worker }
265*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnCreateIncr(struct PerfettoDsImpl * ds_impl,PerfettoDsOnCreateCustomState cb)266*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnCreateIncr(struct PerfettoDsImpl* ds_impl,
267*6dbdd20aSAndroid Build Coastguard Worker                                PerfettoDsOnCreateCustomState cb) {
268*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
269*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_create_incr_cb = cb;
270*6dbdd20aSAndroid Build Coastguard Worker }
271*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetOnDeleteIncr(struct PerfettoDsImpl * ds_impl,PerfettoDsOnDeleteCustomState cb)272*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetOnDeleteIncr(struct PerfettoDsImpl* ds_impl,
273*6dbdd20aSAndroid Build Coastguard Worker                                PerfettoDsOnDeleteCustomState cb) {
274*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
275*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->on_delete_incr_cb = cb;
276*6dbdd20aSAndroid Build Coastguard Worker }
277*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetCbUserArg(struct PerfettoDsImpl * ds_impl,void * user_arg)278*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsSetCbUserArg(struct PerfettoDsImpl* ds_impl, void* user_arg) {
279*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_CHECK(!ds_impl->IsRegistered());
280*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->cb_user_arg = user_arg;
281*6dbdd20aSAndroid Build Coastguard Worker }
282*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsSetBufferExhaustedPolicy(struct PerfettoDsImpl * ds_impl,uint32_t policy)283*6dbdd20aSAndroid Build Coastguard Worker bool PerfettoDsSetBufferExhaustedPolicy(struct PerfettoDsImpl* ds_impl,
284*6dbdd20aSAndroid Build Coastguard Worker                                         uint32_t policy) {
285*6dbdd20aSAndroid Build Coastguard Worker   if (ds_impl->IsRegistered()) {
286*6dbdd20aSAndroid Build Coastguard Worker     return false;
287*6dbdd20aSAndroid Build Coastguard Worker   }
288*6dbdd20aSAndroid Build Coastguard Worker 
289*6dbdd20aSAndroid Build Coastguard Worker   switch (policy) {
290*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_DROP:
291*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->buffer_exhausted_policy = perfetto::BufferExhaustedPolicy::kDrop;
292*6dbdd20aSAndroid Build Coastguard Worker       return true;
293*6dbdd20aSAndroid Build Coastguard Worker     case PERFETTO_DS_BUFFER_EXHAUSTED_POLICY_STALL_AND_ABORT:
294*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->buffer_exhausted_policy =
295*6dbdd20aSAndroid Build Coastguard Worker           perfetto::BufferExhaustedPolicy::kStall;
296*6dbdd20aSAndroid Build Coastguard Worker       return true;
297*6dbdd20aSAndroid Build Coastguard Worker   }
298*6dbdd20aSAndroid Build Coastguard Worker   return false;
299*6dbdd20aSAndroid Build Coastguard Worker }
300*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplRegister(struct PerfettoDsImpl * ds_impl,PERFETTO_ATOMIC (bool)** enabled_ptr,const void * descriptor,size_t descriptor_size)301*6dbdd20aSAndroid Build Coastguard Worker bool PerfettoDsImplRegister(struct PerfettoDsImpl* ds_impl,
302*6dbdd20aSAndroid Build Coastguard Worker                             PERFETTO_ATOMIC(bool) * *enabled_ptr,
303*6dbdd20aSAndroid Build Coastguard Worker                             const void* descriptor,
304*6dbdd20aSAndroid Build Coastguard Worker                             size_t descriptor_size) {
305*6dbdd20aSAndroid Build Coastguard Worker   std::unique_ptr<PerfettoDsImpl> data_source_type(ds_impl);
306*6dbdd20aSAndroid Build Coastguard Worker 
307*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
308*6dbdd20aSAndroid Build Coastguard Worker   dsd.ParseFromArray(descriptor, descriptor_size);
309*6dbdd20aSAndroid Build Coastguard Worker 
310*6dbdd20aSAndroid Build Coastguard Worker   auto factory = [ds_impl]() {
311*6dbdd20aSAndroid Build Coastguard Worker     return std::unique_ptr<perfetto::DataSourceBase>(
312*6dbdd20aSAndroid Build Coastguard Worker         new ShlibDataSource(ds_impl));
313*6dbdd20aSAndroid Build Coastguard Worker   };
314*6dbdd20aSAndroid Build Coastguard Worker 
315*6dbdd20aSAndroid Build Coastguard Worker   DataSourceType::CreateCustomTlsFn create_custom_tls_fn = nullptr;
316*6dbdd20aSAndroid Build Coastguard Worker   DataSourceType::CreateIncrementalStateFn create_incremental_state_fn =
317*6dbdd20aSAndroid Build Coastguard Worker       nullptr;
318*6dbdd20aSAndroid Build Coastguard Worker   void* cb_ctx = nullptr;
319*6dbdd20aSAndroid Build Coastguard Worker   if (data_source_type->on_create_incr_cb &&
320*6dbdd20aSAndroid Build Coastguard Worker       data_source_type->on_delete_incr_cb) {
321*6dbdd20aSAndroid Build Coastguard Worker     create_incremental_state_fn = CreateShlibIncrementalState;
322*6dbdd20aSAndroid Build Coastguard Worker     cb_ctx = data_source_type.get();
323*6dbdd20aSAndroid Build Coastguard Worker   }
324*6dbdd20aSAndroid Build Coastguard Worker   if (data_source_type->on_create_tls_cb &&
325*6dbdd20aSAndroid Build Coastguard Worker       data_source_type->on_delete_tls_cb) {
326*6dbdd20aSAndroid Build Coastguard Worker     create_custom_tls_fn = CreateShlibTls;
327*6dbdd20aSAndroid Build Coastguard Worker     cb_ctx = data_source_type.get();
328*6dbdd20aSAndroid Build Coastguard Worker   }
329*6dbdd20aSAndroid Build Coastguard Worker 
330*6dbdd20aSAndroid Build Coastguard Worker   perfetto::internal::DataSourceParams params;
331*6dbdd20aSAndroid Build Coastguard Worker   params.supports_multiple_instances = true;
332*6dbdd20aSAndroid Build Coastguard Worker   params.requires_callbacks_under_lock = false;
333*6dbdd20aSAndroid Build Coastguard Worker   bool success = data_source_type->cpp_type.Register(
334*6dbdd20aSAndroid Build Coastguard Worker       dsd, factory, params, data_source_type->buffer_exhausted_policy,
335*6dbdd20aSAndroid Build Coastguard Worker       data_source_type->on_flush_cb == nullptr, create_custom_tls_fn,
336*6dbdd20aSAndroid Build Coastguard Worker       create_incremental_state_fn, cb_ctx);
337*6dbdd20aSAndroid Build Coastguard Worker   if (!success) {
338*6dbdd20aSAndroid Build Coastguard Worker     return false;
339*6dbdd20aSAndroid Build Coastguard Worker   }
340*6dbdd20aSAndroid Build Coastguard Worker   *enabled_ptr = &data_source_type->enabled;
341*6dbdd20aSAndroid Build Coastguard Worker   perfetto::base::ignore_result(data_source_type.release());
342*6dbdd20aSAndroid Build Coastguard Worker   return true;
343*6dbdd20aSAndroid Build Coastguard Worker }
344*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplUpdateDescriptor(struct PerfettoDsImpl * ds_impl,const void * descriptor,size_t descriptor_size)345*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsImplUpdateDescriptor(struct PerfettoDsImpl* ds_impl,
346*6dbdd20aSAndroid Build Coastguard Worker                                     const void* descriptor,
347*6dbdd20aSAndroid Build Coastguard Worker                                     size_t descriptor_size) {
348*6dbdd20aSAndroid Build Coastguard Worker   perfetto::DataSourceDescriptor dsd;
349*6dbdd20aSAndroid Build Coastguard Worker   dsd.ParseFromArray(descriptor, descriptor_size);
350*6dbdd20aSAndroid Build Coastguard Worker 
351*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->cpp_type.UpdateDescriptor(dsd);
352*6dbdd20aSAndroid Build Coastguard Worker }
353*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsOnStopArgsPostpone(PerfettoDsOnStopArgs * args)354*6dbdd20aSAndroid Build Coastguard Worker PerfettoDsAsyncStopper* PerfettoDsOnStopArgsPostpone(
355*6dbdd20aSAndroid Build Coastguard Worker     PerfettoDsOnStopArgs* args) {
356*6dbdd20aSAndroid Build Coastguard Worker   auto* cb = new std::function<void()>();
357*6dbdd20aSAndroid Build Coastguard Worker   *cb = reinterpret_cast<const ShlibDataSource::StopArgs*>(args)
358*6dbdd20aSAndroid Build Coastguard Worker             ->HandleStopAsynchronously();
359*6dbdd20aSAndroid Build Coastguard Worker   return reinterpret_cast<PerfettoDsAsyncStopper*>(cb);
360*6dbdd20aSAndroid Build Coastguard Worker }
361*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsStopDone(PerfettoDsAsyncStopper * stopper)362*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsStopDone(PerfettoDsAsyncStopper* stopper) {
363*6dbdd20aSAndroid Build Coastguard Worker   auto* cb = reinterpret_cast<std::function<void()>*>(stopper);
364*6dbdd20aSAndroid Build Coastguard Worker   (*cb)();
365*6dbdd20aSAndroid Build Coastguard Worker   delete cb;
366*6dbdd20aSAndroid Build Coastguard Worker }
367*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsOnFlushArgsPostpone(PerfettoDsOnFlushArgs * args)368*6dbdd20aSAndroid Build Coastguard Worker PerfettoDsAsyncFlusher* PerfettoDsOnFlushArgsPostpone(
369*6dbdd20aSAndroid Build Coastguard Worker     PerfettoDsOnFlushArgs* args) {
370*6dbdd20aSAndroid Build Coastguard Worker   auto* cb = new std::function<void()>();
371*6dbdd20aSAndroid Build Coastguard Worker   *cb = reinterpret_cast<const ShlibDataSource::FlushArgs*>(args)
372*6dbdd20aSAndroid Build Coastguard Worker             ->HandleFlushAsynchronously();
373*6dbdd20aSAndroid Build Coastguard Worker   return reinterpret_cast<PerfettoDsAsyncFlusher*>(cb);
374*6dbdd20aSAndroid Build Coastguard Worker }
375*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsFlushDone(PerfettoDsAsyncFlusher * stopper)376*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsFlushDone(PerfettoDsAsyncFlusher* stopper) {
377*6dbdd20aSAndroid Build Coastguard Worker   auto* cb = reinterpret_cast<std::function<void()>*>(stopper);
378*6dbdd20aSAndroid Build Coastguard Worker   (*cb)();
379*6dbdd20aSAndroid Build Coastguard Worker   delete cb;
380*6dbdd20aSAndroid Build Coastguard Worker }
381*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplGetInstanceLocked(struct PerfettoDsImpl * ds_impl,PerfettoDsInstanceIndex idx)382*6dbdd20aSAndroid Build Coastguard Worker void* PerfettoDsImplGetInstanceLocked(struct PerfettoDsImpl* ds_impl,
383*6dbdd20aSAndroid Build Coastguard Worker                                       PerfettoDsInstanceIndex idx) {
384*6dbdd20aSAndroid Build Coastguard Worker   auto* internal_state = ds_impl->cpp_type.static_state()->TryGet(idx);
385*6dbdd20aSAndroid Build Coastguard Worker   if (!internal_state) {
386*6dbdd20aSAndroid Build Coastguard Worker     return nullptr;
387*6dbdd20aSAndroid Build Coastguard Worker   }
388*6dbdd20aSAndroid Build Coastguard Worker   std::unique_lock<std::recursive_mutex> lock(internal_state->lock);
389*6dbdd20aSAndroid Build Coastguard Worker   auto* data_source =
390*6dbdd20aSAndroid Build Coastguard Worker       static_cast<ShlibDataSource*>(internal_state->data_source.get());
391*6dbdd20aSAndroid Build Coastguard Worker   if (&data_source->type() != ds_impl) {
392*6dbdd20aSAndroid Build Coastguard Worker     // The data source instance has been destroyed and recreated as a different
393*6dbdd20aSAndroid Build Coastguard Worker     // type while we where tracing.
394*6dbdd20aSAndroid Build Coastguard Worker     return nullptr;
395*6dbdd20aSAndroid Build Coastguard Worker   }
396*6dbdd20aSAndroid Build Coastguard Worker   void* inst_ctx = data_source->inst_ctx();
397*6dbdd20aSAndroid Build Coastguard Worker   if (inst_ctx != nullptr) {
398*6dbdd20aSAndroid Build Coastguard Worker     lock.release();
399*6dbdd20aSAndroid Build Coastguard Worker   }
400*6dbdd20aSAndroid Build Coastguard Worker   return inst_ctx;
401*6dbdd20aSAndroid Build Coastguard Worker }
402*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplReleaseInstanceLocked(struct PerfettoDsImpl * ds_impl,PerfettoDsInstanceIndex idx)403*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsImplReleaseInstanceLocked(struct PerfettoDsImpl* ds_impl,
404*6dbdd20aSAndroid Build Coastguard Worker                                          PerfettoDsInstanceIndex idx) {
405*6dbdd20aSAndroid Build Coastguard Worker   // The `valid_instances` bitmap might have changed since the lock has been
406*6dbdd20aSAndroid Build Coastguard Worker   // taken, but the instance must still be alive (we were holding the lock on
407*6dbdd20aSAndroid Build Coastguard Worker   // it).
408*6dbdd20aSAndroid Build Coastguard Worker   auto* internal_state = ds_impl->cpp_type.static_state()->GetUnsafe(idx);
409*6dbdd20aSAndroid Build Coastguard Worker   internal_state->lock.unlock();
410*6dbdd20aSAndroid Build Coastguard Worker }
411*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplGetCustomTls(struct PerfettoDsImpl *,struct PerfettoDsTracerImpl * tracer,PerfettoDsInstanceIndex)412*6dbdd20aSAndroid Build Coastguard Worker void* PerfettoDsImplGetCustomTls(struct PerfettoDsImpl*,
413*6dbdd20aSAndroid Build Coastguard Worker                                  struct PerfettoDsTracerImpl* tracer,
414*6dbdd20aSAndroid Build Coastguard Worker                                  PerfettoDsInstanceIndex) {
415*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
416*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(tracer);
417*6dbdd20aSAndroid Build Coastguard Worker 
418*6dbdd20aSAndroid Build Coastguard Worker   PERFETTO_DCHECK(tls_inst->data_source_custom_tls);
419*6dbdd20aSAndroid Build Coastguard Worker   return tls_inst->data_source_custom_tls.get();
420*6dbdd20aSAndroid Build Coastguard Worker }
421*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplGetIncrementalState(struct PerfettoDsImpl * ds_impl,struct PerfettoDsTracerImpl * tracer,PerfettoDsInstanceIndex idx)422*6dbdd20aSAndroid Build Coastguard Worker void* PerfettoDsImplGetIncrementalState(struct PerfettoDsImpl* ds_impl,
423*6dbdd20aSAndroid Build Coastguard Worker                                         struct PerfettoDsTracerImpl* tracer,
424*6dbdd20aSAndroid Build Coastguard Worker                                         PerfettoDsInstanceIndex idx) {
425*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
426*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(tracer);
427*6dbdd20aSAndroid Build Coastguard Worker 
428*6dbdd20aSAndroid Build Coastguard Worker   return ds_impl->cpp_type.GetIncrementalState(tls_inst, idx);
429*6dbdd20aSAndroid Build Coastguard Worker }
430*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplTraceIterateBegin(struct PerfettoDsImpl * ds_impl)431*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoDsImplTracerIterator PerfettoDsImplTraceIterateBegin(
432*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsImpl* ds_impl) {
433*6dbdd20aSAndroid Build Coastguard Worker   DataSourceThreadLocalState** tls =
434*6dbdd20aSAndroid Build Coastguard Worker       &g_tls_cache[ds_impl->cpp_type.static_state()->index];
435*6dbdd20aSAndroid Build Coastguard Worker 
436*6dbdd20aSAndroid Build Coastguard Worker   struct PerfettoDsImplTracerIterator ret = {0, nullptr, nullptr};
437*6dbdd20aSAndroid Build Coastguard Worker   uint32_t cached_instances =
438*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->cpp_type.valid_instances()->load(std::memory_order_relaxed);
439*6dbdd20aSAndroid Build Coastguard Worker   if (!cached_instances) {
440*6dbdd20aSAndroid Build Coastguard Worker     return ret;
441*6dbdd20aSAndroid Build Coastguard Worker   }
442*6dbdd20aSAndroid Build Coastguard Worker   bool res =
443*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->cpp_type.TracePrologue<DataSourceTraits, TracePointTraits>(
444*6dbdd20aSAndroid Build Coastguard Worker           tls, &cached_instances, &ds_impl->cpp_type);
445*6dbdd20aSAndroid Build Coastguard Worker   if (!res) {
446*6dbdd20aSAndroid Build Coastguard Worker     return ret;
447*6dbdd20aSAndroid Build Coastguard Worker   }
448*6dbdd20aSAndroid Build Coastguard Worker   DataSourceType::InstancesIterator it =
449*6dbdd20aSAndroid Build Coastguard Worker       ds_impl->cpp_type.BeginIteration<TracePointTraits>(cached_instances, *tls,
450*6dbdd20aSAndroid Build Coastguard Worker                                                          &ds_impl->cpp_type);
451*6dbdd20aSAndroid Build Coastguard Worker   ret.inst_id = it.i;
452*6dbdd20aSAndroid Build Coastguard Worker   (*tls)->root_tls->cached_instances = it.cached_instances;
453*6dbdd20aSAndroid Build Coastguard Worker   ret.tracer = reinterpret_cast<struct PerfettoDsTracerImpl*>(it.instance);
454*6dbdd20aSAndroid Build Coastguard Worker   if (!ret.tracer) {
455*6dbdd20aSAndroid Build Coastguard Worker     ds_impl->cpp_type.TraceEpilogue(*tls);
456*6dbdd20aSAndroid Build Coastguard Worker   }
457*6dbdd20aSAndroid Build Coastguard Worker 
458*6dbdd20aSAndroid Build Coastguard Worker   ret.tls = reinterpret_cast<struct PerfettoDsTlsImpl*>(*tls);
459*6dbdd20aSAndroid Build Coastguard Worker   return ret;
460*6dbdd20aSAndroid Build Coastguard Worker }
461*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplTraceIterateNext(struct PerfettoDsImpl * ds_impl,struct PerfettoDsImplTracerIterator * iterator)462*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsImplTraceIterateNext(
463*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsImpl* ds_impl,
464*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsImplTracerIterator* iterator) {
465*6dbdd20aSAndroid Build Coastguard Worker   auto* tls = reinterpret_cast<DataSourceThreadLocalState*>(iterator->tls);
466*6dbdd20aSAndroid Build Coastguard Worker 
467*6dbdd20aSAndroid Build Coastguard Worker   DataSourceType::InstancesIterator it;
468*6dbdd20aSAndroid Build Coastguard Worker   it.i = iterator->inst_id;
469*6dbdd20aSAndroid Build Coastguard Worker   it.cached_instances = tls->root_tls->cached_instances;
470*6dbdd20aSAndroid Build Coastguard Worker   it.instance =
471*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(iterator->tracer);
472*6dbdd20aSAndroid Build Coastguard Worker 
473*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->cpp_type.NextIteration<TracePointTraits>(&it, tls,
474*6dbdd20aSAndroid Build Coastguard Worker                                                     &ds_impl->cpp_type);
475*6dbdd20aSAndroid Build Coastguard Worker 
476*6dbdd20aSAndroid Build Coastguard Worker   iterator->inst_id = it.i;
477*6dbdd20aSAndroid Build Coastguard Worker   tls->root_tls->cached_instances = it.cached_instances;
478*6dbdd20aSAndroid Build Coastguard Worker   iterator->tracer =
479*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<struct PerfettoDsTracerImpl*>(it.instance);
480*6dbdd20aSAndroid Build Coastguard Worker 
481*6dbdd20aSAndroid Build Coastguard Worker   if (!iterator->tracer) {
482*6dbdd20aSAndroid Build Coastguard Worker     ds_impl->cpp_type.TraceEpilogue(tls);
483*6dbdd20aSAndroid Build Coastguard Worker   }
484*6dbdd20aSAndroid Build Coastguard Worker }
485*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsImplTraceIterateBreak(struct PerfettoDsImpl * ds_impl,struct PerfettoDsImplTracerIterator * iterator)486*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsImplTraceIterateBreak(
487*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsImpl* ds_impl,
488*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsImplTracerIterator* iterator) {
489*6dbdd20aSAndroid Build Coastguard Worker   auto* tls = reinterpret_cast<DataSourceThreadLocalState*>(iterator->tls);
490*6dbdd20aSAndroid Build Coastguard Worker 
491*6dbdd20aSAndroid Build Coastguard Worker   ds_impl->cpp_type.TraceEpilogue(tls);
492*6dbdd20aSAndroid Build Coastguard Worker }
493*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsTracerImplPacketBegin(struct PerfettoDsTracerImpl * tracer)494*6dbdd20aSAndroid Build Coastguard Worker struct PerfettoStreamWriter PerfettoDsTracerImplPacketBegin(
495*6dbdd20aSAndroid Build Coastguard Worker     struct PerfettoDsTracerImpl* tracer) {
496*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
497*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(tracer);
498*6dbdd20aSAndroid Build Coastguard Worker 
499*6dbdd20aSAndroid Build Coastguard Worker   auto message_handle = tls_inst->trace_writer->NewTracePacket();
500*6dbdd20aSAndroid Build Coastguard Worker   struct PerfettoStreamWriter ret;
501*6dbdd20aSAndroid Build Coastguard Worker   protozero::ScatteredStreamWriter* sw = message_handle.TakeStreamWriter();
502*6dbdd20aSAndroid Build Coastguard Worker   ret.impl = reinterpret_cast<PerfettoStreamWriterImpl*>(sw);
503*6dbdd20aSAndroid Build Coastguard Worker   perfetto::UpdateStreamWriter(*sw, &ret);
504*6dbdd20aSAndroid Build Coastguard Worker   return ret;
505*6dbdd20aSAndroid Build Coastguard Worker }
506*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsTracerImplPacketEnd(struct PerfettoDsTracerImpl * tracer,struct PerfettoStreamWriter * w)507*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsTracerImplPacketEnd(struct PerfettoDsTracerImpl* tracer,
508*6dbdd20aSAndroid Build Coastguard Worker                                    struct PerfettoStreamWriter* w) {
509*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
510*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(tracer);
511*6dbdd20aSAndroid Build Coastguard Worker   auto* sw = reinterpret_cast<protozero::ScatteredStreamWriter*>(w->impl);
512*6dbdd20aSAndroid Build Coastguard Worker 
513*6dbdd20aSAndroid Build Coastguard Worker   sw->set_write_ptr(w->write_ptr);
514*6dbdd20aSAndroid Build Coastguard Worker   tls_inst->trace_writer->FinishTracePacket();
515*6dbdd20aSAndroid Build Coastguard Worker }
516*6dbdd20aSAndroid Build Coastguard Worker 
PerfettoDsTracerImplFlush(struct PerfettoDsTracerImpl * tracer,PerfettoDsTracerOnFlushCb cb,void * user_arg)517*6dbdd20aSAndroid Build Coastguard Worker void PerfettoDsTracerImplFlush(struct PerfettoDsTracerImpl* tracer,
518*6dbdd20aSAndroid Build Coastguard Worker                                PerfettoDsTracerOnFlushCb cb,
519*6dbdd20aSAndroid Build Coastguard Worker                                void* user_arg) {
520*6dbdd20aSAndroid Build Coastguard Worker   auto* tls_inst =
521*6dbdd20aSAndroid Build Coastguard Worker       reinterpret_cast<DataSourceInstanceThreadLocalState*>(tracer);
522*6dbdd20aSAndroid Build Coastguard Worker 
523*6dbdd20aSAndroid Build Coastguard Worker   std::function<void()> fn;
524*6dbdd20aSAndroid Build Coastguard Worker   if (cb != nullptr) {
525*6dbdd20aSAndroid Build Coastguard Worker     fn = [user_arg, cb]() { cb(user_arg); };
526*6dbdd20aSAndroid Build Coastguard Worker   }
527*6dbdd20aSAndroid Build Coastguard Worker   tls_inst->trace_writer->Flush(fn);
528*6dbdd20aSAndroid Build Coastguard Worker }
529