xref: /aosp_15_r20/external/perfetto/ui/src/plugins/dev.perfetto.CpuidleTimeInState/index.ts (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1// Copyright (C) 2024 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 {Trace} from '../../public/trace';
16import {PerfettoPlugin} from '../../public/plugin';
17import {CounterOptions} from '../../components/tracks/base_counter_track';
18import {TrackNode} from '../../public/workspace';
19import {createQueryCounterTrack} from '../../components/tracks/query_counter_track';
20
21export default class implements PerfettoPlugin {
22  static readonly id = 'dev.perfetto.CpuidleTimeInState';
23  private async addCounterTrack(
24    ctx: Trace,
25    name: string,
26    query: string,
27    group?: TrackNode,
28    options?: Partial<CounterOptions>,
29  ) {
30    const uri = `/cpuidle_time_in_state_${name}`;
31    const track = await createQueryCounterTrack({
32      trace: ctx,
33      uri,
34      data: {
35        sqlSource: query,
36        columns: ['ts', 'value'],
37      },
38      columns: {ts: 'ts', value: 'value'},
39      options,
40    });
41    ctx.tracks.registerTrack({
42      uri,
43      title: name,
44      track,
45    });
46    const trackNode = new TrackNode({uri, title: name});
47    if (group) {
48      group.addChildInOrder(trackNode);
49    }
50  }
51
52  async onTraceLoad(ctx: Trace): Promise<void> {
53    const group = new TrackNode({
54      title: 'Cpuidle Time In State',
55      isSummary: true,
56    });
57
58    const e = ctx.engine;
59    await e.query(`INCLUDE PERFETTO MODULE linux.cpu.idle_time_in_state;`);
60    const result = await e.query(
61      `select distinct state_name from cpu_idle_time_in_state_counters`,
62    );
63    const it = result.iter({state_name: 'str'});
64    for (; it.valid(); it.next()) {
65      this.addCounterTrack(
66        ctx,
67        it.state_name,
68        `
69          select
70            ts,
71            idle_percentage as value
72          from cpu_idle_time_in_state_counters
73          where state_name = '${it.state_name}'
74        `,
75        group,
76        {unit: 'percent'},
77      );
78    }
79    if (group.hasChildren) {
80      ctx.workspace.addChildInOrder(group);
81    }
82  }
83}
84