• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
138-- Ensure we always get the previous clock tick for duration in
139-- android_thread_time_in_state_event_raw.
140DROP VIEW IF EXISTS android_thread_time_in_state_event_clock;
141CREATE VIEW android_thread_time_in_state_event_clock AS
142SELECT
143  ts,
144  LAG(ts) OVER (ORDER BY ts) AS lag_ts
145FROM (
146  SELECT DISTINCT ts from android_thread_time_in_state_base
147);
148
149DROP VIEW IF EXISTS android_thread_time_in_state_event_raw;
150CREATE VIEW android_thread_time_in_state_event_raw AS
151SELECT
152  ts,
153  ts - lag_ts AS dur,
154  upid,
155  core_type,
156  utid,
157  -- We need globally unique track names so add the utid even when we
158  -- know the name. But when we don't, also use the tid because that's what
159  -- the rest of the UI does.
160  IFNULL(thread.name, 'Thread ' || thread.tid) || ' (' || thread.utid || ')'
161      AS thread_track_name,
162  freq,
163  runtime_ms_counter - LAG(runtime_ms_counter)
164      OVER (PARTITION BY core_type, utid, freq ORDER BY ts) AS runtime_ms
165FROM android_thread_time_in_state_base
166    -- Join to keep only utids which have non-zero runtime in the trace.
167    JOIN android_thread_time_in_state_counters USING (utid, core_type)
168    JOIN android_thread_time_in_state_event_clock USING(ts)
169    JOIN thread using (utid);
170
171DROP VIEW IF EXISTS android_thread_time_in_state_event_thread;
172CREATE VIEW android_thread_time_in_state_event_thread AS
173SELECT
174  'counter' AS track_type,
175  thread_track_name || ' (' || core_type || ' core)' as track_name,
176  ts,
177  dur,
178  upid,
179  sum(runtime_ms * freq) as ms_freq
180FROM android_thread_time_in_state_event_raw
181WHERE runtime_ms IS NOT NULL
182  AND dur != 0
183GROUP BY track_type, track_name, ts, dur, upid;
184
185DROP VIEW IF EXISTS android_thread_time_in_state_event_global;
186CREATE VIEW android_thread_time_in_state_event_global AS
187SELECT
188  'counter' AS track_type,
189  'Total ' || core_type || ' core cycles / sec' as track_name,
190  ts,
191  dur,
192  0 AS upid,
193  SUM(runtime_ms * freq) AS ms_freq
194FROM android_thread_time_in_state_event_raw
195WHERE runtime_ms IS NOT NULL
196GROUP BY ts, track_name;
197
198DROP TABLE IF EXISTS android_thread_time_in_state_event;
199CREATE TABLE android_thread_time_in_state_event AS
200SELECT track_type, track_name, ts, dur, upid, ms_freq * 1000000 / dur AS value
201FROM android_thread_time_in_state_event_thread
202UNION ALL
203SELECT track_type, track_name, ts, dur, upid, ms_freq * 1000000 / dur AS value
204FROM android_thread_time_in_state_event_global
205-- Biggest values at top of list in UI.
206ORDER BY value DESC;
207