• 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
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