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