1// Copyright (C) 2024 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 {asUtid} from '../../components/sql_utils/core_types'; 16import {NUM, NUM_NULL, STR_NULL} from '../../trace_processor/query_result'; 17import {Trace} from '../../public/trace'; 18import {PerfettoPlugin} from '../../public/plugin'; 19import {ChromeTasksThreadTrack} from './track'; 20import {TrackNode} from '../../public/workspace'; 21 22export default class implements PerfettoPlugin { 23 static readonly id = 'org.chromium.ChromeTasks'; 24 25 async onTraceLoad(ctx: Trace) { 26 await this.createTracks(ctx); 27 } 28 29 async createTracks(ctx: Trace) { 30 const it = ( 31 await ctx.engine.query(` 32 INCLUDE PERFETTO MODULE chrome.tasks; 33 34 with relevant_threads as ( 35 select distinct utid from chrome_tasks 36 ) 37 select 38 (CASE process.name 39 WHEN 'Browser' THEN 1 40 WHEN 'Gpu' THEN 2 41 WHEN 'Renderer' THEN 4 42 ELSE 3 43 END) as processRank, 44 process.name as processName, 45 process.pid, 46 process.upid, 47 (CASE thread.name 48 WHEN 'CrBrowserMain' THEN 1 49 WHEN 'CrRendererMain' THEN 1 50 WHEN 'CrGpuMain' THEN 1 51 WHEN 'Chrome_IOThread' THEN 2 52 WHEN 'Chrome_ChildIOThread' THEN 2 53 WHEN 'VizCompositorThread' THEN 3 54 WHEN 'NetworkService' THEN 3 55 WHEN 'Compositor' THEN 3 56 WHEN 'CompositorGpuThread' THEN 4 57 WHEN 'CompositorTileWorker&' THEN 5 58 WHEN 'ThreadPoolService' THEN 6 59 WHEN 'ThreadPoolSingleThreadForegroundBlocking&' THEN 6 60 WHEN 'ThreadPoolForegroundWorker' THEN 6 61 ELSE 7 62 END) as threadRank, 63 thread.name as threadName, 64 thread.tid, 65 thread.utid 66 from relevant_threads 67 join thread using (utid) 68 join process using (upid) 69 order by processRank, upid, threadRank, utid 70 `) 71 ).iter({ 72 processRank: NUM, 73 processName: STR_NULL, 74 pid: NUM_NULL, 75 upid: NUM, 76 threadRank: NUM, 77 threadName: STR_NULL, 78 tid: NUM_NULL, 79 utid: NUM, 80 }); 81 82 const group = new TrackNode({title: 'Chrome Tasks', isSummary: true}); 83 for (; it.valid(); it.next()) { 84 const utid = it.utid; 85 const uri = `org.chromium.ChromeTasks#thread.${utid}`; 86 const title = `${it.threadName} ${it.tid}`; 87 ctx.tracks.registerTrack({ 88 uri, 89 track: new ChromeTasksThreadTrack(ctx, uri, asUtid(utid)), 90 title, 91 }); 92 const track = new TrackNode({uri, title}); 93 group.addChildInOrder(track); 94 ctx.workspace.addChildInOrder(group); 95 } 96 } 97} 98