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 19-- Create the base CPU span join table. 20SELECT RUN_METRIC('android/android_cpu_agg.sql'); 21SELECT RUN_METRIC('android/cpu_info.sql'); 22 23-- Create a span join safe launches view; since both views 24-- being span joined have an "id" column, we need to rename 25-- the id column for launches to disambiguate the two. 26DROP VIEW IF EXISTS android_launches_span_join_safe; 27CREATE PERFETTO VIEW android_launches_span_join_safe AS 28SELECT ts, dur, startup_id 29FROM android_startups; 30 31DROP VIEW IF EXISTS launches_span_join_safe; 32CREATE PERFETTO VIEW launches_span_join_safe AS 33SELECT startup_id AS launch_id, * FROM android_launches_span_join_safe; 34 35-- Span join the CPU table with the launches table to get the 36-- breakdown per-cpu. 37DROP TABLE IF EXISTS cpu_freq_sched_per_thread_per_launch; 38CREATE VIRTUAL TABLE cpu_freq_sched_per_thread_per_launch 39USING SPAN_JOIN( 40 android_launches_span_join_safe, 41 cpu_freq_sched_per_thread PARTITIONED cpu 42); 43 44-- Materialized to avoid span-joining once per core type. 45DROP TABLE IF EXISTS mcycles_per_core_type_per_launch; 46CREATE PERFETTO TABLE mcycles_per_core_type_per_launch AS 47SELECT 48 startup_id, 49 IFNULL(core_type_per_cpu.core_type, 'unknown') AS core_type, 50 CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles 51FROM cpu_freq_sched_per_thread_per_launch 52LEFT JOIN core_type_per_cpu USING (cpu) 53WHERE utid != 0 54GROUP BY 1, 2; 55 56-- Given a launch id and core type, returns the number of mcycles consumed 57-- on CPUs of that core type during the launch. 58CREATE OR REPLACE PERFETTO FUNCTION mcycles_for_launch_and_core_type(startup_id INT, core_type STRING) 59RETURNS INT AS 60SELECT mcycles 61FROM mcycles_per_core_type_per_launch m 62WHERE m.startup_id = $startup_id AND m.core_type = $core_type; 63 64-- Contains the process using the most mcycles during the launch 65-- *excluding the process being started*. 66-- Materialized to avoid span-joining once per launch. 67DROP TABLE IF EXISTS top_mcyles_process_excluding_started_per_launch; 68CREATE PERFETTO TABLE top_mcyles_process_excluding_started_per_launch AS 69WITH mcycles_per_launch_and_process AS MATERIALIZED ( 70 SELECT 71 startup_id, 72 upid, 73 CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles 74 FROM cpu_freq_sched_per_thread_per_launch c 75 JOIN thread USING (utid) 76 JOIN process USING (upid) 77 WHERE 78 utid != 0 79 AND upid NOT IN ( 80 SELECT upid 81 FROM android_startup_processes l 82 ) 83 GROUP BY startup_id, upid 84) 85SELECT * 86FROM ( 87 SELECT 88 *, 89 ROW_NUMBER() OVER (PARTITION BY startup_id ORDER BY mcycles DESC) AS mcycles_rank 90 FROM mcycles_per_launch_and_process 91) 92WHERE mcycles_rank <= 5; 93 94-- Given a launch id, returns the name of the processes consuming the most 95-- mcycles during the launch excluding the process being started. 96CREATE OR REPLACE PERFETTO FUNCTION n_most_active_process_names_for_launch(startup_id INT) 97RETURNS STRING AS 98SELECT RepeatedField(process_name) 99FROM ( 100 SELECT IFNULL(process.name, "[NULL]") AS process_name 101 FROM top_mcyles_process_excluding_started_per_launch 102 JOIN process USING (upid) 103 WHERE startup_id = $startup_id 104 ORDER BY mcycles DESC 105); 106 107-- Given a launch id, returns the most active process name. 108CREATE OR REPLACE PERFETTO FUNCTION most_active_process_for_launch(startup_id INT) 109RETURNS STRING AS 110SELECT process.name AS process_name 111FROM top_mcyles_process_excluding_started_per_launch 112JOIN process USING (upid) 113WHERE startup_id = $startup_id 114ORDER BY mcycles DESC 115LIMIT 1; 116