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