• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1--
2-- Copyright 2024 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
16INCLUDE PERFETTO MODULE linux.cpu.frequency;
17
18-- Returns the timestamp of the start of the partition that contains the |ts|.
19CREATE PERFETTO FUNCTION _partition_start(
20    ts TIMESTAMP,
21    size LONG
22)
23RETURNS LONG AS
24-- Division of two ints would result in floor(ts/size).
25SELECT
26  (
27    $ts / $size
28  ) * $size;
29
30-- Returns the number of partitions required to cover all of the trace
31-- timestamps.
32CREATE PERFETTO FUNCTION _partition_count(
33    size LONG
34)
35RETURNS LONG AS
36SELECT
37  (
38    _partition_start(trace_end(), $size) - _partition_start(trace_start(), $size)
39  ) / $size + 1;
40
41-- Returns a table of partitions with first partition containing the
42-- TRACE_START() and last one containing TRACE_END().
43CREATE PERFETTO FUNCTION _partitions(
44    size LONG
45)
46RETURNS TABLE (
47  ts TIMESTAMP,
48  ts_end LONG
49) AS
50WITH
51  no_ends AS (
52    SELECT
53      _partition_start(trace_start(), $size) + (
54        id * $size
55      ) AS ts
56    -- We are using the sched table for source of ids. If the table is too small
57    -- for specified size, the results would be invalid none the less.
58    FROM sched
59    LIMIT _partition_count($size)
60  )
61SELECT
62  ts,
63  ts + $size AS ts_end
64FROM no_ends;
65
66-- Partitions any |intervals| table with partitions defined in the |partitions|
67-- table.
68CREATE PERFETTO MACRO _interval_partitions(
69    -- Requires |ts| and |ts_end| columns.
70    partitions TableOrSubquery,
71    -- Requires |ts| and |ts_end| column.
72    intervals TableOrSubquery
73)
74RETURNS TableOrSubquery AS
75(
76  SELECT
77    p.ts AS partition_ts,
78    iif(i.ts_end < p.ts_end, i.ts_end, p.ts_end) AS ts_end,
79    iif(i.ts < p.ts, p.ts, i.ts) AS ts
80  FROM $intervals AS i
81  JOIN $partitions AS p
82    ON (
83      p.ts <= i.ts AND i.ts < p.ts_end
84    )
85);
86
87-- Returns a table of utilization per given period.
88-- Utilization is calculated as sum of average utilization of each CPU in each
89-- period, which is defined as a multiply of |interval|. For this reason
90-- first and last period might have lower then real utilization.
91CREATE PERFETTO MACRO _cpu_avg_utilization_per_period(
92    -- Length of the period on which utilization should be averaged.
93    interval Expr,
94    -- Either sched table or its filtered down version.
95    sched_table TableOrSubquery
96)
97-- The returned table has the schema (ts TIMESTAMP, utilization DOUBLE,
98-- unnormalized_utilization DOUBLE).
99RETURNS TableOrSubquery AS
100(
101  SELECT
102    partition_ts AS ts,
103    sum(ts_end - ts) / (
104      cast_double!($interval) * (
105        SELECT
106          max(cpu) + 1
107        FROM sched
108      )
109    ) AS utilization,
110    sum(ts_end - ts) / cast_double!($interval) AS unnormalized_utilization
111  FROM _interval_partitions!(_partitions($interval), $sched_table)
112  GROUP BY
113    1
114);
115
116CREATE PERFETTO VIEW _cpu_freq_for_metrics AS
117SELECT
118  id,
119  ts,
120  dur,
121  cpu,
122  ucpu,
123  freq
124FROM cpu_frequency_counters
125WHERE
126  freq IS NOT NULL;
127
128CREATE PERFETTO VIEW _sched_without_id AS
129SELECT
130  ts,
131  dur,
132  utid,
133  ucpu
134FROM sched
135WHERE
136  NOT utid IN (
137    SELECT
138      utid
139    FROM thread
140    WHERE
141      is_idle
142  ) AND dur != -1;
143
144CREATE VIRTUAL TABLE _cpu_freq_per_thread_span_join USING SPAN_LEFT_JOIN (
145    _sched_without_id PARTITIONED ucpu,
146    _cpu_freq_for_metrics PARTITIONED ucpu);
147
148CREATE PERFETTO TABLE _cpu_freq_per_thread_no_id AS
149SELECT
150  *
151FROM _cpu_freq_per_thread_span_join;
152
153CREATE PERFETTO VIEW _cpu_freq_per_thread AS
154SELECT
155  _auto_id AS id,
156  ts,
157  dur,
158  ucpu,
159  cpu,
160  utid,
161  freq,
162  id AS counter_id
163FROM _cpu_freq_per_thread_no_id;
164