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 {Trace} from '../../public/trace'; 16*6dbdd20aSAndroid Build Coastguard Workerimport {PerfettoPlugin} from '../../public/plugin'; 17*6dbdd20aSAndroid Build Coastguard Workerimport {ThreadDesc, ThreadMap} from '../dev.perfetto.Thread/threads'; 18*6dbdd20aSAndroid Build Coastguard Workerimport {NUM, NUM_NULL, STR, STR_NULL} from '../../trace_processor/query_result'; 19*6dbdd20aSAndroid Build Coastguard Workerimport {assertExists} from '../../base/logging'; 20*6dbdd20aSAndroid Build Coastguard Worker 21*6dbdd20aSAndroid Build Coastguard Workerasync function listThreads(trace: Trace) { 22*6dbdd20aSAndroid Build Coastguard Worker const query = `select 23*6dbdd20aSAndroid Build Coastguard Worker utid, 24*6dbdd20aSAndroid Build Coastguard Worker tid, 25*6dbdd20aSAndroid Build Coastguard Worker pid, 26*6dbdd20aSAndroid Build Coastguard Worker ifnull(thread.name, '') as threadName, 27*6dbdd20aSAndroid Build Coastguard Worker ifnull( 28*6dbdd20aSAndroid Build Coastguard Worker case when length(process.name) > 0 then process.name else null end, 29*6dbdd20aSAndroid Build Coastguard Worker thread.name) as procName, 30*6dbdd20aSAndroid Build Coastguard Worker process.cmdline as cmdline 31*6dbdd20aSAndroid Build Coastguard Worker from (select * from thread order by upid) as thread 32*6dbdd20aSAndroid Build Coastguard Worker left join (select * from process order by upid) as process 33*6dbdd20aSAndroid Build Coastguard Worker using(upid)`; 34*6dbdd20aSAndroid Build Coastguard Worker const result = await trace.engine.query(query); 35*6dbdd20aSAndroid Build Coastguard Worker const threads = new Map<number, ThreadDesc>(); 36*6dbdd20aSAndroid Build Coastguard Worker const it = result.iter({ 37*6dbdd20aSAndroid Build Coastguard Worker utid: NUM, 38*6dbdd20aSAndroid Build Coastguard Worker tid: NUM, 39*6dbdd20aSAndroid Build Coastguard Worker pid: NUM_NULL, 40*6dbdd20aSAndroid Build Coastguard Worker threadName: STR, 41*6dbdd20aSAndroid Build Coastguard Worker procName: STR_NULL, 42*6dbdd20aSAndroid Build Coastguard Worker cmdline: STR_NULL, 43*6dbdd20aSAndroid Build Coastguard Worker }); 44*6dbdd20aSAndroid Build Coastguard Worker for (; it.valid(); it.next()) { 45*6dbdd20aSAndroid Build Coastguard Worker const utid = it.utid; 46*6dbdd20aSAndroid Build Coastguard Worker const tid = it.tid; 47*6dbdd20aSAndroid Build Coastguard Worker const pid = it.pid === null ? undefined : it.pid; 48*6dbdd20aSAndroid Build Coastguard Worker const threadName = it.threadName; 49*6dbdd20aSAndroid Build Coastguard Worker const procName = it.procName === null ? undefined : it.procName; 50*6dbdd20aSAndroid Build Coastguard Worker const cmdline = it.cmdline === null ? undefined : it.cmdline; 51*6dbdd20aSAndroid Build Coastguard Worker threads.set(utid, {utid, tid, threadName, pid, procName, cmdline}); 52*6dbdd20aSAndroid Build Coastguard Worker } 53*6dbdd20aSAndroid Build Coastguard Worker return threads; 54*6dbdd20aSAndroid Build Coastguard Worker} 55*6dbdd20aSAndroid Build Coastguard Worker 56*6dbdd20aSAndroid Build Coastguard Workerexport default class implements PerfettoPlugin { 57*6dbdd20aSAndroid Build Coastguard Worker static readonly id = 'dev.perfetto.Thread'; 58*6dbdd20aSAndroid Build Coastguard Worker private threads?: ThreadMap; 59*6dbdd20aSAndroid Build Coastguard Worker 60*6dbdd20aSAndroid Build Coastguard Worker async onTraceLoad(ctx: Trace) { 61*6dbdd20aSAndroid Build Coastguard Worker this.threads = await listThreads(ctx); 62*6dbdd20aSAndroid Build Coastguard Worker } 63*6dbdd20aSAndroid Build Coastguard Worker 64*6dbdd20aSAndroid Build Coastguard Worker getThreadMap() { 65*6dbdd20aSAndroid Build Coastguard Worker return assertExists(this.threads); 66*6dbdd20aSAndroid Build Coastguard Worker } 67*6dbdd20aSAndroid Build Coastguard Worker} 68