1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2023 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 {Trace} from '../../public/trace'; 17*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin'; 18*6dbdd20aSAndroid Build Coastguard Workerimport {ActiveCPUCountTrack, CPUType} from './active_cpu_count'; 19*6dbdd20aSAndroid Build Coastguard Workerimport { 20*6dbdd20aSAndroid Build Coastguard Worker RunnableThreadCountTrack, 21*6dbdd20aSAndroid Build Coastguard Worker UninterruptibleSleepThreadCountTrack, 22*6dbdd20aSAndroid Build Coastguard Worker} from './thread_count'; 23*6dbdd20aSAndroid Build Coastguard Worker 24*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin { 25*6dbdd20aSAndroid Build Coastguard Worker static readonly id = 'dev.perfetto.Sched'; 26*6dbdd20aSAndroid Build Coastguard Worker async onTraceLoad(ctx: Trace) { 27*6dbdd20aSAndroid Build Coastguard Worker const runnableThreadCountUri = `/runnable_thread_count`; 28*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 29*6dbdd20aSAndroid Build Coastguard Worker uri: runnableThreadCountUri, 30*6dbdd20aSAndroid Build Coastguard Worker title: 'Runnable thread count', 31*6dbdd20aSAndroid Build Coastguard Worker track: new RunnableThreadCountTrack(ctx, runnableThreadCountUri), 32*6dbdd20aSAndroid Build Coastguard Worker }); 33*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 34*6dbdd20aSAndroid Build Coastguard Worker id: 'dev.perfetto.Sched.AddRunnableThreadCountTrackCommand', 35*6dbdd20aSAndroid Build Coastguard Worker name: 'Add track: runnable thread count', 36*6dbdd20aSAndroid Build Coastguard Worker callback: () => 37*6dbdd20aSAndroid Build Coastguard Worker addPinnedTrack(ctx, runnableThreadCountUri, 'Runnable thread count'), 38*6dbdd20aSAndroid Build Coastguard Worker }); 39*6dbdd20aSAndroid Build Coastguard Worker 40*6dbdd20aSAndroid Build Coastguard Worker const uninterruptibleSleepThreadCountUri = `/uninterruptible_sleep_thread_count`; 41*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 42*6dbdd20aSAndroid Build Coastguard Worker uri: uninterruptibleSleepThreadCountUri, 43*6dbdd20aSAndroid Build Coastguard Worker title: 'Uninterruptible Sleep thread count', 44*6dbdd20aSAndroid Build Coastguard Worker track: new UninterruptibleSleepThreadCountTrack( 45*6dbdd20aSAndroid Build Coastguard Worker ctx, 46*6dbdd20aSAndroid Build Coastguard Worker uninterruptibleSleepThreadCountUri, 47*6dbdd20aSAndroid Build Coastguard Worker ), 48*6dbdd20aSAndroid Build Coastguard Worker }); 49*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 50*6dbdd20aSAndroid Build Coastguard Worker id: 'dev.perfetto.Sched.AddUninterruptibleSleepThreadCountTrackCommand', 51*6dbdd20aSAndroid Build Coastguard Worker name: 'Add track: uninterruptible sleep thread count', 52*6dbdd20aSAndroid Build Coastguard Worker callback: () => 53*6dbdd20aSAndroid Build Coastguard Worker addPinnedTrack( 54*6dbdd20aSAndroid Build Coastguard Worker ctx, 55*6dbdd20aSAndroid Build Coastguard Worker uninterruptibleSleepThreadCountUri, 56*6dbdd20aSAndroid Build Coastguard Worker 'Uninterruptible Sleep thread count', 57*6dbdd20aSAndroid Build Coastguard Worker ), 58*6dbdd20aSAndroid Build Coastguard Worker }); 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Worker const uri = uriForActiveCPUCountTrack(); 61*6dbdd20aSAndroid Build Coastguard Worker const title = 'Active CPU count'; 62*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 63*6dbdd20aSAndroid Build Coastguard Worker uri, 64*6dbdd20aSAndroid Build Coastguard Worker title: title, 65*6dbdd20aSAndroid Build Coastguard Worker track: new ActiveCPUCountTrack({trackUri: uri}, ctx), 66*6dbdd20aSAndroid Build Coastguard Worker }); 67*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 68*6dbdd20aSAndroid Build Coastguard Worker id: 'dev.perfetto.Sched.AddActiveCPUCountTrackCommand', 69*6dbdd20aSAndroid Build Coastguard Worker name: 'Add track: active CPU count', 70*6dbdd20aSAndroid Build Coastguard Worker callback: () => addPinnedTrack(ctx, uri, title), 71*6dbdd20aSAndroid Build Coastguard Worker }); 72*6dbdd20aSAndroid Build Coastguard Worker 73*6dbdd20aSAndroid Build Coastguard Worker for (const cpuType of Object.values(CPUType)) { 74*6dbdd20aSAndroid Build Coastguard Worker const uri = uriForActiveCPUCountTrack(cpuType); 75*6dbdd20aSAndroid Build Coastguard Worker const title = `Active ${cpuType} CPU count`; 76*6dbdd20aSAndroid Build Coastguard Worker ctx.tracks.registerTrack({ 77*6dbdd20aSAndroid Build Coastguard Worker uri, 78*6dbdd20aSAndroid Build Coastguard Worker title: title, 79*6dbdd20aSAndroid Build Coastguard Worker track: new ActiveCPUCountTrack({trackUri: uri}, ctx, cpuType), 80*6dbdd20aSAndroid Build Coastguard Worker }); 81*6dbdd20aSAndroid Build Coastguard Worker 82*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 83*6dbdd20aSAndroid Build Coastguard Worker id: `dev.perfetto.Sched.AddActiveCPUCountTrackCommand.${cpuType}`, 84*6dbdd20aSAndroid Build Coastguard Worker name: `Add track: active ${cpuType} CPU count`, 85*6dbdd20aSAndroid Build Coastguard Worker callback: () => addPinnedTrack(ctx, uri, title), 86*6dbdd20aSAndroid Build Coastguard Worker }); 87*6dbdd20aSAndroid Build Coastguard Worker } 88*6dbdd20aSAndroid Build Coastguard Worker } 89*6dbdd20aSAndroid Build Coastguard Worker} 90*6dbdd20aSAndroid Build Coastguard Worker 91*6dbdd20aSAndroid Build Coastguard Workerfunction uriForActiveCPUCountTrack(cpuType?: CPUType): string { 92*6dbdd20aSAndroid Build Coastguard Worker const prefix = `/active_cpus`; 93*6dbdd20aSAndroid Build Coastguard Worker if (cpuType !== undefined) { 94*6dbdd20aSAndroid Build Coastguard Worker return `${prefix}_${cpuType}`; 95*6dbdd20aSAndroid Build Coastguard Worker } else { 96*6dbdd20aSAndroid Build Coastguard Worker return prefix; 97*6dbdd20aSAndroid Build Coastguard Worker } 98*6dbdd20aSAndroid Build Coastguard Worker} 99*6dbdd20aSAndroid Build Coastguard Worker 100*6dbdd20aSAndroid Build Coastguard Workerfunction addPinnedTrack(ctx: Trace, uri: string, title: string) { 101*6dbdd20aSAndroid Build Coastguard Worker const track = new TrackNode({uri, title}); 102*6dbdd20aSAndroid Build Coastguard Worker // Add track to the top of the stack 103*6dbdd20aSAndroid Build Coastguard Worker ctx.workspace.addChildFirst(track); 104*6dbdd20aSAndroid Build Coastguard Worker track.pin(); 105*6dbdd20aSAndroid Build Coastguard Worker} 106