xref: /aosp_15_r20/external/perfetto/ui/src/plugins/dev.perfetto.CpuFreq/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2021 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15import {TrackNode} from '../../public/workspace';
16import {CPU_FREQ_TRACK_KIND} from '../../public/track_kinds';
17import {Trace} from '../../public/trace';
18import {PerfettoPlugin} from '../../public/plugin';
19import {NUM, NUM_NULL} from '../../trace_processor/query_result';
20import {CpuFreqTrack} from './cpu_freq_track';
21
22export default class implements PerfettoPlugin {
23  static readonly id = 'dev.perfetto.CpuFreq';
24  async onTraceLoad(ctx: Trace): Promise<void> {
25    const {engine} = ctx;
26
27    const cpus = [];
28    const cpusResult = await engine.query(
29      'select distinct cpu from cpu_counter_track order by cpu;',
30    );
31    for (const it = cpusResult.iter({cpu: NUM}); it.valid(); it.next()) {
32      cpus.push(it.cpu);
33    }
34
35    const maxCpuFreqResult = await engine.query(`
36      select ifnull(max(value), 0) as freq
37      from counter c
38      join cpu_counter_track t on c.track_id = t.id
39      join _counter_track_summary s on t.id = s.id
40      where name = 'cpufreq';
41    `);
42    const maxCpuFreq = maxCpuFreqResult.firstRow({freq: NUM}).freq;
43
44    for (const cpu of cpus) {
45      // Only add a cpu freq track if we have cpu freq data.
46      const cpuFreqIdleResult = await engine.query(`
47        select
48          id as cpuFreqId,
49          (
50            select id
51            from cpu_counter_track
52            where name = 'cpuidle'
53            and cpu = ${cpu}
54            limit 1
55          ) as cpuIdleId
56        from cpu_counter_track
57        join _counter_track_summary using (id)
58        where name = 'cpufreq' and cpu = ${cpu}
59        limit 1;
60      `);
61
62      if (cpuFreqIdleResult.numRows() > 0) {
63        const row = cpuFreqIdleResult.firstRow({
64          cpuFreqId: NUM,
65          cpuIdleId: NUM_NULL,
66        });
67        const freqTrackId = row.cpuFreqId;
68        const idleTrackId = row.cpuIdleId === null ? undefined : row.cpuIdleId;
69
70        const config = {
71          cpu,
72          maximumValue: maxCpuFreq,
73          freqTrackId,
74          idleTrackId,
75        };
76
77        const uri = `/cpu_freq_cpu${cpu}`;
78        const title = `Cpu ${cpu} Frequency`;
79        ctx.tracks.registerTrack({
80          uri,
81          title,
82          tags: {
83            kind: CPU_FREQ_TRACK_KIND,
84            cpu,
85          },
86          track: new CpuFreqTrack(config, ctx),
87        });
88        const trackNode = new TrackNode({uri, title, sortOrder: -40});
89        ctx.workspace.addChildInOrder(trackNode);
90      }
91    }
92  }
93}
94