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