1*6dbdd20aSAndroid Build Coastguard Worker// Copyright (C) 2024 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 {getThreadInfo, ThreadInfo} from '../../components/sql_utils/thread'; 16*6dbdd20aSAndroid Build Coastguard Workerimport {addDebugSliceTrack} from '../../components/tracks/debug_tracks'; 17*6dbdd20aSAndroid Build Coastguard Workerimport {Trace} from '../../public/trace'; 18*6dbdd20aSAndroid Build Coastguard Workerimport {THREAD_STATE_TRACK_KIND} from '../../public/track_kinds'; 19*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin'; 20*6dbdd20aSAndroid Build Coastguard Workerimport {asUtid, Utid} from '../../components/sql_utils/core_types'; 21*6dbdd20aSAndroid Build Coastguard Workerimport {addQueryResultsTab} from '../../components/query_table/query_result_tab'; 22*6dbdd20aSAndroid Build Coastguard Workerimport {showModal} from '../../widgets/modal'; 23*6dbdd20aSAndroid Build Coastguard Workerimport { 24*6dbdd20aSAndroid Build Coastguard Worker CRITICAL_PATH_CMD, 25*6dbdd20aSAndroid Build Coastguard Worker CRITICAL_PATH_LITE_CMD, 26*6dbdd20aSAndroid Build Coastguard Worker} from '../../public/exposed_commands'; 27*6dbdd20aSAndroid Build Coastguard Workerimport {getTimeSpanOfSelectionOrVisibleWindow} from '../../public/utils'; 28*6dbdd20aSAndroid Build Coastguard Worker 29*6dbdd20aSAndroid Build Coastguard Workerconst criticalPathSliceColumns = { 30*6dbdd20aSAndroid Build Coastguard Worker ts: 'ts', 31*6dbdd20aSAndroid Build Coastguard Worker dur: 'dur', 32*6dbdd20aSAndroid Build Coastguard Worker name: 'name', 33*6dbdd20aSAndroid Build Coastguard Worker}; 34*6dbdd20aSAndroid Build Coastguard Worker 35*6dbdd20aSAndroid Build Coastguard Workerconst criticalPathsliceColumnNames = [ 36*6dbdd20aSAndroid Build Coastguard Worker 'id', 37*6dbdd20aSAndroid Build Coastguard Worker 'utid', 38*6dbdd20aSAndroid Build Coastguard Worker 'ts', 39*6dbdd20aSAndroid Build Coastguard Worker 'dur', 40*6dbdd20aSAndroid Build Coastguard Worker 'name', 41*6dbdd20aSAndroid Build Coastguard Worker 'table_name', 42*6dbdd20aSAndroid Build Coastguard Worker]; 43*6dbdd20aSAndroid Build Coastguard Worker 44*6dbdd20aSAndroid Build Coastguard Workerconst criticalPathsliceLiteColumns = { 45*6dbdd20aSAndroid Build Coastguard Worker ts: 'ts', 46*6dbdd20aSAndroid Build Coastguard Worker dur: 'dur', 47*6dbdd20aSAndroid Build Coastguard Worker name: 'thread_name', 48*6dbdd20aSAndroid Build Coastguard Worker}; 49*6dbdd20aSAndroid Build Coastguard Worker 50*6dbdd20aSAndroid Build Coastguard Workerconst criticalPathsliceLiteColumnNames = [ 51*6dbdd20aSAndroid Build Coastguard Worker 'id', 52*6dbdd20aSAndroid Build Coastguard Worker 'utid', 53*6dbdd20aSAndroid Build Coastguard Worker 'ts', 54*6dbdd20aSAndroid Build Coastguard Worker 'dur', 55*6dbdd20aSAndroid Build Coastguard Worker 'thread_name', 56*6dbdd20aSAndroid Build Coastguard Worker 'process_name', 57*6dbdd20aSAndroid Build Coastguard Worker 'table_name', 58*6dbdd20aSAndroid Build Coastguard Worker]; 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Workerconst sliceLiteColumns = {ts: 'ts', dur: 'dur', name: 'thread_name'}; 61*6dbdd20aSAndroid Build Coastguard Worker 62*6dbdd20aSAndroid Build Coastguard Workerconst sliceLiteColumnNames = [ 63*6dbdd20aSAndroid Build Coastguard Worker 'id', 64*6dbdd20aSAndroid Build Coastguard Worker 'utid', 65*6dbdd20aSAndroid Build Coastguard Worker 'ts', 66*6dbdd20aSAndroid Build Coastguard Worker 'dur', 67*6dbdd20aSAndroid Build Coastguard Worker 'thread_name', 68*6dbdd20aSAndroid Build Coastguard Worker 'process_name', 69*6dbdd20aSAndroid Build Coastguard Worker 'table_name', 70*6dbdd20aSAndroid Build Coastguard Worker]; 71*6dbdd20aSAndroid Build Coastguard Worker 72*6dbdd20aSAndroid Build Coastguard Workerconst sliceColumns = {ts: 'ts', dur: 'dur', name: 'name'}; 73*6dbdd20aSAndroid Build Coastguard Worker 74*6dbdd20aSAndroid Build Coastguard Workerconst sliceColumnNames = ['id', 'utid', 'ts', 'dur', 'name', 'table_name']; 75*6dbdd20aSAndroid Build Coastguard Worker 76*6dbdd20aSAndroid Build Coastguard Workerfunction getFirstUtidOfSelectionOrVisibleWindow(trace: Trace): number { 77*6dbdd20aSAndroid Build Coastguard Worker const selection = trace.selection.selection; 78*6dbdd20aSAndroid Build Coastguard Worker if (selection.kind === 'area') { 79*6dbdd20aSAndroid Build Coastguard Worker for (const trackDesc of selection.tracks) { 80*6dbdd20aSAndroid Build Coastguard Worker if ( 81*6dbdd20aSAndroid Build Coastguard Worker trackDesc?.tags?.kind === THREAD_STATE_TRACK_KIND && 82*6dbdd20aSAndroid Build Coastguard Worker trackDesc?.tags?.utid !== undefined 83*6dbdd20aSAndroid Build Coastguard Worker ) { 84*6dbdd20aSAndroid Build Coastguard Worker return trackDesc.tags.utid; 85*6dbdd20aSAndroid Build Coastguard Worker } 86*6dbdd20aSAndroid Build Coastguard Worker } 87*6dbdd20aSAndroid Build Coastguard Worker } 88*6dbdd20aSAndroid Build Coastguard Worker 89*6dbdd20aSAndroid Build Coastguard Worker return 0; 90*6dbdd20aSAndroid Build Coastguard Worker} 91*6dbdd20aSAndroid Build Coastguard Worker 92*6dbdd20aSAndroid Build Coastguard Workerfunction showModalErrorAreaSelectionRequired() { 93*6dbdd20aSAndroid Build Coastguard Worker showModal({ 94*6dbdd20aSAndroid Build Coastguard Worker title: 'Error: range selection required', 95*6dbdd20aSAndroid Build Coastguard Worker content: 96*6dbdd20aSAndroid Build Coastguard Worker 'This command requires an area selection over a thread state track.', 97*6dbdd20aSAndroid Build Coastguard Worker }); 98*6dbdd20aSAndroid Build Coastguard Worker} 99*6dbdd20aSAndroid Build Coastguard Worker 100*6dbdd20aSAndroid Build Coastguard Workerfunction showModalErrorThreadStateRequired() { 101*6dbdd20aSAndroid Build Coastguard Worker showModal({ 102*6dbdd20aSAndroid Build Coastguard Worker title: 'Error: thread state selection required', 103*6dbdd20aSAndroid Build Coastguard Worker content: 'This command requires a thread state slice to be selected.', 104*6dbdd20aSAndroid Build Coastguard Worker }); 105*6dbdd20aSAndroid Build Coastguard Worker} 106*6dbdd20aSAndroid Build Coastguard Worker 107*6dbdd20aSAndroid Build Coastguard Worker// If utid is undefined, returns the utid for the selected thread state track, 108*6dbdd20aSAndroid Build Coastguard Worker// if any. If it's defined, looks up the info about that specific utid. 109*6dbdd20aSAndroid Build Coastguard Workerasync function getThreadInfoForUtidOrSelection( 110*6dbdd20aSAndroid Build Coastguard Worker trace: Trace, 111*6dbdd20aSAndroid Build Coastguard Worker utid?: Utid, 112*6dbdd20aSAndroid Build Coastguard Worker): Promise<ThreadInfo | undefined> { 113*6dbdd20aSAndroid Build Coastguard Worker if (utid === undefined) { 114*6dbdd20aSAndroid Build Coastguard Worker const selection = trace.selection.selection; 115*6dbdd20aSAndroid Build Coastguard Worker if (selection.kind === 'track_event') { 116*6dbdd20aSAndroid Build Coastguard Worker if (selection.utid !== undefined) { 117*6dbdd20aSAndroid Build Coastguard Worker utid = asUtid(selection.utid); 118*6dbdd20aSAndroid Build Coastguard Worker } 119*6dbdd20aSAndroid Build Coastguard Worker } 120*6dbdd20aSAndroid Build Coastguard Worker } 121*6dbdd20aSAndroid Build Coastguard Worker if (utid === undefined) return undefined; 122*6dbdd20aSAndroid Build Coastguard Worker return getThreadInfo(trace.engine, utid); 123*6dbdd20aSAndroid Build Coastguard Worker} 124*6dbdd20aSAndroid Build Coastguard Worker 125*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin { 126*6dbdd20aSAndroid Build Coastguard Worker static readonly id = 'dev.perfetto.CriticalPath'; 127*6dbdd20aSAndroid Build Coastguard Worker async onTraceLoad(ctx: Trace): Promise<void> { 128*6dbdd20aSAndroid Build Coastguard Worker // The 3 commands below are used in two contextes: 129*6dbdd20aSAndroid Build Coastguard Worker // 1. By clicking a slice and using the command palette. In this case the 130*6dbdd20aSAndroid Build Coastguard Worker // utid argument is undefined and we need to look at the selection. 131*6dbdd20aSAndroid Build Coastguard Worker // 2. Invoked via runCommand(...) by thread_state_tab.ts when the user 132*6dbdd20aSAndroid Build Coastguard Worker // clicks on the buttons in the details panel. In this case the details 133*6dbdd20aSAndroid Build Coastguard Worker // panel passes the utid explicitly. 134*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 135*6dbdd20aSAndroid Build Coastguard Worker id: CRITICAL_PATH_LITE_CMD, 136*6dbdd20aSAndroid Build Coastguard Worker name: 'Critical path lite (selected thread state slice)', 137*6dbdd20aSAndroid Build Coastguard Worker callback: async (utid?: Utid) => { 138*6dbdd20aSAndroid Build Coastguard Worker const thdInfo = await getThreadInfoForUtidOrSelection(ctx, utid); 139*6dbdd20aSAndroid Build Coastguard Worker if (thdInfo === undefined) { 140*6dbdd20aSAndroid Build Coastguard Worker return showModalErrorThreadStateRequired(); 141*6dbdd20aSAndroid Build Coastguard Worker } 142*6dbdd20aSAndroid Build Coastguard Worker ctx.engine 143*6dbdd20aSAndroid Build Coastguard Worker .query(`INCLUDE PERFETTO MODULE sched.thread_executing_span;`) 144*6dbdd20aSAndroid Build Coastguard Worker .then(() => 145*6dbdd20aSAndroid Build Coastguard Worker addDebugSliceTrack({ 146*6dbdd20aSAndroid Build Coastguard Worker trace: ctx, 147*6dbdd20aSAndroid Build Coastguard Worker data: { 148*6dbdd20aSAndroid Build Coastguard Worker sqlSource: ` 149*6dbdd20aSAndroid Build Coastguard Worker SELECT 150*6dbdd20aSAndroid Build Coastguard Worker cr.id, 151*6dbdd20aSAndroid Build Coastguard Worker cr.utid, 152*6dbdd20aSAndroid Build Coastguard Worker cr.ts, 153*6dbdd20aSAndroid Build Coastguard Worker cr.dur, 154*6dbdd20aSAndroid Build Coastguard Worker thread.name AS thread_name, 155*6dbdd20aSAndroid Build Coastguard Worker process.name AS process_name, 156*6dbdd20aSAndroid Build Coastguard Worker 'thread_state' AS table_name 157*6dbdd20aSAndroid Build Coastguard Worker FROM 158*6dbdd20aSAndroid Build Coastguard Worker _thread_executing_span_critical_path( 159*6dbdd20aSAndroid Build Coastguard Worker ${thdInfo.utid}, 160*6dbdd20aSAndroid Build Coastguard Worker trace_bounds.start_ts, 161*6dbdd20aSAndroid Build Coastguard Worker trace_bounds.end_ts - trace_bounds.start_ts) cr, 162*6dbdd20aSAndroid Build Coastguard Worker trace_bounds 163*6dbdd20aSAndroid Build Coastguard Worker JOIN thread USING(utid) 164*6dbdd20aSAndroid Build Coastguard Worker JOIN process USING(upid) 165*6dbdd20aSAndroid Build Coastguard Worker `, 166*6dbdd20aSAndroid Build Coastguard Worker columns: sliceLiteColumnNames, 167*6dbdd20aSAndroid Build Coastguard Worker }, 168*6dbdd20aSAndroid Build Coastguard Worker title: `${thdInfo.name}`, 169*6dbdd20aSAndroid Build Coastguard Worker columns: sliceLiteColumns, 170*6dbdd20aSAndroid Build Coastguard Worker argColumns: sliceLiteColumnNames, 171*6dbdd20aSAndroid Build Coastguard Worker }), 172*6dbdd20aSAndroid Build Coastguard Worker ); 173*6dbdd20aSAndroid Build Coastguard Worker }, 174*6dbdd20aSAndroid Build Coastguard Worker }); 175*6dbdd20aSAndroid Build Coastguard Worker 176*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 177*6dbdd20aSAndroid Build Coastguard Worker id: CRITICAL_PATH_CMD, 178*6dbdd20aSAndroid Build Coastguard Worker name: 'Critical path (selected thread state slice)', 179*6dbdd20aSAndroid Build Coastguard Worker callback: async (utid?: Utid) => { 180*6dbdd20aSAndroid Build Coastguard Worker const thdInfo = await getThreadInfoForUtidOrSelection(ctx, utid); 181*6dbdd20aSAndroid Build Coastguard Worker if (thdInfo === undefined) { 182*6dbdd20aSAndroid Build Coastguard Worker return showModalErrorThreadStateRequired(); 183*6dbdd20aSAndroid Build Coastguard Worker } 184*6dbdd20aSAndroid Build Coastguard Worker ctx.engine 185*6dbdd20aSAndroid Build Coastguard Worker .query( 186*6dbdd20aSAndroid Build Coastguard Worker `INCLUDE PERFETTO MODULE sched.thread_executing_span_with_slice;`, 187*6dbdd20aSAndroid Build Coastguard Worker ) 188*6dbdd20aSAndroid Build Coastguard Worker .then(() => 189*6dbdd20aSAndroid Build Coastguard Worker addDebugSliceTrack({ 190*6dbdd20aSAndroid Build Coastguard Worker trace: ctx, 191*6dbdd20aSAndroid Build Coastguard Worker data: { 192*6dbdd20aSAndroid Build Coastguard Worker sqlSource: ` 193*6dbdd20aSAndroid Build Coastguard Worker SELECT cr.id, cr.utid, cr.ts, cr.dur, cr.name, cr.table_name 194*6dbdd20aSAndroid Build Coastguard Worker FROM 195*6dbdd20aSAndroid Build Coastguard Worker _thread_executing_span_critical_path_stack( 196*6dbdd20aSAndroid Build Coastguard Worker ${thdInfo.utid}, 197*6dbdd20aSAndroid Build Coastguard Worker trace_bounds.start_ts, 198*6dbdd20aSAndroid Build Coastguard Worker trace_bounds.end_ts - trace_bounds.start_ts) cr, 199*6dbdd20aSAndroid Build Coastguard Worker trace_bounds WHERE name IS NOT NULL 200*6dbdd20aSAndroid Build Coastguard Worker `, 201*6dbdd20aSAndroid Build Coastguard Worker columns: sliceColumnNames, 202*6dbdd20aSAndroid Build Coastguard Worker }, 203*6dbdd20aSAndroid Build Coastguard Worker title: `${thdInfo.name}`, 204*6dbdd20aSAndroid Build Coastguard Worker columns: sliceColumns, 205*6dbdd20aSAndroid Build Coastguard Worker argColumns: sliceColumnNames, 206*6dbdd20aSAndroid Build Coastguard Worker }), 207*6dbdd20aSAndroid Build Coastguard Worker ); 208*6dbdd20aSAndroid Build Coastguard Worker }, 209*6dbdd20aSAndroid Build Coastguard Worker }); 210*6dbdd20aSAndroid Build Coastguard Worker 211*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 212*6dbdd20aSAndroid Build Coastguard Worker id: 'perfetto.CriticalPathLite_AreaSelection', 213*6dbdd20aSAndroid Build Coastguard Worker name: 'Critical path lite (over area selection)', 214*6dbdd20aSAndroid Build Coastguard Worker callback: async () => { 215*6dbdd20aSAndroid Build Coastguard Worker const trackUtid = getFirstUtidOfSelectionOrVisibleWindow(ctx); 216*6dbdd20aSAndroid Build Coastguard Worker const window = await getTimeSpanOfSelectionOrVisibleWindow(ctx); 217*6dbdd20aSAndroid Build Coastguard Worker if (trackUtid === 0) { 218*6dbdd20aSAndroid Build Coastguard Worker return showModalErrorAreaSelectionRequired(); 219*6dbdd20aSAndroid Build Coastguard Worker } 220*6dbdd20aSAndroid Build Coastguard Worker await ctx.engine.query( 221*6dbdd20aSAndroid Build Coastguard Worker `INCLUDE PERFETTO MODULE sched.thread_executing_span;`, 222*6dbdd20aSAndroid Build Coastguard Worker ); 223*6dbdd20aSAndroid Build Coastguard Worker await addDebugSliceTrack({ 224*6dbdd20aSAndroid Build Coastguard Worker trace: ctx, 225*6dbdd20aSAndroid Build Coastguard Worker data: { 226*6dbdd20aSAndroid Build Coastguard Worker sqlSource: ` 227*6dbdd20aSAndroid Build Coastguard Worker SELECT 228*6dbdd20aSAndroid Build Coastguard Worker cr.id, 229*6dbdd20aSAndroid Build Coastguard Worker cr.utid, 230*6dbdd20aSAndroid Build Coastguard Worker cr.ts, 231*6dbdd20aSAndroid Build Coastguard Worker cr.dur, 232*6dbdd20aSAndroid Build Coastguard Worker thread.name AS thread_name, 233*6dbdd20aSAndroid Build Coastguard Worker process.name AS process_name, 234*6dbdd20aSAndroid Build Coastguard Worker 'thread_state' AS table_name 235*6dbdd20aSAndroid Build Coastguard Worker FROM 236*6dbdd20aSAndroid Build Coastguard Worker _thread_executing_span_critical_path( 237*6dbdd20aSAndroid Build Coastguard Worker ${trackUtid}, 238*6dbdd20aSAndroid Build Coastguard Worker ${window.start}, 239*6dbdd20aSAndroid Build Coastguard Worker ${window.end} - ${window.start}) cr 240*6dbdd20aSAndroid Build Coastguard Worker JOIN thread USING(utid) 241*6dbdd20aSAndroid Build Coastguard Worker JOIN process USING(upid) 242*6dbdd20aSAndroid Build Coastguard Worker `, 243*6dbdd20aSAndroid Build Coastguard Worker columns: criticalPathsliceLiteColumnNames, 244*6dbdd20aSAndroid Build Coastguard Worker }, 245*6dbdd20aSAndroid Build Coastguard Worker title: 246*6dbdd20aSAndroid Build Coastguard Worker (await getThreadInfo(ctx.engine, trackUtid as Utid)).name ?? 247*6dbdd20aSAndroid Build Coastguard Worker '<thread name>', 248*6dbdd20aSAndroid Build Coastguard Worker columns: criticalPathsliceLiteColumns, 249*6dbdd20aSAndroid Build Coastguard Worker argColumns: criticalPathsliceLiteColumnNames, 250*6dbdd20aSAndroid Build Coastguard Worker }); 251*6dbdd20aSAndroid Build Coastguard Worker }, 252*6dbdd20aSAndroid Build Coastguard Worker }); 253*6dbdd20aSAndroid Build Coastguard Worker 254*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 255*6dbdd20aSAndroid Build Coastguard Worker id: 'perfetto.CriticalPath_AreaSelection', 256*6dbdd20aSAndroid Build Coastguard Worker name: 'Critical path (over area selection)', 257*6dbdd20aSAndroid Build Coastguard Worker callback: async () => { 258*6dbdd20aSAndroid Build Coastguard Worker const trackUtid = getFirstUtidOfSelectionOrVisibleWindow(ctx); 259*6dbdd20aSAndroid Build Coastguard Worker const window = await getTimeSpanOfSelectionOrVisibleWindow(ctx); 260*6dbdd20aSAndroid Build Coastguard Worker if (trackUtid === 0) { 261*6dbdd20aSAndroid Build Coastguard Worker return showModalErrorAreaSelectionRequired(); 262*6dbdd20aSAndroid Build Coastguard Worker } 263*6dbdd20aSAndroid Build Coastguard Worker await ctx.engine.query( 264*6dbdd20aSAndroid Build Coastguard Worker `INCLUDE PERFETTO MODULE sched.thread_executing_span_with_slice;`, 265*6dbdd20aSAndroid Build Coastguard Worker ); 266*6dbdd20aSAndroid Build Coastguard Worker await addDebugSliceTrack({ 267*6dbdd20aSAndroid Build Coastguard Worker trace: ctx, 268*6dbdd20aSAndroid Build Coastguard Worker data: { 269*6dbdd20aSAndroid Build Coastguard Worker sqlSource: ` 270*6dbdd20aSAndroid Build Coastguard Worker SELECT cr.id, cr.utid, cr.ts, cr.dur, cr.name, cr.table_name 271*6dbdd20aSAndroid Build Coastguard Worker FROM 272*6dbdd20aSAndroid Build Coastguard Worker _critical_path_stack( 273*6dbdd20aSAndroid Build Coastguard Worker ${trackUtid}, 274*6dbdd20aSAndroid Build Coastguard Worker ${window.start}, 275*6dbdd20aSAndroid Build Coastguard Worker ${window.end} - ${window.start}, 1, 1, 1, 1) cr 276*6dbdd20aSAndroid Build Coastguard Worker WHERE name IS NOT NULL 277*6dbdd20aSAndroid Build Coastguard Worker `, 278*6dbdd20aSAndroid Build Coastguard Worker columns: criticalPathsliceColumnNames, 279*6dbdd20aSAndroid Build Coastguard Worker }, 280*6dbdd20aSAndroid Build Coastguard Worker title: 281*6dbdd20aSAndroid Build Coastguard Worker (await getThreadInfo(ctx.engine, trackUtid as Utid)).name ?? 282*6dbdd20aSAndroid Build Coastguard Worker '<thread name>', 283*6dbdd20aSAndroid Build Coastguard Worker columns: criticalPathSliceColumns, 284*6dbdd20aSAndroid Build Coastguard Worker argColumns: criticalPathsliceColumnNames, 285*6dbdd20aSAndroid Build Coastguard Worker }); 286*6dbdd20aSAndroid Build Coastguard Worker }, 287*6dbdd20aSAndroid Build Coastguard Worker }); 288*6dbdd20aSAndroid Build Coastguard Worker 289*6dbdd20aSAndroid Build Coastguard Worker ctx.commands.registerCommand({ 290*6dbdd20aSAndroid Build Coastguard Worker id: 'perfetto.CriticalPathPprof_AreaSelection', 291*6dbdd20aSAndroid Build Coastguard Worker name: 'Critical path pprof (over area selection)', 292*6dbdd20aSAndroid Build Coastguard Worker callback: async () => { 293*6dbdd20aSAndroid Build Coastguard Worker const trackUtid = getFirstUtidOfSelectionOrVisibleWindow(ctx); 294*6dbdd20aSAndroid Build Coastguard Worker const window = await getTimeSpanOfSelectionOrVisibleWindow(ctx); 295*6dbdd20aSAndroid Build Coastguard Worker if (trackUtid === 0) { 296*6dbdd20aSAndroid Build Coastguard Worker return showModalErrorAreaSelectionRequired(); 297*6dbdd20aSAndroid Build Coastguard Worker } 298*6dbdd20aSAndroid Build Coastguard Worker addQueryResultsTab(ctx, { 299*6dbdd20aSAndroid Build Coastguard Worker query: ` 300*6dbdd20aSAndroid Build Coastguard Worker INCLUDE PERFETTO MODULE sched.thread_executing_span_with_slice; 301*6dbdd20aSAndroid Build Coastguard Worker SELECT * 302*6dbdd20aSAndroid Build Coastguard Worker FROM 303*6dbdd20aSAndroid Build Coastguard Worker _thread_executing_span_critical_path_graph( 304*6dbdd20aSAndroid Build Coastguard Worker "criical_path", 305*6dbdd20aSAndroid Build Coastguard Worker ${trackUtid}, 306*6dbdd20aSAndroid Build Coastguard Worker ${window.start}, 307*6dbdd20aSAndroid Build Coastguard Worker ${window.end} - ${window.start}) cr`, 308*6dbdd20aSAndroid Build Coastguard Worker title: 'Critical path', 309*6dbdd20aSAndroid Build Coastguard Worker }); 310*6dbdd20aSAndroid Build Coastguard Worker }, 311*6dbdd20aSAndroid Build Coastguard Worker }); 312*6dbdd20aSAndroid Build Coastguard Worker } 313*6dbdd20aSAndroid Build Coastguard Worker} 314