1-- 2-- Copyright 2020 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 17SELECT RUN_METRIC('android/cpu_info.sql'); 18SELECT RUN_METRIC('android/process_metadata.sql'); 19 20DROP TABLE IF EXISTS android_thread_time_in_state_base; 21CREATE TABLE android_thread_time_in_state_base AS 22SELECT 23 base.*, 24 IFNULL(core_type_per_cpu.core_type, 'unknown') core_type 25FROM ( 26 SELECT 27 ts, 28 utid, 29 EXTRACT_ARG(counter.arg_set_id, 'time_in_state_cpu_id') AS 30 time_in_state_cpu, 31 EXTRACT_ARG(counter.arg_set_id, 'freq') AS freq, 32 CAST(value AS INT) AS runtime_ms_counter 33 FROM counter 34 JOIN thread_counter_track ON (counter.track_id = thread_counter_track.id) 35 WHERE thread_counter_track.name = 'time_in_state' 36) base 37LEFT JOIN core_type_per_cpu ON (cpu = time_in_state_cpu); 38 39DROP VIEW IF EXISTS android_thread_time_in_state_raw; 40CREATE VIEW android_thread_time_in_state_raw AS 41SELECT 42 utid, 43 time_in_state_cpu, 44 core_type, 45 freq, 46 MAX(runtime_ms_counter) - MIN(runtime_ms_counter) runtime_ms_diff 47FROM android_thread_time_in_state_base 48GROUP BY utid, time_in_state_cpu, core_type, freq; 49 50DROP TABLE IF EXISTS android_thread_time_in_state_counters; 51CREATE TABLE android_thread_time_in_state_counters AS 52SELECT 53 utid, 54 raw.time_in_state_cpu, 55 raw.core_type, 56 SUM(runtime_ms_diff) AS runtime_ms, 57 SUM(raw.freq * runtime_ms_diff / 1000000) AS mcycles, 58 SUM(power * runtime_ms_diff / 3600000) AS power_profile_mah 59FROM android_thread_time_in_state_raw AS raw 60 LEFT OUTER JOIN cpu_cluster_power AS power USING(core_type, freq) 61GROUP BY utid, raw.time_in_state_cpu, raw.core_type 62HAVING runtime_ms > 0; 63 64DROP VIEW IF EXISTS android_thread_time_in_state_thread_metrics; 65CREATE VIEW android_thread_time_in_state_thread_metrics AS 66SELECT 67 utid, 68 RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType( 69 'time_in_state_cpu', time_in_state_cpu, 70 'core_type', core_type, 71 'runtime_ms', runtime_ms, 72 'mcycles', CAST(mcycles AS INT), 73 'power_profile_mah', power_profile_mah 74 )) metrics 75FROM android_thread_time_in_state_counters 76GROUP BY utid; 77 78DROP VIEW IF EXISTS android_thread_time_in_state_threads; 79CREATE VIEW android_thread_time_in_state_threads AS 80SELECT 81 upid, 82 RepeatedField(AndroidThreadTimeInStateMetric_Thread( 83 'name', 84 thread.name, 85 'main_thread', 86 thread.is_main_thread, 87 'metrics_by_core_type', 88 android_thread_time_in_state_thread_metrics.metrics 89 )) threads 90FROM thread 91JOIN android_thread_time_in_state_thread_metrics USING (utid) 92GROUP BY upid; 93 94DROP VIEW IF EXISTS android_thread_time_in_state_process_metrics; 95CREATE VIEW android_thread_time_in_state_process_metrics AS 96WITH process_counters AS ( 97 SELECT 98 upid, 99 time_in_state_cpu, 100 core_type, 101 SUM(runtime_ms) AS runtime_ms, 102 SUM(mcycles) AS mcycles, 103 SUM(power_profile_mah) AS power_profile_mah 104 FROM android_thread_time_in_state_counters 105 JOIN thread USING (utid) 106 GROUP BY upid, time_in_state_cpu, core_type 107) 108SELECT 109 upid, 110 RepeatedField(AndroidThreadTimeInStateMetric_MetricsByCoreType( 111 'time_in_state_cpu', time_in_state_cpu, 112 'core_type', core_type, 113 'runtime_ms', runtime_ms, 114 'mcycles', CAST(mcycles AS INT), 115 'power_profile_mah', power_profile_mah 116 )) metrics 117FROM process_counters 118GROUP BY upid; 119 120DROP VIEW IF EXISTS android_thread_time_in_state_output; 121CREATE VIEW android_thread_time_in_state_output AS 122SELECT AndroidThreadTimeInStateMetric( 123 'processes', ( 124 SELECT 125 RepeatedField(AndroidThreadTimeInStateMetric_Process( 126 'metadata', metadata, 127 'metrics_by_core_type', 128 android_thread_time_in_state_process_metrics.metrics, 129 'threads', android_thread_time_in_state_threads.threads 130 )) 131 FROM process 132 JOIN process_metadata USING (upid) 133 JOIN android_thread_time_in_state_process_metrics USING (upid) 134 JOIN android_thread_time_in_state_threads USING (upid) 135 ) 136); 137 138DROP VIEW IF EXISTS android_thread_time_in_state_event_raw; 139CREATE VIEW android_thread_time_in_state_event_raw AS 140SELECT 141 ts, 142 utid, 143 core_type, 144 freq, 145 time_in_state_cpu, 146 runtime_ms_counter - LAG(runtime_ms_counter) OVER win AS runtime_ms_diff 147FROM android_thread_time_in_state_base 148WINDOW win AS (PARTITION BY utid, core_type, time_in_state_cpu, freq ORDER BY ts); 149 150DROP VIEW IF EXISTS android_thread_time_in_state_by_core_type; 151CREATE VIEW android_thread_time_in_state_by_core_type AS 152SELECT 153 ts, 154 utid, 155 core_type, 156 freq, 157 SUM(runtime_ms_diff) runtime_ms_diff 158FROM android_thread_time_in_state_event_raw 159GROUP BY ts, utid, core_type, freq 160HAVING runtime_ms_diff > 0; 161 162DROP VIEW IF EXISTS android_thread_time_in_state_event_thread; 163CREATE VIEW android_thread_time_in_state_event_thread AS 164SELECT 165 -- We need globally unique track names so add the utid even when we 166 -- know the name. But when we don't, also use the tid because that's what 167 -- the rest of the UI does. 168 IFNULL(thread.name, 'Thread ' || thread.tid) || ' (' || thread.utid || ')' 169 || ' (' || core_type || ' core) mcycles' AS track_name, 170 ts, 171 upid, 172 SUM(runtime_ms_diff * freq) OVER win AS cycles 173FROM android_thread_time_in_state_by_core_type 174JOIN thread USING (utid) 175GROUP BY ts, upid, track_name 176WINDOW win AS (PARTITION BY utid ORDER BY ts); 177 178DROP VIEW IF EXISTS android_thread_time_in_state_event_global; 179CREATE VIEW android_thread_time_in_state_event_global AS 180SELECT 181 'Total ' || core_type || ' core mcycles' as track_name, 182 ts, 183 0 AS upid, 184 SUM(runtime_ms_diff * freq) OVER win as cycles 185FROM android_thread_time_in_state_by_core_type 186GROUP BY ts, track_name 187WINDOW win AS (ORDER BY ts); 188 189DROP TABLE IF EXISTS android_thread_time_in_state_event; 190CREATE TABLE android_thread_time_in_state_event AS 191SELECT 'counter' as track_type, track_name, upid, ts, cycles / 1000000.0 AS value 192FROM android_thread_time_in_state_event_thread 193UNION ALL 194SELECT 'counter' as track_type, track_name, upid, ts, cycles / 1000000.0 AS value 195FROM android_thread_time_in_state_event_global 196-- Biggest values at top of list in UI. 197ORDER BY value DESC; 198