• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 // Should match the definitions in: frameworks/native/cmds/atrace/atrace.cpp
18 #define FRAMEWORK_CATEGORIES(C)                                  \
19   C(always, "always", "Always category")                         \
20   C(graphics, "gfx", "Graphics category")                        \
21   C(input, "input", "Input category")                            \
22   C(view, "view", "View category")                               \
23   C(webview, "webview", "WebView category")                      \
24   C(windowmanager, "wm", "WindowManager category")               \
25   C(activitymanager, "am", "ActivityManager category")           \
26   C(syncmanager, "sm", "SyncManager category")                   \
27   C(audio, "audio", "Audio category")                            \
28   C(video, "video", "Video category")                            \
29   C(camera, "camera", "Camera category")                         \
30   C(hal, "hal", "HAL category")                                  \
31   C(app, "app", "App category")                                  \
32   C(resources, "res", "Resources category")                      \
33   C(dalvik, "dalvik", "Dalvik category")                         \
34   C(rs, "rs", "RS category")                                     \
35   C(bionic, "bionic", "Bionic category")                         \
36   C(power, "power", "Power category")                            \
37   C(packagemanager, "pm", "PackageManager category")             \
38   C(systemserver, "ss", "System Server category")                \
39   C(database, "database", "Database category")                   \
40   C(network, "network", "Network category")                      \
41   C(adb, "adb", "ADB category")                                  \
42   C(vibrator, "vibrator", "Vibrator category")                   \
43   C(aidl, "aidl", "AIDL category")                               \
44   C(nnapi, "nnapi", "NNAPI category")                            \
45   C(rro, "rro", "RRO category")                                  \
46   C(thermal, "thermal", "Thermal category")
47 
48 #include <atomic>
49 #include <mutex>
50 
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   static std::once_flag registration;
232   std::call_once(registration, [test]() {
233     struct PerfettoProducerInitArgs args = PERFETTO_PRODUCER_INIT_ARGS_INIT();
234     args.backends = test ? PERFETTO_BACKEND_IN_PROCESS : PERFETTO_BACKEND_SYSTEM;
235     args.shmem_size_hint_kb = 1024;
236     PerfettoProducerInit(args);
237     PerfettoTeInit();
238     PERFETTO_TE_REGISTER_CATEGORIES(FRAMEWORK_CATEGORIES);
239   });
240 }
241 
perfettoTraceBegin(const struct PerfettoTeCategory & category,const char * name)242 void perfettoTraceBegin(const struct PerfettoTeCategory& category, const char* name) {
243   PERFETTO_TE(category, PERFETTO_TE_SLICE_BEGIN(name));
244 }
245 
perfettoTraceEnd(const struct PerfettoTeCategory & category)246 void perfettoTraceEnd(const struct PerfettoTeCategory& category) {
247   PERFETTO_TE(category, PERFETTO_TE_SLICE_END());
248 }
249 
perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory & category,const char * name,const char * trackName,uint64_t cookie)250 void perfettoTraceAsyncBeginForTrack(const struct PerfettoTeCategory& category, const char* name,
251                                        const char* trackName, uint64_t cookie) {
252   PERFETTO_TE(
253         category, PERFETTO_TE_SLICE_BEGIN(name),
254         PERFETTO_TE_PROTO_TRACK(
255             PerfettoTeNamedTrackUuid(trackName, cookie,
256                                      PerfettoTeProcessTrackUuid()),
257             PERFETTO_TE_PROTO_FIELD_CSTR(
258                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
259                 trackName),
260             PERFETTO_TE_PROTO_FIELD_VARINT(
261                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
262                 PerfettoTeProcessTrackUuid())));
263 }
264 
perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory & category,const char * trackName,uint64_t cookie)265 void perfettoTraceAsyncEndForTrack(const struct PerfettoTeCategory& category,
266                                      const char* trackName, uint64_t cookie) {
267     PERFETTO_TE(
268         category, PERFETTO_TE_SLICE_END(),
269         PERFETTO_TE_PROTO_TRACK(
270             PerfettoTeNamedTrackUuid(trackName, cookie,
271                                      PerfettoTeProcessTrackUuid()),
272             PERFETTO_TE_PROTO_FIELD_CSTR(
273                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
274                 trackName),
275             PERFETTO_TE_PROTO_FIELD_VARINT(
276                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
277                 PerfettoTeProcessTrackUuid())));
278 }
279 
perfettoTraceAsyncBegin(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)280 void perfettoTraceAsyncBegin(const struct PerfettoTeCategory& category, const char* name,
281                                uint64_t cookie) {
282   perfettoTraceAsyncBeginForTrack(category, name, name, cookie);
283 }
284 
perfettoTraceAsyncEnd(const struct PerfettoTeCategory & category,const char * name,uint64_t cookie)285 void perfettoTraceAsyncEnd(const struct PerfettoTeCategory& category, const char* name,
286                              uint64_t cookie) {
287   perfettoTraceAsyncEndForTrack(category, name, cookie);
288 }
289 
perfettoTraceInstant(const struct PerfettoTeCategory & category,const char * name)290 void perfettoTraceInstant(const struct PerfettoTeCategory& category, const char* name) {
291   PERFETTO_TE(category, PERFETTO_TE_INSTANT(name));
292 }
293 
perfettoTraceInstantForTrack(const struct PerfettoTeCategory & category,const char * trackName,const char * name)294 void perfettoTraceInstantForTrack(const struct PerfettoTeCategory& category,
295                                     const char* trackName, const char* name) {
296   PERFETTO_TE(
297         category, PERFETTO_TE_INSTANT(name),
298         PERFETTO_TE_PROTO_TRACK(
299             PerfettoTeNamedTrackUuid(trackName, 1,
300                                      PerfettoTeProcessTrackUuid()),
301             PERFETTO_TE_PROTO_FIELD_CSTR(
302                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
303                 trackName),
304             PERFETTO_TE_PROTO_FIELD_VARINT(
305                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
306                 PerfettoTeProcessTrackUuid())));
307 }
308 
perfettoTraceCounter(const struct PerfettoTeCategory & category,const char * name,int64_t value)309 void perfettoTraceCounter(const struct PerfettoTeCategory& category,
310                           const char* name, int64_t value) {
311   PERFETTO_TE(
312         category, PERFETTO_TE_COUNTER(),
313         PERFETTO_TE_PROTO_TRACK(
314             PerfettoTeCounterTrackUuid(name,
315                                        PerfettoTeProcessTrackUuid()),
316             PERFETTO_TE_PROTO_FIELD_CSTR(
317                 perfetto_protos_TrackDescriptor_atrace_name_field_number,
318                 name),
319             PERFETTO_TE_PROTO_FIELD_VARINT(
320                 perfetto_protos_TrackDescriptor_parent_uuid_field_number,
321                 PerfettoTeProcessTrackUuid()),
322             PERFETTO_TE_PROTO_FIELD_BYTES(
323                 perfetto_protos_TrackDescriptor_counter_field_number,
324                 PERFETTO_NULL, 0)),
325         PERFETTO_TE_INT_COUNTER(value));
326 }
327 }  // namespace internal
328 
329 }  // namespace tracing_perfetto
330