xref: /aosp_15_r20/frameworks/native/libs/tracing_perfetto/tracing_perfetto_internal.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1 /*
2  * Copyright 2024 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 #define FRAMEWORK_CATEGORIES(C)                                  \
18   C(always, "always", "Always category")                         \
19   C(graphics, "graphics", "Graphics category")                   \
20   C(input, "input", "Input category")                            \
21   C(view, "view", "View category")                               \
22   C(webview, "webview", "WebView category")                      \
23   C(windowmanager, "wm", "WindowManager category")               \
24   C(activitymanager, "am", "ActivityManager category")           \
25   C(syncmanager, "syncmanager", "SyncManager category")          \
26   C(audio, "audio", "Audio category")                            \
27   C(video, "video", "Video category")                            \
28   C(camera, "camera", "Camera category")                         \
29   C(hal, "hal", "HAL category")                                  \
30   C(app, "app", "App category")                                  \
31   C(resources, "res", "Resources category")                      \
32   C(dalvik, "dalvik", "Dalvik category")                         \
33   C(rs, "rs", "RS category")                                     \
34   C(bionic, "bionic", "Bionic category")                         \
35   C(power, "power", "Power category")                            \
36   C(packagemanager, "packagemanager", "PackageManager category") \
37   C(systemserver, "ss", "System Server category")                \
38   C(database, "database", "Database category")                   \
39   C(network, "network", "Network category")                      \
40   C(adb, "adb", "ADB category")                                  \
41   C(vibrator, "vibrator", "Vibrator category")                   \
42   C(aidl, "aidl", "AIDL category")                               \
43   C(nnapi, "nnapi", "NNAPI category")                            \
44   C(rro, "rro", "RRO category")                                  \
45   C(thermal, "thermal", "Thermal category")
46 
47 #include <atomic>
48 #include <mutex>
49 
50 #include <android_os.h>
51 #include <android-base/properties.h>
52 #include <cutils/trace.h>
53 #include <inttypes.h>
54 
55 #include "perfetto/public/compiler.h"
56 #include "perfetto/public/producer.h"
57 #include "perfetto/public/te_category_macros.h"
58 #include "perfetto/public/te_macros.h"
59 #include "perfetto/public/track_event.h"
60 #include "trace_categories.h"
61 #include "tracing_perfetto_internal.h"
62 
63 #ifdef __BIONIC__
64 #define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
65 #include <sys/_system_properties.h>
66 #endif
67 
68 namespace tracing_perfetto {
69 
70 namespace internal {
71 
72 namespace {
73 PERFETTO_TE_CATEGORIES_DECLARE(FRAMEWORK_CATEGORIES);
74 
75 PERFETTO_TE_CATEGORIES_DEFINE(FRAMEWORK_CATEGORIES);
76 
77 static constexpr char kPreferFlagProperty[] = "debug.atrace.prefer_sdk";
78 static std::atomic<const prop_info*> prefer_property_info = nullptr;
79 static std::atomic_uint32_t last_prefer_seq_num = 0;
80 static std::atomic_uint64_t prefer_flags = 0;
81 
system_property_find(const char * name)82 static const prop_info* system_property_find(const char* name [[maybe_unused]]) {
83   #ifdef __BIONIC__
84   return __system_property_find(name);
85   #endif
86 
87   return nullptr;
88 }
89 
system_property_serial(const prop_info * pi)90 static uint32_t system_property_serial(const prop_info* pi [[maybe_unused]]) {
91   #ifdef __BIONIC__
92   return __system_property_serial(pi);
93   #endif
94 
95   return last_prefer_seq_num;
96 }
97 
toCategory(uint64_t inCategory)98 struct PerfettoTeCategory* toCategory(uint64_t inCategory) {
99   switch (inCategory) {
100     case TRACE_CATEGORY_ALWAYS:
101       return &always;
102     case TRACE_CATEGORY_GRAPHICS:
103       return &graphics;
104     case TRACE_CATEGORY_INPUT:
105       return &input;
106     case TRACE_CATEGORY_VIEW:
107       return &view;
108     case TRACE_CATEGORY_WEBVIEW:
109       return &webview;
110     case TRACE_CATEGORY_WINDOW_MANAGER:
111       return &windowmanager;
112     case TRACE_CATEGORY_ACTIVITY_MANAGER:
113       return &activitymanager;
114     case TRACE_CATEGORY_SYNC_MANAGER:
115       return &syncmanager;
116     case TRACE_CATEGORY_AUDIO:
117       return &audio;
118     case TRACE_CATEGORY_VIDEO:
119       return &video;
120     case TRACE_CATEGORY_CAMERA:
121       return &camera;
122     case TRACE_CATEGORY_HAL:
123       return &hal;
124     case TRACE_CATEGORY_APP:
125       return &app;
126     case TRACE_CATEGORY_RESOURCES:
127       return &resources;
128     case TRACE_CATEGORY_DALVIK:
129       return &dalvik;
130     case TRACE_CATEGORY_RS:
131       return &rs;
132     case TRACE_CATEGORY_BIONIC:
133       return &bionic;
134     case TRACE_CATEGORY_POWER:
135       return &power;
136     case TRACE_CATEGORY_PACKAGE_MANAGER:
137       return &packagemanager;
138     case TRACE_CATEGORY_SYSTEM_SERVER:
139       return &systemserver;
140     case TRACE_CATEGORY_DATABASE:
141       return &database;
142     case TRACE_CATEGORY_NETWORK:
143       return &network;
144     case TRACE_CATEGORY_ADB:
145       return &adb;
146     case TRACE_CATEGORY_VIBRATOR:
147       return &vibrator;
148     case TRACE_CATEGORY_AIDL:
149       return &aidl;
150     case TRACE_CATEGORY_NNAPI:
151       return &nnapi;
152     case TRACE_CATEGORY_RRO:
153       return &rro;
154     case TRACE_CATEGORY_THERMAL:
155       return &thermal;
156     default:
157       return nullptr;
158   }
159 }
160 
161 }  // namespace
162 
isPerfettoCategoryEnabled(PerfettoTeCategory * category)163 bool isPerfettoCategoryEnabled(PerfettoTeCategory* category) {
164   return category != nullptr;
165 }
166 
167 /**
168  * Updates the cached |prefer_flags|.
169  *
170  * We cache the prefer_flags because reading it on every trace event is expensive.
171  * The cache is invalidated when a sys_prop sequence number changes.
172  */
updatePreferFlags()173 void updatePreferFlags() {
174   if (!prefer_property_info.load(std::memory_order_acquire)) {
175     auto* new_prefer_property_info = system_property_find(kPreferFlagProperty);
176     prefer_flags.store(android::base::GetIntProperty(kPreferFlagProperty, 0),
177                        std::memory_order_relaxed);
178 
179     if (!new_prefer_property_info) {
180       // This should never happen. If it does, we fail gracefully and end up reading the property
181       // traced event.
182       return;
183     }
184 
185     last_prefer_seq_num = system_property_serial(new_prefer_property_info);
186     prefer_property_info.store(new_prefer_property_info, std::memory_order_release);
187   }
188 
189   uint32_t prefer_seq_num =  system_property_serial(prefer_property_info);
190   if (prefer_seq_num != last_prefer_seq_num.load(std::memory_order_acquire)) {
191     prefer_flags.store(android::base::GetIntProperty(kPreferFlagProperty, 0),
192                        std::memory_order_relaxed);
193     last_prefer_seq_num.store(prefer_seq_num, std::memory_order_release);
194   }
195 }
196 
shouldPreferAtrace(PerfettoTeCategory * perfettoCategory,uint64_t atraceCategory)197 bool shouldPreferAtrace(PerfettoTeCategory *perfettoCategory, uint64_t atraceCategory) {
198   // There are 3 cases:
199   // 1. Atrace is not enabled.
200   if (!atrace_is_tag_enabled(atraceCategory)) {
201     return false;
202   }
203 
204   // 2. Atrace is enabled but perfetto is not enabled.
205   if (!isPerfettoCategoryEnabled(perfettoCategory)) {
206     return true;
207   }
208 
209   // Update prefer_flags before checking it below
210   updatePreferFlags();
211 
212   // 3. Atrace and perfetto are enabled.
213   // Even though this category is enabled for track events, the config mandates that we downgrade
214   // it to atrace if the same atrace category is currently enabled. This prevents missing the
215   // event from a concurrent session that needs the same category in atrace.
216   return (atraceCategory & prefer_flags.load(std::memory_order_relaxed)) == 0;
217 }
218 
toPerfettoCategory(uint64_t category)219 struct PerfettoTeCategory* toPerfettoCategory(uint64_t category) {
220   struct PerfettoTeCategory* perfettoCategory = toCategory(category);
221   if (perfettoCategory == nullptr) {
222     return nullptr;
223   }
224 
225   bool enabled = PERFETTO_UNLIKELY(PERFETTO_ATOMIC_LOAD_EXPLICIT(
226        (*perfettoCategory).enabled, PERFETTO_MEMORY_ORDER_RELAXED));
227   return enabled ? perfettoCategory : nullptr;
228 }
229 
registerWithPerfetto(bool test)230 void registerWithPerfetto(bool test) {
231   if (!android::os::perfetto_sdk_tracing()) {
232     return;
233   }
234 
235   static std::once_flag registration;
236   std::call_once(registration, [test]() {
237     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
238     args.backends = test ? PERFETTO_BACKEND_IN_PROCESS : PERFETTO_BACKEND_SYSTEM;
239     args.shmem_size_hint_kb = 1024;
240     PerfettoProducerInit(args);
241     PerfettoTeInit();
242     PERFETTO_TE_REGISTER_CATEGORIES(FRAMEWORK_CATEGORIES);
243   });
244 }
245 
perfettoTraceBegin(const struct PerfettoTeCategory & category,const char * name)246 void perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name) {
247   PERFETTO_TE(category, PERFETTO_TE_SLICE_BEGIN(name));
248 }
249 
perfettoTraceEnd(const struct PerfettoTeCategory & category)250 void perfettoTraceEnd(const struct PerfettoTeCategory& category) {
251   PERFETTO_TE(category, PERFETTO_TE_SLICE_END());
252 }
253 
perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory & category,const char * name,const char * trackName,uint64_t cookie)254 void perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
255                                        const char* trackName, uint64_t cookie) {
256   PERFETTO_TE(
257         category, PERFETTO_TE_SLICE_BEGIN(name),
258         PERFETTO_TE_PROTO_TRACK(
259             PerfettoTeNamedTrackUuid(trackName, cookie,
260                                      PerfettoTeProcessTrackUuid()),
261             PERFETTO_TE_PROTO_FIELD_CSTR(
262                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
263                 trackName),
264             PERFETTO_TE_PROTO_FIELD_VARINT(
265                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
266                 PerfettoTeProcessTrackUuid())));
267 }
268 
perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory & category,const char * trackName,uint64_t cookie)269 void perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
270                                      const char* trackName, uint64_t cookie) {
271     PERFETTO_TE(
272         category, PERFETTO_TE_SLICE_END(),
273         PERFETTO_TE_PROTO_TRACK(
274             PerfettoTeNamedTrackUuid(trackName, cookie,
275                                      PerfettoTeProcessTrackUuid()),
276             PERFETTO_TE_PROTO_FIELD_CSTR(
277                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
278                 trackName),
279             PERFETTO_TE_PROTO_FIELD_VARINT(
280                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
281                 PerfettoTeProcessTrackUuid())));
282 }
283 
perfettoTraceAsyncBegin(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)284 void perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
285                                uint64_t cookie) {
286   perfettoTraceAsyncBeginForTrack(category, name, name, cookie);
287 }
288 
perfettoTraceAsyncEnd(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)289 void perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
290                              uint64_t cookie) {
291   perfettoTraceAsyncEndForTrack(category, name, cookie);
292 }
293 
perfettoTraceInstant(const struct PerfettoTeCategory & category,const char * name)294 void perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name) {
295   PERFETTO_TE(category, PERFETTO_TE_INSTANT(name));
296 }
297 
perfettoTraceInstantForTrack(const struct PerfettoTeCategory & category,const char * trackName,const char * name)298 void perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
299                                     const char* trackName, const char* name) {
300   PERFETTO_TE(
301         category, PERFETTO_TE_INSTANT(name),
302         PERFETTO_TE_PROTO_TRACK(
303             PerfettoTeNamedTrackUuid(trackName, 1,
304                                      PerfettoTeProcessTrackUuid()),
305             PERFETTO_TE_PROTO_FIELD_CSTR(
306                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
307                 trackName),
308             PERFETTO_TE_PROTO_FIELD_VARINT(
309                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
310                 PerfettoTeProcessTrackUuid())));
311 }
312 
perfettoTraceCounter(const struct PerfettoTeCategory & category,const char * name,int64_t value)313 void perfettoTraceCounter(const struct PerfettoTeCategory& category,
314                           const char* name, int64_t value) {
315   PERFETTO_TE(
316         category, PERFETTO_TE_COUNTER(),
317         PERFETTO_TE_PROTO_TRACK(
318             PerfettoTeCounterTrackUuid(name,
319                                        PerfettoTeProcessTrackUuid()),
320             PERFETTO_TE_PROTO_FIELD_CSTR(
321                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
322                 name),
323             PERFETTO_TE_PROTO_FIELD_VARINT(
324                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
325                 PerfettoTeProcessTrackUuid()),
326             PERFETTO_TE_PROTO_FIELD_BYTES(
327                 perfetto_protos_TrackDescriptor_counter_field_number,
328                 PERFETTO_NULL, 0)),
329         PERFETTO_TE_INT_COUNTER(value));
330 }
331 }  // namespace internal
332 
333 }  // namespace tracing_perfetto
334