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