1-- 2-- Copyright 2022 The Android Open Source Project 3-- 4-- Licensed under the Apache License, Version 2.0 (the "License"); 5-- you may not use this file except in compliance with the License. 6-- You may obtain a copy of the License at 7-- 8-- https://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 17INCLUDE PERFETTO MODULE android.startup.startups; 18 19SELECT RUN_METRIC('android/startup/thread_state_breakdown.sql'); 20SELECT RUN_METRIC('android/startup/system_state.sql'); 21SELECT RUN_METRIC('android/startup/mcycles_per_launch.sql'); 22 23CREATE OR REPLACE PERFETTO FUNCTION _is_spans_overlapping( 24 ts1 LONG, 25 ts_end1 LONG, 26 ts2 LONG, 27 ts_end2 LONG) 28RETURNS BOOL AS 29SELECT (IIF($ts1 < $ts2, $ts2, $ts1) 30 < IIF($ts_end1 < $ts_end2, $ts_end1, $ts_end2)); 31 32CREATE OR REPLACE PERFETTO FUNCTION get_percent(num LONG, total LONG) 33RETURNS STRING AS 34 SELECT SUBSTRING(CAST(($num * 100 + 0.0) / $total AS STRING), 1, 5); 35 36CREATE OR REPLACE PERFETTO FUNCTION get_ns_to_s(ns LONG) 37RETURNS STRING AS 38 SELECT CAST(($ns + 0.0) / 1e9 AS STRING); 39 40CREATE OR REPLACE PERFETTO FUNCTION get_ns_to_ms(ns LONG) 41RETURNS STRING AS 42 SELECT SUBSTRING(CAST(($ns + 0.0) / 1e6 AS STRING), 1, 6); 43 44CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_in_runnable_state( 45 startup_id LONG, num_threads INT) 46RETURNS PROTO AS 47 SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection( 48 'start_timestamp', ts, 'end_timestamp', ts + dur, 49 'thread_utid', utid, 'thread_name', thread_name)) 50 FROM ( 51 SELECT ts, dur, utid, thread_name 52 FROM launch_threads_by_thread_state l 53 JOIN thread USING (utid) 54 WHERE l.startup_id = $startup_id AND (state GLOB "R" OR state GLOB "R+") AND l.is_main_thread 55 ORDER BY dur DESC 56 LIMIT $num_threads); 57 58CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_and_state( 59 startup_id LONG, state STRING, num_threads INT) 60RETURNS PROTO AS 61 SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection( 62 'start_timestamp', ts, 'end_timestamp', ts + dur, 63 'thread_utid', utid, 'thread_name', thread_name)) 64 FROM ( 65 SELECT ts, dur, utid, thread_name 66 FROM launch_threads_by_thread_state l 67 JOIN thread USING (utid) 68 WHERE l.startup_id = $startup_id AND state GLOB $state AND l.is_main_thread 69 ORDER BY dur DESC 70 LIMIT $num_threads); 71 72CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_time_for_launch_state_and_io_wait( 73 startup_id INT, state STRING, io_wait BOOL, num_threads INT) 74RETURNS PROTO AS 75 SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection( 76 'start_timestamp', ts, 'end_timestamp', ts + dur, 77 'thread_utid', utid, 'thread_name', thread_name)) 78 FROM ( 79 SELECT ts, dur, utid, thread_name 80 FROM launch_threads_by_thread_state l 81 JOIN thread USING (utid) 82 WHERE l.startup_id = $startup_id AND state GLOB $state 83 AND l.is_main_thread AND l.io_wait = $io_wait 84 ORDER BY dur DESC 85 LIMIT $num_threads); 86 87CREATE OR REPLACE PERFETTO FUNCTION get_thread_time_for_launch_state_and_thread( 88 startup_id INT, state STRING, thread_name STRING, num_threads INT) 89RETURNS PROTO AS 90 SELECT RepeatedField(AndroidStartupMetric_TraceThreadSection( 91 'start_timestamp', ts, 'end_timestamp', ts + dur, 92 'thread_utid', utid, 'thread_name', thread_name)) 93 FROM ( 94 SELECT ts, dur, utid, thread_name 95 FROM launch_threads_by_thread_state l 96 JOIN thread USING (utid) 97 WHERE l.startup_id = $startup_id AND state GLOB $state AND thread_name = $thread_name 98 ORDER BY dur DESC 99 LIMIT $num_threads); 100 101CREATE OR REPLACE PERFETTO FUNCTION get_missing_baseline_profile_for_launch( 102 startup_id LONG, pkg_name STRING) 103RETURNS PROTO AS 104 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 105 'start_timestamp', slice_ts, 106 'end_timestamp', slice_ts + slice_dur, 107 'slice_id', slice_id, 108 'slice_name', slice_name)) 109 FROM ( 110 SELECT slice_ts, slice_dur, slice_id, slice_name 111 FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME($startup_id, 112 "location=* status=* filter=* reason=*") 113 WHERE 114 -- when location is the package odex file and the reason is "install" or "install-dm", 115 -- if the compilation filter is not "speed-profile", baseline/cloud profile is missing. 116 SUBSTR(STR_SPLIT(slice_name, " status=", 0), LENGTH("location=") + 1) 117 GLOB ("*" || $pkg_name || "*odex") 118 AND (STR_SPLIT(slice_name, " reason=", 1) = "install" 119 OR STR_SPLIT(slice_name, " reason=", 1) = "install-dm") 120 ORDER BY slice_dur DESC 121 LIMIT 1); 122 123CREATE OR REPLACE PERFETTO FUNCTION get_run_from_apk(startup_id LONG) 124RETURNS PROTO AS 125 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 126 'start_timestamp', slice_ts, 127 'end_timestamp', slice_ts + slice_dur, 128 'slice_id', slice_id, 129 'slice_name', slice_name)) 130 FROM ( 131 SELECT slice_ts, slice_dur, slice_id, slice_name 132 FROM android_thread_slices_for_all_startups 133 WHERE 134 startup_id = $startup_id AND is_main_thread AND 135 slice_name GLOB "location=* status=* filter=* reason=*" AND 136 STR_SPLIT(STR_SPLIT(slice_name, " filter=", 1), " reason=", 0) 137 GLOB ("*" || "run-from-apk" || "*") 138 ORDER BY slice_dur DESC 139 LIMIT 1); 140 141CREATE OR REPLACE PERFETTO FUNCTION get_unlock_running_during_launch_slice(startup_id LONG) 142RETURNS PROTO AS 143 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 144 'start_timestamp', slice_ts, 145 'end_timestamp', slice_ts + slice_dur, 146 'slice_id', slice_id, 147 'slice_name', slice_name)) 148 FROM ( 149 SELECT slice.ts as slice_ts, slice.dur as slice_dur, 150 slice.id as slice_id, slice.name as slice_name 151 FROM slice, android_startups launches 152 JOIN thread_track ON slice.track_id = thread_track.id 153 JOIN thread USING(utid) 154 JOIN process USING(upid) 155 WHERE launches.startup_id = $startup_id 156 AND slice.name = "KeyguardUpdateMonitor#onAuthenticationSucceeded" 157 AND process.name = "com.android.systemui" 158 AND slice.ts >= launches.ts 159 AND (slice.ts + slice.dur) <= launches.ts_end 160 LIMIT 1); 161 162CREATE OR REPLACE PERFETTO FUNCTION get_gc_activity(startup_id LONG, num_slices INT) 163RETURNS PROTO AS 164 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 165 'start_timestamp', slice_ts, 166 'end_timestamp', slice_ts + slice_dur, 167 'slice_id', slice_id, 168 'slice_name', slice_name)) 169 FROM ( 170 SELECT slice_ts, slice_dur, slice_id, slice_name 171 FROM android_thread_slices_for_all_startups slice 172 WHERE 173 slice.startup_id = $startup_id AND 174 ( 175 slice_name GLOB "*semispace GC" OR 176 slice_name GLOB "*mark sweep GC" OR 177 slice_name GLOB "*concurrent copying GC" 178 ) 179 ORDER BY slice_dur DESC 180 LIMIT $num_slices); 181 182CREATE OR REPLACE PERFETTO FUNCTION get_dur_on_main_thread_for_startup_and_slice( 183 startup_id LONG, slice_name STRING, num_slices INT) 184RETURNS PROTO AS 185 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 186 'start_timestamp', slice_ts, 187 'end_timestamp', slice_ts + slice_dur, 188 'slice_id', slice_id, 189 'slice_name', slice_name)) 190 FROM ( 191 SELECT slice_ts, slice_dur, slice_id, slice_name 192 FROM android_thread_slices_for_all_startups l 193 WHERE startup_id = $startup_id 194 AND slice_name GLOB $slice_name 195 ORDER BY slice_dur DESC 196 LIMIT $num_slices); 197 198CREATE OR REPLACE PERFETTO FUNCTION get_main_thread_binder_transactions_blocked( 199 startup_id LONG, threshold DOUBLE, num_slices INT) 200RETURNS PROTO AS 201 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 202 'start_timestamp', slice_ts, 'end_timestamp', slice_ts + slice_dur, 203 'slice_id', slice_id, 'slice_name', slice_name)) 204 FROM ( 205 SELECT request.slice_ts as slice_ts, request.slice_dur as slice_dur, 206 request.id as slice_id, request.slice_name as slice_name 207 FROM ( 208 SELECT slice_id as id, slice_dur, thread_name, process.name as process, 209 s.arg_set_id, is_main_thread, 210 slice_ts, s.utid, slice_name 211 FROM android_thread_slices_for_all_startups s 212 JOIN process ON ( 213 EXTRACT_ARG(s.arg_set_id, "destination process") = process.pid 214 ) 215 WHERE startup_id = $startup_id AND slice_name GLOB "binder transaction" 216 AND slice_dur > $threshold 217 ) request 218 JOIN following_flow(request.id) arrow 219 JOIN slice reply ON reply.id = arrow.slice_in 220 JOIN thread USING (utid) 221 WHERE reply.dur > $threshold AND request.is_main_thread 222 ORDER BY request.slice_dur DESC 223 LIMIT $num_slices); 224 225CREATE OR REPLACE PERFETTO FUNCTION get_slices_concurrent_to_launch( 226 startup_id INT, slice_glob STRING, num_slices INT) 227RETURNS PROTO AS 228 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 229 'start_timestamp', ts, 'end_timestamp', ts + dur, 230 'slice_id', id, 'slice_name', name)) 231 FROM ( 232 SELECT s.ts as ts, dur, id, name FROM slice s 233 JOIN ( 234 SELECT ts, ts_end 235 FROM android_startups 236 WHERE startup_id = $startup_id 237 ) launch 238 WHERE 239 s.name GLOB $slice_glob AND 240 s.ts BETWEEN launch.ts AND launch.ts_end 241 ORDER BY dur DESC LIMIT $num_slices); 242 243CREATE OR REPLACE PERFETTO FUNCTION get_slices_for_startup_and_slice_name( 244 startup_id INT, slice_name STRING, num_slices INT) 245RETURNS PROTO AS 246 SELECT RepeatedField(AndroidStartupMetric_TraceSliceSection( 247 'start_timestamp', slice_ts, 'end_timestamp', slice_ts + slice_dur, 248 'slice_id', slice_id, 'slice_name', slice_name)) 249 FROM ( 250 SELECT slice_ts, slice_dur, slice_id, slice_name 251 FROM android_thread_slices_for_all_startups 252 WHERE startup_id = $startup_id AND slice_name GLOB $slice_name 253 ORDER BY slice_dur DESC 254 LIMIT $num_slices); 255 256CREATE OR REPLACE PERFETTO FUNCTION get_process_running_concurrent_to_launch( 257 startup_id INT, process_glob STRING) 258RETURNS STRING AS 259 SELECT process.name 260 FROM sched 261 JOIN thread USING (utid) 262 JOIN process USING (upid) 263 JOIN ( 264 SELECT ts, ts_end 265 FROM android_startups 266 WHERE startup_id = $startup_id 267 ) launch 268 WHERE 269 process.name GLOB $process_glob AND 270 sched.ts BETWEEN launch.ts AND launch.ts_end 271 ORDER BY (launch.ts_end - sched.ts) DESC 272 LIMIT 1; 273 274CREATE OR REPLACE PERFETTO FUNCTION get_slow_start_reason_with_details(startup_id LONG) 275RETURNS PROTO AS 276 SELECT RepeatedField(AndroidStartupMetric_SlowStartReason( 277 'reason_id', reason_id, 278 'reason', slow_cause, 279 'launch_dur', launch_dur, 280 'expected_value', expected_val, 281 'actual_value', actual_val, 282 'trace_slice_sections', trace_slices, 283 'trace_thread_sections', trace_threads, 284 'additional_info', extra)) 285 FROM ( 286 SELECT 'No baseline or cloud profiles' as slow_cause, 287 launch.dur as launch_dur, 288 'NO_BASELINE_OR_CLOUD_PROFILES' as reason_id, 289 AndroidStartupMetric_ThresholdValue( 290 'value', FALSE, 291 'unit', 'TRUE_OR_FALSE') as expected_val, 292 AndroidStartupMetric_ActualValue( 293 'value', TRUE) as actual_val, 294 get_missing_baseline_profile_for_launch(launch.startup_id, launch.package) 295 as trace_slices, 296 NULL as trace_threads, 297 NULL as extra 298 FROM android_startups launch 299 WHERE launch.startup_id = $startup_id 300 AND missing_baseline_profile_for_launch(launch.startup_id, launch.package) 301 302 UNION ALL 303 SELECT 'Optimized artifacts missing, run from apk' as slow_cause, 304 launch.dur as launch_dur, 305 'RUN_FROM_APK' as reason_id, 306 AndroidStartupMetric_ThresholdValue( 307 'value', FALSE, 308 'unit', 'TRUE_OR_FALSE') as expected_val, 309 AndroidStartupMetric_ActualValue( 310 'value', TRUE) as actual_val, 311 get_run_from_apk(launch.startup_id) as trace_slices, 312 NULL as trace_threads, 313 NULL as extra 314 FROM android_startups launch 315 WHERE launch.startup_id = $startup_id 316 AND run_from_apk_for_launch(launch.startup_id) 317 318 UNION ALL 319 SELECT 'Unlock running during launch' as slow_cause, 320 launch.dur as launch_dur, 321 'UNLOCK_RUNNING' as reason_id, 322 AndroidStartupMetric_ThresholdValue( 323 'value', FALSE, 324 'unit', 'TRUE_OR_FALSE') as expected_val, 325 AndroidStartupMetric_ActualValue( 326 'value', TRUE) as actual_val, 327 get_unlock_running_during_launch_slice(launch.startup_id) as trace_slices, 328 NULL as trace_threads, 329 NULL as extra 330 FROM android_startups launch 331 WHERE launch.startup_id = $startup_id 332 AND is_unlock_running_during_launch(launch.startup_id) 333 334 UNION ALL 335 SELECT 'App in debuggable mode' as slow_cause, 336 launch.dur as launch_dur, 337 'APP_IN_DEBUGGABLE_MODE' as reason_id, 338 AndroidStartupMetric_ThresholdValue( 339 'value', FALSE, 340 'unit', 'TRUE_OR_FALSE') as expected_val, 341 AndroidStartupMetric_ActualValue( 342 'value', TRUE) as actual_val, 343 NULL as trace_slices, 344 NULL as trace_threads, 345 NULL as extra 346 FROM android_startups launch 347 WHERE launch.startup_id = $startup_id 348 AND is_process_debuggable(launch.package) 349 350 UNION ALL 351 SELECT 'GC Activity' as slow_cause, 352 launch.dur as launch_dur, 353 'GC_ACTIVITY' as reason_id, 354 AndroidStartupMetric_ThresholdValue( 355 'value', FALSE, 356 'unit', 'TRUE_OR_FALSE') as expected_val, 357 AndroidStartupMetric_ActualValue( 358 'value', TRUE) as actual_val, 359 get_gc_activity(launch.startup_id, 1) as trace_slices, 360 NULL as trace_threads, 361 NULL as extra 362 FROM android_startups launch 363 WHERE launch.startup_id = $startup_id 364 AND total_gc_time_by_launch(launch.startup_id) > 0 365 366 UNION ALL 367 SELECT 'dex2oat running during launch' AS slow_cause, 368 launch.dur as launch_dur, 369 'DEX2OAT_RUNNING' as reason_id, 370 AndroidStartupMetric_ThresholdValue( 371 'value', FALSE, 372 'unit', 'TRUE_OR_FALSE') as expected_val, 373 AndroidStartupMetric_ActualValue( 374 'value', TRUE) as actual_val, 375 NULL as trace_slices, 376 NULL as trace_threads, 377 'Process: ' || get_process_running_concurrent_to_launch(launch.startup_id, '*dex2oat64') 378 as extra 379 FROM android_startups launch 380 WHERE launch.startup_id = $startup_id AND 381 dur_of_process_running_concurrent_to_launch(launch.startup_id, '*dex2oat64') > 0 382 383 UNION ALL 384 SELECT 'installd running during launch' AS slow_cause, 385 launch.dur as launch_dur, 386 'INSTALLD_RUNNING' as reason_id, 387 AndroidStartupMetric_ThresholdValue( 388 'value', FALSE, 389 'unit', 'TRUE_OR_FALSE') as expected_val, 390 AndroidStartupMetric_ActualValue( 391 'value', TRUE) as actual_val, 392 NULL as trace_slices, 393 NULL as trace_threads, 394 'Process: ' || get_process_running_concurrent_to_launch(launch.startup_id, '*installd') 395 as extra 396 FROM android_startups launch 397 WHERE launch.startup_id = $startup_id AND 398 dur_of_process_running_concurrent_to_launch(launch.startup_id, '*installd') > 0 399 400 UNION ALL 401 SELECT 'Main Thread - Time spent in Runnable state' as slow_cause, 402 launch.dur as launch_dur, 403 'MAIN_THREAD_TIME_SPENT_IN_RUNNABLE' as reason_id, 404 AndroidStartupMetric_ThresholdValue( 405 'value', 15, 406 'unit', 'PERCENTAGE', 407 'higher_expected', FALSE) as expected_val, 408 AndroidStartupMetric_ActualValue( 409 'value', 410 main_thread_time_for_launch_in_runnable_state(launch.startup_id) * 100 / launch.dur, 411 'dur', main_thread_time_for_launch_in_runnable_state(launch.startup_id)) as actual_val, 412 NULL as trace_slices, 413 get_main_thread_time_for_launch_in_runnable_state(launch.startup_id, 3) as trace_threads, 414 NULL as extra 415 FROM android_startups launch 416 WHERE launch.startup_id = $startup_id 417 AND main_thread_time_for_launch_in_runnable_state(launch.startup_id) > launch.dur * 0.15 418 419 UNION ALL 420 SELECT 'Main Thread - Time spent in interruptible sleep state' as slow_cause, 421 launch.dur as launch_dur, 422 'MAIN_THREAD_TIME_SPENT_IN_INTERRUPTIBLE_SLEEP' as reason_id, 423 AndroidStartupMetric_ThresholdValue( 424 'value', 2900000000, 425 'unit', 'NS', 426 'higher_expected', FALSE) as expected_val, 427 AndroidStartupMetric_ActualValue( 428 'value', main_thread_time_for_launch_and_state(launch.startup_id, 'S')) as actual_val, 429 NULL as trace_slices, 430 get_main_thread_time_for_launch_and_state(launch.startup_id, 'S', 3) as trace_threads, 431 NULL as extra 432 FROM android_startups launch 433 WHERE launch.startup_id = $startup_id 434 AND main_thread_time_for_launch_and_state(launch.startup_id, 'S') > 2900e6 435 436 UNION ALL 437 SELECT 'Main Thread - Time spent in Blocking I/O' as slow_cause, 438 launch.dur as launch_dur, 439 'MAIN_THREAD_TIME_SPENT_IN_BLOCKING_IO' as reason_id, 440 AndroidStartupMetric_ThresholdValue( 441 'value', 450000000, 442 'unit', 'NS', 443 'higher_expected', FALSE) as expected_val, 444 AndroidStartupMetric_ActualValue( 445 'value', main_thread_time_for_launch_state_and_io_wait( 446 launch.startup_id, 'D*', TRUE)) as actual_val, 447 NULL as trace_slices, 448 get_main_thread_time_for_launch_state_and_io_wait( 449 launch.startup_id, 'D*', TRUE, 3) as trace_threads, 450 NULL as extra 451 FROM android_startups launch 452 WHERE launch.startup_id = $startup_id 453 AND main_thread_time_for_launch_state_and_io_wait(launch.startup_id, 'D*', TRUE) > 450e6 454 455 UNION ALL 456 SELECT 'Main Thread - Time spent in OpenDexFilesFromOat*' as slow_cause, 457 launch.dur as launch_dur, 458 'MAIN_THREAD_TIME_SPENT_IN_OPEN_DEX_FILES_FROM_OAT' as reason_id, 459 AndroidStartupMetric_ThresholdValue( 460 'value', 20, 461 'unit', 'PERCENTAGE', 462 'higher_expected', FALSE) as expected_val, 463 AndroidStartupMetric_ActualValue( 464 'value', android_sum_dur_on_main_thread_for_startup_and_slice( 465 launch.startup_id, 'OpenDexFilesFromOat*') * 100 / launch.dur, 466 'dur', android_sum_dur_on_main_thread_for_startup_and_slice( 467 launch.startup_id, 'OpenDexFilesFromOat*')) as actual_val, 468 get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'OpenDexFilesFromOat*', 3) 469 as trace_slices, 470 NULL as trace_threads, 471 NULL as extra 472 FROM android_startups launch 473 WHERE launch.startup_id = $startup_id AND 474 android_sum_dur_on_main_thread_for_startup_and_slice( 475 launch.startup_id, 'OpenDexFilesFromOat*') > launch.dur * 0.2 476 477 UNION ALL 478 SELECT 'Time spent in bindApplication' as slow_cause, 479 launch.dur as launch_dur, 480 'TIME_SPENT_IN_BIND_APPLICATION' as reason_id, 481 AndroidStartupMetric_ThresholdValue( 482 'value', 1250000000, 483 'unit', 'NS', 484 'higher_expected', FALSE) as expected_val, 485 AndroidStartupMetric_ActualValue( 486 'value', android_sum_dur_for_startup_and_slice( 487 launch.startup_id, 'bindApplication')) as actual_val, 488 get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'bindApplication', 3) 489 as trace_slices, 490 NULL as trace_threads, 491 NULL as extra 492 FROM android_startups launch 493 WHERE launch.startup_id = $startup_id 494 AND android_sum_dur_for_startup_and_slice(launch.startup_id, 'bindApplication') > 1250e6 495 496 UNION ALL 497 SELECT 'Time spent in view inflation' as slow_cause, 498 launch.dur as launch_dur, 499 'TIME_SPENT_IN_VIEW_INFLATION' as reason_id, 500 AndroidStartupMetric_ThresholdValue( 501 'value', 450000000, 502 'unit', 'NS', 503 'higher_expected', FALSE) as expected_val, 504 AndroidStartupMetric_ActualValue( 505 'value', android_sum_dur_for_startup_and_slice( 506 launch.startup_id, 'inflate')) as actual_val, 507 get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'inflate', 3) 508 as trace_slices, 509 NULL as trace_threads, 510 NULL as extra 511 FROM android_startups launch 512 WHERE launch.startup_id = $startup_id 513 AND android_sum_dur_for_startup_and_slice(launch.startup_id, 'inflate') > 450e6 514 515 UNION ALL 516 SELECT 'Time spent in ResourcesManager#getResources' as slow_cause, 517 launch.dur as launch_dur, 518 'TIME_SPENT_IN_RESOURCES_MANAGER_GET_RESOURCES' as reason_id, 519 AndroidStartupMetric_ThresholdValue( 520 'value', 130000000, 521 'unit', 'NS', 522 'higher_expected', FALSE) as expected_val, 523 AndroidStartupMetric_ActualValue( 524 'value', android_sum_dur_for_startup_and_slice( 525 launch.startup_id, 'ResourcesManager#getResources')) as actual_val, 526 get_dur_on_main_thread_for_startup_and_slice( 527 launch.startup_id, 'ResourcesManager#getResources', 3) as trace_slices, 528 NULL as trace_threads, 529 NULL as extra 530 FROM android_startups launch 531 WHERE launch.startup_id = $startup_id 532 AND android_sum_dur_for_startup_and_slice( 533 launch.startup_id, 'ResourcesManager#getResources') > 130e6 534 535 UNION ALL 536 SELECT 'Time spent verifying classes' as slow_cause, 537 launch.dur as launch_dur, 538 'TIME_SPENT_VERIFYING_CLASSES' as reason_id, 539 AndroidStartupMetric_ThresholdValue( 540 'value', 15, 541 'unit', 'PERCENTAGE', 542 'higher_expected', FALSE) as expected_val, 543 AndroidStartupMetric_ActualValue( 544 'value', android_sum_dur_for_startup_and_slice( 545 launch.startup_id, 'VerifyClass*') * 100 / launch.dur, 546 'dur', android_sum_dur_for_startup_and_slice( 547 launch.startup_id, 'VerifyClass*')) as actual_val, 548 get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'VerifyClass*', 3) 549 as trace_slices, 550 NULL as trace_threads, 551 NULL as extra 552 FROM android_startups launch 553 WHERE launch.startup_id = $startup_id AND 554 android_sum_dur_for_startup_and_slice(launch.startup_id, 'VerifyClass*') 555 > launch.dur * 0.15 556 557 UNION ALL 558 SELECT 'Potential CPU contention with another process' AS slow_cause, 559 launch.dur as launch_dur, 560 'POTENTIAL_CPU_CONTENTION_WITH_ANOTHER_PROCESS' as reason_id, 561 AndroidStartupMetric_ThresholdValue( 562 'value', 100000000, 563 'unit', 'NS', 564 'higher_expected', FALSE) as expected_val, 565 AndroidStartupMetric_ActualValue( 566 'value', 567 main_thread_time_for_launch_in_runnable_state(launch.startup_id)) as actual_val, 568 NULL as trace_slices, 569 get_main_thread_time_for_launch_in_runnable_state(launch.startup_id, 3) as trace_threads, 570 NULL as extra 571 FROM android_startups launch 572 WHERE launch.startup_id = $startup_id AND 573 main_thread_time_for_launch_in_runnable_state(launch.startup_id) > 100e6 AND 574 most_active_process_for_launch(launch.startup_id) IS NOT NULL 575 576 UNION ALL 577 SELECT 'JIT Activity' as slow_cause, 578 launch.dur as launch_dur, 579 'JIT_ACTIVITY' as reason_id, 580 AndroidStartupMetric_ThresholdValue( 581 'value', 100000000, 582 'unit', 'NS', 583 'higher_expected', FALSE) as expected_val, 584 AndroidStartupMetric_ActualValue( 585 'value', thread_time_for_launch_state_and_thread( 586 launch.startup_id, 'Running', 'Jit thread pool')) as actual_val, 587 NULL as trace_slices, 588 get_thread_time_for_launch_state_and_thread( 589 launch.startup_id, 'Running', 'Jit thread pool', 3) as trace_threads, 590 NULL as extra 591 FROM android_startups launch 592 WHERE launch.startup_id = $startup_id 593 AND thread_time_for_launch_state_and_thread( 594 launch.startup_id, 595 'Running', 596 'Jit thread pool' 597 ) > 100e6 598 599 UNION ALL 600 SELECT 'Main Thread - Lock contention' as slow_cause, 601 launch.dur as launch_dur, 602 'MAIN_THREAD_LOCK_CONTENTION' as reason_id, 603 AndroidStartupMetric_ThresholdValue( 604 'value', 20, 605 'unit', 'PERCENTAGE', 606 'higher_expected', FALSE) as expected_val, 607 AndroidStartupMetric_ActualValue( 608 'value', android_sum_dur_on_main_thread_for_startup_and_slice( 609 launch.startup_id, 'Lock contention on*') * 100 / launch.dur, 610 'dur', android_sum_dur_on_main_thread_for_startup_and_slice( 611 launch.startup_id, 'Lock contention on*')) as actual_val, 612 get_dur_on_main_thread_for_startup_and_slice(launch.startup_id, 'lock contention on*', 3) 613 as trace_slices, 614 NULL as trace_threads, 615 NULL as extra 616 FROM android_startups launch 617 WHERE launch.startup_id = $startup_id 618 AND android_sum_dur_on_main_thread_for_startup_and_slice( 619 launch.startup_id, 620 'Lock contention on*' 621 ) > launch.dur * 0.2 622 623 UNION ALL 624 SELECT 'Main Thread - Monitor contention' as slow_cause, 625 launch.dur as launch_dur, 626 'MAIN_THREAD_MONITOR_CONTENTION' as reason_id, 627 AndroidStartupMetric_ThresholdValue( 628 'value', 15, 629 'unit', 'PERCENTAGE', 630 'higher_expected', FALSE) as expected_val, 631 AndroidStartupMetric_ActualValue( 632 'value', android_sum_dur_on_main_thread_for_startup_and_slice( 633 launch.startup_id, 'Lock contention on a monitor*') * 100 / launch.dur, 634 'dur', android_sum_dur_on_main_thread_for_startup_and_slice( 635 launch.startup_id, 'Lock contention on a monitor*')) as actual_val, 636 get_dur_on_main_thread_for_startup_and_slice( 637 launch.startup_id, 'lock contention on a monitor*', 3) as trace_slices, 638 NULL as trace_threads, 639 NULL as extra 640 FROM android_startups launch 641 WHERE launch.startup_id = $startup_id 642 AND android_sum_dur_on_main_thread_for_startup_and_slice( 643 launch.startup_id, 644 'Lock contention on a monitor*' 645 ) > launch.dur * 0.15 646 647 UNION ALL 648 SELECT 'JIT compiled methods' as slow_cause, 649 launch.dur as launch_dur, 650 'JIT_COMPILED_METHODS' as reason_id, 651 AndroidStartupMetric_ThresholdValue( 652 'value', 65, 653 'unit', 'COUNT', 654 'higher_expected', FALSE) as expected_val, 655 AndroidStartupMetric_ActualValue( 656 'value', (SELECT COUNT(1) 657 FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launch.startup_id, 'JIT compiling*') 658 WHERE thread_name = 'Jit thread pool')) as actual_val, 659 get_slices_for_startup_and_slice_name(launch.startup_id, 'JIT compiling*', 3) 660 as trace_slices, 661 NULL as traced_threads, 662 NULL as extra 663 FROM android_startups launch 664 WHERE launch.startup_id = $startup_id 665 AND ( 666 SELECT COUNT(1) 667 FROM ANDROID_SLICES_FOR_STARTUP_AND_SLICE_NAME(launch.startup_id, 'JIT compiling*') 668 WHERE thread_name = 'Jit thread pool') > 65 669 670 UNION ALL 671 SELECT 'Broadcast dispatched count' as slow_cause, 672 launch.dur as launch_dur, 673 'BROADCAST_DISPATCHED_COUNT' as reason_id, 674 AndroidStartupMetric_ThresholdValue( 675 'value', 15, 676 'unit', 'COUNT', 677 'higher_expected', FALSE) as expected_val, 678 AndroidStartupMetric_ActualValue( 679 'value', count_slices_concurrent_to_launch(launch.startup_id, 680 'Broadcast dispatched*')) as actual_val, 681 get_slices_concurrent_to_launch(launch.startup_id, 'Broadcast dispatched*', 3) 682 as trace_slices, 683 NULL as trace_threads, 684 NULL as extra 685 FROM android_startups launch 686 WHERE launch.startup_id = $startup_id 687 AND count_slices_concurrent_to_launch( 688 launch.startup_id, 689 'Broadcast dispatched*') > 15 690 691 UNION ALL 692 SELECT 'Broadcast received count' as slow_cause, 693 launch.dur as launch_dur, 694 'BROADCAST_RECEIVED_COUNT' as reason_id, 695 AndroidStartupMetric_ThresholdValue( 696 'value', 50, 697 'unit', 'COUNT', 698 'higher_expected', FALSE) as expected_val, 699 AndroidStartupMetric_ActualValue( 700 'value', count_slices_concurrent_to_launch(launch.startup_id, 701 'broadcastReceiveReg*')) as actual_val, 702 get_slices_concurrent_to_launch(launch.startup_id, 'broadcastReceiveReg*', 3) 703 as trace_slices, 704 NULL as trace_threads, 705 NULL as extra 706 FROM android_startups launch 707 WHERE launch.startup_id = $startup_id 708 AND count_slices_concurrent_to_launch( 709 launch.startup_id, 710 'broadcastReceiveReg*') > 50 711 712 UNION ALL 713 SELECT 'Startup running concurrent to launch' as slow_cause, 714 launch.dur as launch_dur, 715 'STARTUP_RUNNING_CONCURRENT' as reason_id, 716 AndroidStartupMetric_ThresholdValue( 717 'value', FALSE, 718 'unit', 'TRUE_OR_FALSE') as expected_val, 719 AndroidStartupMetric_ActualValue( 720 'value', TRUE) as actual_val, 721 NULL as trace_slices, 722 NULL as trace_threads, 723 'Package: ' || ( 724 SELECT package 725 FROM android_startups l 726 WHERE l.startup_id != launch.startup_id 727 AND _is_spans_overlapping(l.ts, l.ts_end, launch.ts, launch.ts_end) 728 LIMIT 1) as extra 729 FROM android_startups launch 730 WHERE launch.startup_id = $startup_id 731 AND EXISTS( 732 SELECT package 733 FROM android_startups l 734 WHERE l.startup_id != launch.startup_id 735 AND _is_spans_overlapping(l.ts, l.ts_end, launch.ts, launch.ts_end)) 736 737 UNION ALL 738 SELECT 'Main Thread - Binder transactions blocked' as slow_cause, 739 launch.dur as launch_dur, 740 'MAIN_THREAD_BINDER_TRANSCATIONS_BLOCKED' as reason_id, 741 AndroidStartupMetric_ThresholdValue( 742 'value', FALSE, 743 'unit', 'TRUE_OR_FALSE') as expected_val, 744 AndroidStartupMetric_ActualValue( 745 'value', TRUE) as actual_val, 746 get_main_thread_binder_transactions_blocked(launch.startup_id, 2e7, 3) as trace_slices, 747 NULL as trace_threads, 748 NULL as extra 749 FROM android_startups launch 750 WHERE launch.startup_id = $startup_id 751 AND ( 752 SELECT COUNT(1) 753 FROM BINDER_TRANSACTION_REPLY_SLICES_FOR_LAUNCH(launch.startup_id, 2e7)) > 0 754 ); 755