xref: /aosp_15_r20/external/pigweed/pw_trace_tokenized/trace.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1*61c4878aSAndroid Build Coastguard Worker // Copyright 2020 The Pigweed Authors
2*61c4878aSAndroid Build Coastguard Worker //
3*61c4878aSAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4*61c4878aSAndroid Build Coastguard Worker // use this file except in compliance with the License. You may obtain a copy of
5*61c4878aSAndroid Build Coastguard Worker // the License at
6*61c4878aSAndroid Build Coastguard Worker //
7*61c4878aSAndroid Build Coastguard Worker //     https://www.apache.org/licenses/LICENSE-2.0
8*61c4878aSAndroid Build Coastguard Worker //
9*61c4878aSAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*61c4878aSAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11*61c4878aSAndroid Build Coastguard Worker // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12*61c4878aSAndroid Build Coastguard Worker // License for the specific language governing permissions and limitations under
13*61c4878aSAndroid Build Coastguard Worker // the License.
14*61c4878aSAndroid Build Coastguard Worker //==============================================================================
15*61c4878aSAndroid Build Coastguard Worker //
16*61c4878aSAndroid Build Coastguard Worker 
17*61c4878aSAndroid Build Coastguard Worker #include "pw_trace/trace.h"
18*61c4878aSAndroid Build Coastguard Worker 
19*61c4878aSAndroid Build Coastguard Worker #include "pw_preprocessor/util.h"
20*61c4878aSAndroid Build Coastguard Worker #include "pw_trace_tokenized/trace_callback.h"
21*61c4878aSAndroid Build Coastguard Worker #include "pw_trace_tokenized/trace_tokenized.h"
22*61c4878aSAndroid Build Coastguard Worker #include "pw_varint/varint.h"
23*61c4878aSAndroid Build Coastguard Worker 
24*61c4878aSAndroid Build Coastguard Worker namespace pw {
25*61c4878aSAndroid Build Coastguard Worker namespace trace {
26*61c4878aSAndroid Build Coastguard Worker 
GetCallbacks()27*61c4878aSAndroid Build Coastguard Worker Callbacks& GetCallbacks() {
28*61c4878aSAndroid Build Coastguard Worker   static Callbacks callbacks;
29*61c4878aSAndroid Build Coastguard Worker   return callbacks;
30*61c4878aSAndroid Build Coastguard Worker }
31*61c4878aSAndroid Build Coastguard Worker 
GetTokenizedTracer()32*61c4878aSAndroid Build Coastguard Worker TokenizedTracer& GetTokenizedTracer() {
33*61c4878aSAndroid Build Coastguard Worker   static TokenizedTracer tokenized_tracer(GetCallbacks());
34*61c4878aSAndroid Build Coastguard Worker   return tokenized_tracer;
35*61c4878aSAndroid Build Coastguard Worker }
36*61c4878aSAndroid Build Coastguard Worker 
37*61c4878aSAndroid Build Coastguard Worker using TraceEvent = pw_trace_tokenized_TraceEvent;
38*61c4878aSAndroid Build Coastguard Worker 
HandleTraceEvent(uint32_t trace_token,EventType event_type,const char * module,uint32_t trace_id,uint8_t flags,const void * data_buffer,size_t data_size)39*61c4878aSAndroid Build Coastguard Worker void TokenizedTracer::HandleTraceEvent(uint32_t trace_token,
40*61c4878aSAndroid Build Coastguard Worker                                        EventType event_type,
41*61c4878aSAndroid Build Coastguard Worker                                        const char* module,
42*61c4878aSAndroid Build Coastguard Worker                                        uint32_t trace_id,
43*61c4878aSAndroid Build Coastguard Worker                                        uint8_t flags,
44*61c4878aSAndroid Build Coastguard Worker                                        const void* data_buffer,
45*61c4878aSAndroid Build Coastguard Worker                                        size_t data_size) {
46*61c4878aSAndroid Build Coastguard Worker   // Early exit if disabled and no callbacks are register to receive events
47*61c4878aSAndroid Build Coastguard Worker   // while disabled.
48*61c4878aSAndroid Build Coastguard Worker   if (!enabled_ && callbacks_.GetCalledOnEveryEventCount() == 0) {
49*61c4878aSAndroid Build Coastguard Worker     return;
50*61c4878aSAndroid Build Coastguard Worker   }
51*61c4878aSAndroid Build Coastguard Worker 
52*61c4878aSAndroid Build Coastguard Worker   TraceEvent event = {
53*61c4878aSAndroid Build Coastguard Worker       .trace_token = trace_token,
54*61c4878aSAndroid Build Coastguard Worker       .event_type = event_type,
55*61c4878aSAndroid Build Coastguard Worker       .module = module,
56*61c4878aSAndroid Build Coastguard Worker       .flags = flags,
57*61c4878aSAndroid Build Coastguard Worker       .trace_id = trace_id,
58*61c4878aSAndroid Build Coastguard Worker       .data_size = data_size,
59*61c4878aSAndroid Build Coastguard Worker       .data_buffer = data_buffer,
60*61c4878aSAndroid Build Coastguard Worker   };
61*61c4878aSAndroid Build Coastguard Worker 
62*61c4878aSAndroid Build Coastguard Worker   // Call any event callback which is registered to receive every event.
63*61c4878aSAndroid Build Coastguard Worker   pw_trace_TraceEventReturnFlags ret_flags = 0;
64*61c4878aSAndroid Build Coastguard Worker   ret_flags |=
65*61c4878aSAndroid Build Coastguard Worker       callbacks_.CallEventCallbacks(Callbacks::kCallOnEveryEvent, &event);
66*61c4878aSAndroid Build Coastguard Worker   // Return if disabled.
67*61c4878aSAndroid Build Coastguard Worker   if ((PW_TRACE_EVENT_RETURN_FLAGS_SKIP_EVENT & ret_flags) || !enabled_) {
68*61c4878aSAndroid Build Coastguard Worker     return;
69*61c4878aSAndroid Build Coastguard Worker   }
70*61c4878aSAndroid Build Coastguard Worker 
71*61c4878aSAndroid Build Coastguard Worker   // Call any event callback not already called.
72*61c4878aSAndroid Build Coastguard Worker   ret_flags |=
73*61c4878aSAndroid Build Coastguard Worker       callbacks_.CallEventCallbacks(Callbacks::kCallOnlyWhenEnabled, &event);
74*61c4878aSAndroid Build Coastguard Worker   // Return if disabled (from a callback) or if a callback has indicated the
75*61c4878aSAndroid Build Coastguard Worker   // sample should be skipped.
76*61c4878aSAndroid Build Coastguard Worker   if ((PW_TRACE_EVENT_RETURN_FLAGS_SKIP_EVENT & ret_flags) || !enabled_) {
77*61c4878aSAndroid Build Coastguard Worker     return;
78*61c4878aSAndroid Build Coastguard Worker   }
79*61c4878aSAndroid Build Coastguard Worker 
80*61c4878aSAndroid Build Coastguard Worker   // Create trace event
81*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_QUEUE_LOCK();
82*61c4878aSAndroid Build Coastguard Worker   if (!event_queue_
83*61c4878aSAndroid Build Coastguard Worker            .TryPushBack(event.trace_token,
84*61c4878aSAndroid Build Coastguard Worker                         event.event_type,
85*61c4878aSAndroid Build Coastguard Worker                         event.module,
86*61c4878aSAndroid Build Coastguard Worker                         event.trace_id,
87*61c4878aSAndroid Build Coastguard Worker                         event.flags,
88*61c4878aSAndroid Build Coastguard Worker                         event.data_buffer,
89*61c4878aSAndroid Build Coastguard Worker                         event.data_size)
90*61c4878aSAndroid Build Coastguard Worker            .ok()) {
91*61c4878aSAndroid Build Coastguard Worker     // Queue full dropping sample
92*61c4878aSAndroid Build Coastguard Worker     // TODO(rgoliver): Allow other strategies, for example: drop oldest, try
93*61c4878aSAndroid Build Coastguard Worker     // empty queue, or block.
94*61c4878aSAndroid Build Coastguard Worker   }
95*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_QUEUE_UNLOCK();
96*61c4878aSAndroid Build Coastguard Worker 
97*61c4878aSAndroid Build Coastguard Worker   // Sample is now in queue (if not dropped), try to empty the queue if not
98*61c4878aSAndroid Build Coastguard Worker   // already being emptied.
99*61c4878aSAndroid Build Coastguard Worker   if (PW_TRACE_TRY_LOCK()) {
100*61c4878aSAndroid Build Coastguard Worker     while (!event_queue_.IsEmpty()) {
101*61c4878aSAndroid Build Coastguard Worker       HandleNextItemInQueue(event_queue_.PeekFront());
102*61c4878aSAndroid Build Coastguard Worker       event_queue_.PopFront();
103*61c4878aSAndroid Build Coastguard Worker     }
104*61c4878aSAndroid Build Coastguard Worker     PW_TRACE_UNLOCK();
105*61c4878aSAndroid Build Coastguard Worker   }
106*61c4878aSAndroid Build Coastguard Worker 
107*61c4878aSAndroid Build Coastguard Worker   // Disable after processing if an event callback had set the flag.
108*61c4878aSAndroid Build Coastguard Worker   if (PW_TRACE_EVENT_RETURN_FLAGS_DISABLE_AFTER_PROCESSING & ret_flags) {
109*61c4878aSAndroid Build Coastguard Worker     enabled_ = false;
110*61c4878aSAndroid Build Coastguard Worker   }
111*61c4878aSAndroid Build Coastguard Worker }
112*61c4878aSAndroid Build Coastguard Worker 
HandleNextItemInQueue(const volatile TraceQueue::QueueEventBlock * event_block)113*61c4878aSAndroid Build Coastguard Worker void TokenizedTracer::HandleNextItemInQueue(
114*61c4878aSAndroid Build Coastguard Worker     const volatile TraceQueue::QueueEventBlock* event_block) {
115*61c4878aSAndroid Build Coastguard Worker   // Get next item in queue
116*61c4878aSAndroid Build Coastguard Worker   uint32_t trace_token = event_block->trace_token;
117*61c4878aSAndroid Build Coastguard Worker   EventType event_type = event_block->event_type;
118*61c4878aSAndroid Build Coastguard Worker   uint32_t trace_id = event_block->trace_id;
119*61c4878aSAndroid Build Coastguard Worker   const std::byte* data_buffer =
120*61c4878aSAndroid Build Coastguard Worker       const_cast<const std::byte*>(event_block->data_buffer);
121*61c4878aSAndroid Build Coastguard Worker   size_t data_size = event_block->data_size;
122*61c4878aSAndroid Build Coastguard Worker 
123*61c4878aSAndroid Build Coastguard Worker   // Create header to store trace info
124*61c4878aSAndroid Build Coastguard Worker   static constexpr size_t kMaxHeaderSize =
125*61c4878aSAndroid Build Coastguard Worker       sizeof(trace_token) + pw::varint::kMaxVarint64SizeBytes +  // time
126*61c4878aSAndroid Build Coastguard Worker       pw::varint::kMaxVarint64SizeBytes;                         // trace_id
127*61c4878aSAndroid Build Coastguard Worker   std::byte header[kMaxHeaderSize];
128*61c4878aSAndroid Build Coastguard Worker   memcpy(header, &trace_token, sizeof(trace_token));
129*61c4878aSAndroid Build Coastguard Worker   size_t header_size = sizeof(trace_token);
130*61c4878aSAndroid Build Coastguard Worker 
131*61c4878aSAndroid Build Coastguard Worker   // Compute delta of time elapsed since last trace entry.
132*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_TIME_TYPE trace_time = pw_trace_GetTraceTime();
133*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_TIME_TYPE delta =
134*61c4878aSAndroid Build Coastguard Worker       (last_trace_time_ == 0)
135*61c4878aSAndroid Build Coastguard Worker           ? 0
136*61c4878aSAndroid Build Coastguard Worker           : PW_TRACE_GET_TIME_DELTA(last_trace_time_, trace_time);
137*61c4878aSAndroid Build Coastguard Worker   header_size += pw::varint::Encode(
138*61c4878aSAndroid Build Coastguard Worker       delta,
139*61c4878aSAndroid Build Coastguard Worker       span<std::byte>(&header[header_size], kMaxHeaderSize - header_size));
140*61c4878aSAndroid Build Coastguard Worker   last_trace_time_ = trace_time;
141*61c4878aSAndroid Build Coastguard Worker 
142*61c4878aSAndroid Build Coastguard Worker   // Calculate packet id if needed.
143*61c4878aSAndroid Build Coastguard Worker   if (PW_TRACE_HAS_TRACE_ID(event_type)) {
144*61c4878aSAndroid Build Coastguard Worker     header_size += pw::varint::Encode(
145*61c4878aSAndroid Build Coastguard Worker         trace_id,
146*61c4878aSAndroid Build Coastguard Worker         span<std::byte>(&header[header_size], kMaxHeaderSize - header_size));
147*61c4878aSAndroid Build Coastguard Worker   }
148*61c4878aSAndroid Build Coastguard Worker 
149*61c4878aSAndroid Build Coastguard Worker   // Send encoded output to any registered trace sinks.
150*61c4878aSAndroid Build Coastguard Worker   callbacks_.CallSinks(
151*61c4878aSAndroid Build Coastguard Worker       span<const std::byte>(header, header_size),
152*61c4878aSAndroid Build Coastguard Worker       span<const std::byte>(reinterpret_cast<const std::byte*>(data_buffer),
153*61c4878aSAndroid Build Coastguard Worker                             data_size));
154*61c4878aSAndroid Build Coastguard Worker }
155*61c4878aSAndroid Build Coastguard Worker 
CallEventCallbacks(CallOnEveryEvent called_on_every_event,TraceEvent * event)156*61c4878aSAndroid Build Coastguard Worker pw_trace_TraceEventReturnFlags Callbacks::CallEventCallbacks(
157*61c4878aSAndroid Build Coastguard Worker     CallOnEveryEvent called_on_every_event, TraceEvent* event) {
158*61c4878aSAndroid Build Coastguard Worker   pw_trace_TraceEventReturnFlags ret_flags = 0;
159*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS; i++) {
160*61c4878aSAndroid Build Coastguard Worker     if (event_callbacks_[i].callback &&
161*61c4878aSAndroid Build Coastguard Worker         event_callbacks_[i].called_on_every_event == called_on_every_event) {
162*61c4878aSAndroid Build Coastguard Worker       ret_flags |=
163*61c4878aSAndroid Build Coastguard Worker           GetEventCallback(i)->callback(event_callbacks_[i].user_data, event);
164*61c4878aSAndroid Build Coastguard Worker     }
165*61c4878aSAndroid Build Coastguard Worker   }
166*61c4878aSAndroid Build Coastguard Worker   return ret_flags;
167*61c4878aSAndroid Build Coastguard Worker }
168*61c4878aSAndroid Build Coastguard Worker 
CallSinks(span<const std::byte> header,span<const std::byte> data)169*61c4878aSAndroid Build Coastguard Worker void Callbacks::CallSinks(span<const std::byte> header,
170*61c4878aSAndroid Build Coastguard Worker                           span<const std::byte> data) {
171*61c4878aSAndroid Build Coastguard Worker   for (size_t sink_idx = 0; sink_idx < PW_TRACE_CONFIG_MAX_SINKS; sink_idx++) {
172*61c4878aSAndroid Build Coastguard Worker     void* user_data = sink_callbacks_[sink_idx].user_data;
173*61c4878aSAndroid Build Coastguard Worker     if (sink_callbacks_[sink_idx].start_block) {
174*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].start_block(user_data,
175*61c4878aSAndroid Build Coastguard Worker                                             header.size() + data.size());
176*61c4878aSAndroid Build Coastguard Worker     }
177*61c4878aSAndroid Build Coastguard Worker     if (sink_callbacks_[sink_idx].add_bytes) {
178*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].add_bytes(
179*61c4878aSAndroid Build Coastguard Worker           user_data, header.data(), header.size());
180*61c4878aSAndroid Build Coastguard Worker       if (!data.empty()) {
181*61c4878aSAndroid Build Coastguard Worker         sink_callbacks_[sink_idx].add_bytes(
182*61c4878aSAndroid Build Coastguard Worker             user_data, data.data(), data.size());
183*61c4878aSAndroid Build Coastguard Worker       }
184*61c4878aSAndroid Build Coastguard Worker     }
185*61c4878aSAndroid Build Coastguard Worker     if (sink_callbacks_[sink_idx].end_block) {
186*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].end_block(user_data);
187*61c4878aSAndroid Build Coastguard Worker     }
188*61c4878aSAndroid Build Coastguard Worker   }
189*61c4878aSAndroid Build Coastguard Worker }
190*61c4878aSAndroid Build Coastguard Worker 
RegisterSink(SinkStartBlock start_func,SinkAddBytes add_bytes_func,SinkEndBlock end_block_func,void * user_data,SinkHandle * handle)191*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::RegisterSink(SinkStartBlock start_func,
192*61c4878aSAndroid Build Coastguard Worker                                    SinkAddBytes add_bytes_func,
193*61c4878aSAndroid Build Coastguard Worker                                    SinkEndBlock end_block_func,
194*61c4878aSAndroid Build Coastguard Worker                                    void* user_data,
195*61c4878aSAndroid Build Coastguard Worker                                    SinkHandle* handle) {
196*61c4878aSAndroid Build Coastguard Worker   pw_Status status = PW_STATUS_RESOURCE_EXHAUSTED;
197*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_LOCK();
198*61c4878aSAndroid Build Coastguard Worker   for (size_t sink_idx = 0; sink_idx < PW_TRACE_CONFIG_MAX_SINKS; sink_idx++) {
199*61c4878aSAndroid Build Coastguard Worker     if (IsSinkFree(sink_idx)) {
200*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].start_block = start_func;
201*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].add_bytes = add_bytes_func;
202*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].end_block = end_block_func;
203*61c4878aSAndroid Build Coastguard Worker       sink_callbacks_[sink_idx].user_data = user_data;
204*61c4878aSAndroid Build Coastguard Worker       if (handle) {
205*61c4878aSAndroid Build Coastguard Worker         *handle = sink_idx;
206*61c4878aSAndroid Build Coastguard Worker       }
207*61c4878aSAndroid Build Coastguard Worker       status = PW_STATUS_OK;
208*61c4878aSAndroid Build Coastguard Worker       break;
209*61c4878aSAndroid Build Coastguard Worker     }
210*61c4878aSAndroid Build Coastguard Worker   }
211*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_UNLOCK();
212*61c4878aSAndroid Build Coastguard Worker   return status;
213*61c4878aSAndroid Build Coastguard Worker }
214*61c4878aSAndroid Build Coastguard Worker 
UnregisterSink(SinkHandle handle)215*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::UnregisterSink(SinkHandle handle) {
216*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_LOCK();
217*61c4878aSAndroid Build Coastguard Worker   if (handle >= PW_TRACE_CONFIG_MAX_SINKS) {
218*61c4878aSAndroid Build Coastguard Worker     return PW_STATUS_INVALID_ARGUMENT;
219*61c4878aSAndroid Build Coastguard Worker   }
220*61c4878aSAndroid Build Coastguard Worker   sink_callbacks_[handle].start_block = nullptr;
221*61c4878aSAndroid Build Coastguard Worker   sink_callbacks_[handle].add_bytes = nullptr;
222*61c4878aSAndroid Build Coastguard Worker   sink_callbacks_[handle].end_block = nullptr;
223*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_UNLOCK();
224*61c4878aSAndroid Build Coastguard Worker   return PW_STATUS_OK;
225*61c4878aSAndroid Build Coastguard Worker }
226*61c4878aSAndroid Build Coastguard Worker 
UnregisterAllSinks()227*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::UnregisterAllSinks() {
228*61c4878aSAndroid Build Coastguard Worker   for (size_t sink_idx = 0; sink_idx < PW_TRACE_CONFIG_MAX_SINKS; sink_idx++) {
229*61c4878aSAndroid Build Coastguard Worker     UnregisterSink(sink_idx)
230*61c4878aSAndroid Build Coastguard Worker         .IgnoreError();  // TODO: b/242598609 - Handle Status properly
231*61c4878aSAndroid Build Coastguard Worker   }
232*61c4878aSAndroid Build Coastguard Worker   return PW_STATUS_OK;
233*61c4878aSAndroid Build Coastguard Worker }
234*61c4878aSAndroid Build Coastguard Worker 
GetSink(SinkHandle handle)235*61c4878aSAndroid Build Coastguard Worker Callbacks::SinkCallbacks* Callbacks::GetSink(SinkHandle handle) {
236*61c4878aSAndroid Build Coastguard Worker   if (handle >= PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS) {
237*61c4878aSAndroid Build Coastguard Worker     return nullptr;
238*61c4878aSAndroid Build Coastguard Worker   }
239*61c4878aSAndroid Build Coastguard Worker   return &sink_callbacks_[handle];
240*61c4878aSAndroid Build Coastguard Worker }
241*61c4878aSAndroid Build Coastguard Worker 
RegisterEventCallback(EventCallback callback,CallOnEveryEvent called_on_every_event,void * user_data,EventCallbackHandle * handle)242*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::RegisterEventCallback(
243*61c4878aSAndroid Build Coastguard Worker     EventCallback callback,
244*61c4878aSAndroid Build Coastguard Worker     CallOnEveryEvent called_on_every_event,
245*61c4878aSAndroid Build Coastguard Worker     void* user_data,
246*61c4878aSAndroid Build Coastguard Worker     EventCallbackHandle* handle) {
247*61c4878aSAndroid Build Coastguard Worker   pw_Status status = PW_STATUS_RESOURCE_EXHAUSTED;
248*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_LOCK();
249*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS; i++) {
250*61c4878aSAndroid Build Coastguard Worker     if (event_callbacks_[i].callback == nullptr) {
251*61c4878aSAndroid Build Coastguard Worker       event_callbacks_[i].callback = callback;
252*61c4878aSAndroid Build Coastguard Worker       event_callbacks_[i].user_data = user_data;
253*61c4878aSAndroid Build Coastguard Worker       event_callbacks_[i].called_on_every_event = called_on_every_event;
254*61c4878aSAndroid Build Coastguard Worker       called_on_every_event_count_ += called_on_every_event ? 1 : 0;
255*61c4878aSAndroid Build Coastguard Worker       if (handle) {
256*61c4878aSAndroid Build Coastguard Worker         *handle = i;
257*61c4878aSAndroid Build Coastguard Worker       }
258*61c4878aSAndroid Build Coastguard Worker       status = PW_STATUS_OK;
259*61c4878aSAndroid Build Coastguard Worker       break;
260*61c4878aSAndroid Build Coastguard Worker     }
261*61c4878aSAndroid Build Coastguard Worker   }
262*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_UNLOCK();
263*61c4878aSAndroid Build Coastguard Worker   return status;
264*61c4878aSAndroid Build Coastguard Worker }
265*61c4878aSAndroid Build Coastguard Worker 
UnregisterEventCallback(EventCallbackHandle handle)266*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::UnregisterEventCallback(EventCallbackHandle handle) {
267*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_LOCK();
268*61c4878aSAndroid Build Coastguard Worker   if (handle >= PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS) {
269*61c4878aSAndroid Build Coastguard Worker     return PW_STATUS_INVALID_ARGUMENT;
270*61c4878aSAndroid Build Coastguard Worker   }
271*61c4878aSAndroid Build Coastguard Worker   event_callbacks_[handle].callback = nullptr;
272*61c4878aSAndroid Build Coastguard Worker   event_callbacks_[handle].user_data = nullptr;
273*61c4878aSAndroid Build Coastguard Worker   called_on_every_event_count_ +=
274*61c4878aSAndroid Build Coastguard Worker       event_callbacks_[handle].called_on_every_event ? 1 : 0;
275*61c4878aSAndroid Build Coastguard Worker   event_callbacks_[handle].called_on_every_event = kCallOnlyWhenEnabled;
276*61c4878aSAndroid Build Coastguard Worker   PW_TRACE_UNLOCK();
277*61c4878aSAndroid Build Coastguard Worker   return PW_STATUS_OK;
278*61c4878aSAndroid Build Coastguard Worker }
279*61c4878aSAndroid Build Coastguard Worker 
UnregisterAllEventCallbacks()280*61c4878aSAndroid Build Coastguard Worker pw::Status Callbacks::UnregisterAllEventCallbacks() {
281*61c4878aSAndroid Build Coastguard Worker   for (size_t i = 0; i < PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS; i++) {
282*61c4878aSAndroid Build Coastguard Worker     UnregisterEventCallback(i)
283*61c4878aSAndroid Build Coastguard Worker         .IgnoreError();  // TODO: b/242598609 - Handle Status properly
284*61c4878aSAndroid Build Coastguard Worker   }
285*61c4878aSAndroid Build Coastguard Worker   return PW_STATUS_OK;
286*61c4878aSAndroid Build Coastguard Worker }
287*61c4878aSAndroid Build Coastguard Worker 
GetEventCallback(EventCallbackHandle handle)288*61c4878aSAndroid Build Coastguard Worker Callbacks::EventCallbacks* Callbacks::GetEventCallback(
289*61c4878aSAndroid Build Coastguard Worker     EventCallbackHandle handle) {
290*61c4878aSAndroid Build Coastguard Worker   if (handle >= PW_TRACE_CONFIG_MAX_EVENT_CALLBACKS) {
291*61c4878aSAndroid Build Coastguard Worker     return nullptr;
292*61c4878aSAndroid Build Coastguard Worker   }
293*61c4878aSAndroid Build Coastguard Worker   return &event_callbacks_[handle];
294*61c4878aSAndroid Build Coastguard Worker }
295*61c4878aSAndroid Build Coastguard Worker 
296*61c4878aSAndroid Build Coastguard Worker // C functions
297*61c4878aSAndroid Build Coastguard Worker 
298*61c4878aSAndroid Build Coastguard Worker PW_EXTERN_C_START
299*61c4878aSAndroid Build Coastguard Worker 
pw_trace_Enable(bool enable)300*61c4878aSAndroid Build Coastguard Worker void pw_trace_Enable(bool enable) { GetTokenizedTracer().Enable(enable); }
301*61c4878aSAndroid Build Coastguard Worker 
pw_trace_IsEnabled()302*61c4878aSAndroid Build Coastguard Worker bool pw_trace_IsEnabled() { return GetTokenizedTracer().IsEnabled(); }
303*61c4878aSAndroid Build Coastguard Worker 
pw_trace_TraceEvent(uint32_t trace_token,pw_trace_EventType event_type,const char * module,uint32_t trace_id,uint8_t flags,const void * data_buffer,size_t data_size)304*61c4878aSAndroid Build Coastguard Worker void pw_trace_TraceEvent(uint32_t trace_token,
305*61c4878aSAndroid Build Coastguard Worker                          pw_trace_EventType event_type,
306*61c4878aSAndroid Build Coastguard Worker                          const char* module,
307*61c4878aSAndroid Build Coastguard Worker                          uint32_t trace_id,
308*61c4878aSAndroid Build Coastguard Worker                          uint8_t flags,
309*61c4878aSAndroid Build Coastguard Worker                          const void* data_buffer,
310*61c4878aSAndroid Build Coastguard Worker                          size_t data_size) {
311*61c4878aSAndroid Build Coastguard Worker   GetTokenizedTracer().HandleTraceEvent(
312*61c4878aSAndroid Build Coastguard Worker       trace_token, event_type, module, trace_id, flags, data_buffer, data_size);
313*61c4878aSAndroid Build Coastguard Worker }
314*61c4878aSAndroid Build Coastguard Worker 
pw_trace_RegisterSink(pw_trace_SinkStartBlock start_func,pw_trace_SinkAddBytes add_bytes_func,pw_trace_SinkEndBlock end_block_func,void * user_data,pw_trace_SinkHandle * handle)315*61c4878aSAndroid Build Coastguard Worker pw_Status pw_trace_RegisterSink(pw_trace_SinkStartBlock start_func,
316*61c4878aSAndroid Build Coastguard Worker                                 pw_trace_SinkAddBytes add_bytes_func,
317*61c4878aSAndroid Build Coastguard Worker                                 pw_trace_SinkEndBlock end_block_func,
318*61c4878aSAndroid Build Coastguard Worker                                 void* user_data,
319*61c4878aSAndroid Build Coastguard Worker                                 pw_trace_SinkHandle* handle) {
320*61c4878aSAndroid Build Coastguard Worker   return GetCallbacks()
321*61c4878aSAndroid Build Coastguard Worker       .RegisterSink(
322*61c4878aSAndroid Build Coastguard Worker           start_func, add_bytes_func, end_block_func, user_data, handle)
323*61c4878aSAndroid Build Coastguard Worker       .code();
324*61c4878aSAndroid Build Coastguard Worker }
325*61c4878aSAndroid Build Coastguard Worker 
pw_trace_UnregisterSink(pw_trace_EventCallbackHandle handle)326*61c4878aSAndroid Build Coastguard Worker pw_Status pw_trace_UnregisterSink(pw_trace_EventCallbackHandle handle) {
327*61c4878aSAndroid Build Coastguard Worker   return GetCallbacks().UnregisterSink(handle).code();
328*61c4878aSAndroid Build Coastguard Worker }
329*61c4878aSAndroid Build Coastguard Worker 
pw_trace_RegisterEventCallback(pw_trace_EventCallback callback,pw_trace_ShouldCallOnEveryEvent called_on_every_event,void * user_data,pw_trace_EventCallbackHandle * handle)330*61c4878aSAndroid Build Coastguard Worker pw_Status pw_trace_RegisterEventCallback(
331*61c4878aSAndroid Build Coastguard Worker     pw_trace_EventCallback callback,
332*61c4878aSAndroid Build Coastguard Worker     pw_trace_ShouldCallOnEveryEvent called_on_every_event,
333*61c4878aSAndroid Build Coastguard Worker     void* user_data,
334*61c4878aSAndroid Build Coastguard Worker     pw_trace_EventCallbackHandle* handle) {
335*61c4878aSAndroid Build Coastguard Worker   return GetCallbacks()
336*61c4878aSAndroid Build Coastguard Worker       .RegisterEventCallback(
337*61c4878aSAndroid Build Coastguard Worker           callback,
338*61c4878aSAndroid Build Coastguard Worker           static_cast<Callbacks::CallOnEveryEvent>(called_on_every_event),
339*61c4878aSAndroid Build Coastguard Worker           user_data,
340*61c4878aSAndroid Build Coastguard Worker           handle)
341*61c4878aSAndroid Build Coastguard Worker       .code();
342*61c4878aSAndroid Build Coastguard Worker }
343*61c4878aSAndroid Build Coastguard Worker 
pw_trace_UnregisterEventCallback(pw_trace_EventCallbackHandle handle)344*61c4878aSAndroid Build Coastguard Worker pw_Status pw_trace_UnregisterEventCallback(
345*61c4878aSAndroid Build Coastguard Worker     pw_trace_EventCallbackHandle handle) {
346*61c4878aSAndroid Build Coastguard Worker   return GetCallbacks().UnregisterEventCallback(handle).code();
347*61c4878aSAndroid Build Coastguard Worker }
348*61c4878aSAndroid Build Coastguard Worker 
349*61c4878aSAndroid Build Coastguard Worker PW_EXTERN_C_END
350*61c4878aSAndroid Build Coastguard Worker 
351*61c4878aSAndroid Build Coastguard Worker }  // namespace trace
352*61c4878aSAndroid Build Coastguard Worker }  // namespace pw
353