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