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 NOT utid IN ( 54 SELECT utid FROM thread WHERE is_idle 55) 56GROUP BY 1, 2; 57 58-- Given a launch id and core type, returns the number of mcycles consumed 59-- on CPUs of that core type during the launch. 60CREATE OR REPLACE PERFETTO FUNCTION mcycles_for_launch_and_core_type(startup_id INT, core_type STRING) 61RETURNS INT AS 62SELECT mcycles 63FROM mcycles_per_core_type_per_launch m 64WHERE m.startup_id = $startup_id AND m.core_type = $core_type; 65 66-- Contains the process using the most mcycles during the launch 67-- *excluding the process being started*. 68-- Materialized to avoid span-joining once per launch. 69DROP TABLE IF EXISTS top_mcyles_process_excluding_started_per_launch; 70CREATE PERFETTO TABLE top_mcyles_process_excluding_started_per_launch AS 71WITH mcycles_per_launch_and_process AS MATERIALIZED ( 72 SELECT 73 startup_id, 74 upid, 75 CAST(SUM(dur * freq_khz / 1000) / 1e9 AS INT) AS mcycles 76 FROM cpu_freq_sched_per_thread_per_launch c 77 JOIN thread USING (utid) 78 JOIN process USING (upid) 79 WHERE 80 NOT is_idle 81 AND upid NOT IN ( 82 SELECT upid 83 FROM android_startup_processes l 84 ) 85 GROUP BY startup_id, upid 86) 87SELECT * 88FROM ( 89 SELECT 90 *, 91 ROW_NUMBER() OVER (PARTITION BY startup_id ORDER BY mcycles DESC) AS mcycles_rank 92 FROM mcycles_per_launch_and_process 93) 94WHERE mcycles_rank <= 5; 95 96-- Given a launch id, returns the name of the processes consuming the most 97-- mcycles during the launch excluding the process being started. 98CREATE OR REPLACE PERFETTO FUNCTION n_most_active_process_names_for_launch(startup_id INT) 99RETURNS STRING AS 100SELECT RepeatedField(process_name) 101FROM ( 102 SELECT IFNULL(process.name, "[NULL]") AS process_name 103 FROM top_mcyles_process_excluding_started_per_launch 104 JOIN process USING (upid) 105 WHERE startup_id = $startup_id 106 ORDER BY mcycles DESC 107); 108 109-- Given a launch id, returns the most active process name. 110CREATE OR REPLACE PERFETTO FUNCTION most_active_process_for_launch(startup_id INT) 111RETURNS STRING AS 112SELECT process.name AS process_name 113FROM top_mcyles_process_excluding_started_per_launch 114JOIN process USING (upid) 115WHERE startup_id = $startup_id 116ORDER BY mcycles DESC 117LIMIT 1; 118