1fb726d48Sopenharmony_ci/* 2fb726d48Sopenharmony_ci * Copyright (C) 2022 Huawei Device Co., Ltd. 3fb726d48Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb726d48Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb726d48Sopenharmony_ci * You may obtain a copy of the License at 6fb726d48Sopenharmony_ci * 7fb726d48Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb726d48Sopenharmony_ci * 9fb726d48Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb726d48Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb726d48Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb726d48Sopenharmony_ci * See the License for the specific language governing permissions and 13fb726d48Sopenharmony_ci * limitations under the License. 14fb726d48Sopenharmony_ci */ 15fb726d48Sopenharmony_ci 16fb726d48Sopenharmony_ciimport { SpSystemTrace } from '../SpSystemTrace'; 17fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow'; 18fb726d48Sopenharmony_ciimport { Utils } from '../trace/base/Utils'; 19fb726d48Sopenharmony_ciimport { PerfThread } from '../../bean/PerfProfile'; 20fb726d48Sopenharmony_ciimport { HiPerfCpuStruct } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfCPU2'; 21fb726d48Sopenharmony_ciimport { 22fb726d48Sopenharmony_ci HiPerfCallChartRender, 23fb726d48Sopenharmony_ci HiPerfCallChartStruct, 24fb726d48Sopenharmony_ci} from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfCallChart'; 25fb726d48Sopenharmony_ciimport { HiPerfThreadStruct } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfThread2'; 26fb726d48Sopenharmony_ciimport { HiPerfProcessStruct } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfProcess2'; 27fb726d48Sopenharmony_ciimport { info } from '../../../log/Log'; 28fb726d48Sopenharmony_ciimport { HiPerfEventStruct } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfEvent'; 29fb726d48Sopenharmony_ciimport { perfDataQuery } from './PerfDataQuery'; 30fb726d48Sopenharmony_ciimport { type HiPerfReportStruct } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfReport'; 31fb726d48Sopenharmony_ciimport { folderThreadHandler, getRowContext, rowThreadHandler, SpChartManager } from './SpChartManager'; 32fb726d48Sopenharmony_ciimport { HiperfCpuRender2 } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfCPU2'; 33fb726d48Sopenharmony_ciimport { hiperfCpuDataSender } from '../../database/data-trafic/hiperf/HiperfCpuDataSender'; 34fb726d48Sopenharmony_ciimport { hiperfProcessDataSender } from '../../database/data-trafic/hiperf/HiperfProcessDataSender'; 35fb726d48Sopenharmony_ciimport { HiperfProcessRender2 } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfProcess2'; 36fb726d48Sopenharmony_ciimport { hiperfThreadDataSender } from '../../database/data-trafic/hiperf/HiperfThreadDataSender'; 37fb726d48Sopenharmony_ciimport { HiperfThreadRender2 } from '../../database/ui-worker/hiperf/ProcedureWorkerHiPerfThread2'; 38fb726d48Sopenharmony_ciimport { 39fb726d48Sopenharmony_ci hiperfCallChartDataCacheSender, 40fb726d48Sopenharmony_ci hiperfCallChartDataSender, 41fb726d48Sopenharmony_ci hiperfCallStackCacheSender, 42fb726d48Sopenharmony_ci} from '../../database/data-trafic/hiperf/HiperfCallChartSender'; 43fb726d48Sopenharmony_ciimport { 44fb726d48Sopenharmony_ci queryHiPerfCpuMergeData2, 45fb726d48Sopenharmony_ci queryPerfCmdline, 46fb726d48Sopenharmony_ci queryPerfEventType, 47fb726d48Sopenharmony_ci queryPerfThread, 48fb726d48Sopenharmony_ci} from '../../database/sql/Perf.sql'; 49fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker'; 50fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; 51fb726d48Sopenharmony_ci 52fb726d48Sopenharmony_ciexport interface ResultData { 53fb726d48Sopenharmony_ci existA: boolean | null | undefined; 54fb726d48Sopenharmony_ci existF: boolean | null | undefined; 55fb726d48Sopenharmony_ci fValue: number; 56fb726d48Sopenharmony_ci} 57fb726d48Sopenharmony_ciconst FOLD_HEIGHT = 20; 58fb726d48Sopenharmony_ciexport class SpHiPerf { 59fb726d48Sopenharmony_ci static selectCpuStruct: HiPerfCpuStruct | undefined; 60fb726d48Sopenharmony_ci static stringResult: ResultData | undefined; 61fb726d48Sopenharmony_ci 62fb726d48Sopenharmony_ci private cpuData: Array<unknown> | undefined; 63fb726d48Sopenharmony_ci public maxCpuId: number = 0; //@ts-ignore 64fb726d48Sopenharmony_ci private rowFolder!: TraceRow<unknown>; 65fb726d48Sopenharmony_ci private perfThreads: Array<PerfThread> | undefined; 66fb726d48Sopenharmony_ci private trace: SpSystemTrace; 67fb726d48Sopenharmony_ci private group: unknown; //@ts-ignore 68fb726d48Sopenharmony_ci private rowList: TraceRow<unknown>[] | undefined; 69fb726d48Sopenharmony_ci private eventTypeList: Array<{ id: number; report: string }> = []; 70fb726d48Sopenharmony_ci private callChartType: number = 0; 71fb726d48Sopenharmony_ci private callChartId: number = 0; 72fb726d48Sopenharmony_ci private eventTypeId: number = -2; 73fb726d48Sopenharmony_ci 74fb726d48Sopenharmony_ci constructor(trace: SpSystemTrace) { 75fb726d48Sopenharmony_ci this.trace = trace; 76fb726d48Sopenharmony_ci } 77fb726d48Sopenharmony_ci 78fb726d48Sopenharmony_ci async init(): Promise<void> { 79fb726d48Sopenharmony_ci await this.initCmdLine(); 80fb726d48Sopenharmony_ci this.eventTypeList = await queryPerfEventType(); 81fb726d48Sopenharmony_ci this.rowList = []; 82fb726d48Sopenharmony_ci this.perfThreads = await queryPerfThread(); 83fb726d48Sopenharmony_ci info('PerfThread Data size is: ', this.perfThreads!.length); 84fb726d48Sopenharmony_ci this.group = Utils.groupBy(this.perfThreads || [], 'pid'); 85fb726d48Sopenharmony_ci this.cpuData = await queryHiPerfCpuMergeData2(); 86fb726d48Sopenharmony_ci this.callChartType = 0; 87fb726d48Sopenharmony_ci this.callChartId = 0; 88fb726d48Sopenharmony_ci this.eventTypeId = -2; //@ts-ignore 89fb726d48Sopenharmony_ci this.maxCpuId = this.cpuData.length > 0 ? this.cpuData[0].cpu_id : -Infinity; 90fb726d48Sopenharmony_ci if (this.cpuData.length > 0) { 91fb726d48Sopenharmony_ci // 统计hiperf插件 92fb726d48Sopenharmony_ci let requestBody = { 93fb726d48Sopenharmony_ci eventData: { 94fb726d48Sopenharmony_ci plugin: ['hiperf-plugin'] 95fb726d48Sopenharmony_ci } 96fb726d48Sopenharmony_ci }; 97fb726d48Sopenharmony_ci SpStatisticsHttpUtil.recordPluginUsage(requestBody); 98fb726d48Sopenharmony_ci await this.initFolder(); 99fb726d48Sopenharmony_ci await this.initCallChart(); 100fb726d48Sopenharmony_ci await this.initCpuMerge(); 101fb726d48Sopenharmony_ci await this.initCpu(); 102fb726d48Sopenharmony_ci await this.initProcess(); 103fb726d48Sopenharmony_ci } 104fb726d48Sopenharmony_ci info('HiPerf Data initialized'); 105fb726d48Sopenharmony_ci } 106fb726d48Sopenharmony_ci 107fb726d48Sopenharmony_ci getStringResult(s: string = ''): void { 108fb726d48Sopenharmony_ci let list = s.split(' '); 109fb726d48Sopenharmony_ci let sA = list.findIndex((item) => item === '-a'); 110fb726d48Sopenharmony_ci let sF = list.findIndex((item) => item === '-f'); 111fb726d48Sopenharmony_ci SpHiPerf.stringResult = { 112fb726d48Sopenharmony_ci existA: sA !== -1, 113fb726d48Sopenharmony_ci existF: sF !== -1, 114fb726d48Sopenharmony_ci fValue: Number((1000 / (sF !== -1 ? parseInt(list[sF + 1]) : 1000)).toFixed(2)), 115fb726d48Sopenharmony_ci }; 116fb726d48Sopenharmony_ci } 117fb726d48Sopenharmony_ci 118fb726d48Sopenharmony_ci async initCmdLine(): Promise<void> { 119fb726d48Sopenharmony_ci let perfCmdLines = await queryPerfCmdline(); 120fb726d48Sopenharmony_ci if (perfCmdLines.length > 0) { 121fb726d48Sopenharmony_ci this.getStringResult(perfCmdLines[0].report_value); 122fb726d48Sopenharmony_ci } else { 123fb726d48Sopenharmony_ci SpHiPerf.stringResult = { 124fb726d48Sopenharmony_ci existA: true, 125fb726d48Sopenharmony_ci existF: false, 126fb726d48Sopenharmony_ci fValue: 1, 127fb726d48Sopenharmony_ci }; 128fb726d48Sopenharmony_ci } 129fb726d48Sopenharmony_ci } 130fb726d48Sopenharmony_ci 131fb726d48Sopenharmony_ci async initFolder(): Promise<void> { 132fb726d48Sopenharmony_ci let row = TraceRow.skeleton(); 133fb726d48Sopenharmony_ci row.rowId = 'HiPerf'; 134fb726d48Sopenharmony_ci row.index = 0; 135fb726d48Sopenharmony_ci row.rowType = TraceRow.ROW_TYPE_HIPERF; 136fb726d48Sopenharmony_ci row.rowParentId = ''; 137fb726d48Sopenharmony_ci row.folder = true; 138fb726d48Sopenharmony_ci row.drawType = -2; 139fb726d48Sopenharmony_ci row.addRowSettingPop(); 140fb726d48Sopenharmony_ci row.rowSetting = 'enable'; 141fb726d48Sopenharmony_ci row.rowSettingPopoverDirection = 'bottomLeft'; 142fb726d48Sopenharmony_ci row.style.height = '40px'; 143fb726d48Sopenharmony_ci this.folderRowSettingConfig(row); 144fb726d48Sopenharmony_ci if (SpHiPerf.stringResult?.existA === true) { 145fb726d48Sopenharmony_ci row.name = 'HiPerf (All)'; 146fb726d48Sopenharmony_ci } else { 147fb726d48Sopenharmony_ci //@ts-ignore 148fb726d48Sopenharmony_ci let names = Reflect.ownKeys(this.group) 149fb726d48Sopenharmony_ci .map((pid: unknown) => { 150fb726d48Sopenharmony_ci //@ts-ignore 151fb726d48Sopenharmony_ci let array = this.group[pid] as Array<PerfThread>; 152fb726d48Sopenharmony_ci let process = array.filter((th) => th.pid === th.tid)[0]; 153fb726d48Sopenharmony_ci return process.processName; 154fb726d48Sopenharmony_ci }) 155fb726d48Sopenharmony_ci .join(','); 156fb726d48Sopenharmony_ci row.name = `HiPerf (${names})`; 157fb726d48Sopenharmony_ci } //@ts-ignore 158fb726d48Sopenharmony_ci row.supplier = (): Promise<Array<unknown>> => new Promise<Array<unknown>>((resolve) => resolve([])); 159fb726d48Sopenharmony_ci row.onThreadHandler = folderThreadHandler(row, this.trace); 160fb726d48Sopenharmony_ci this.rowFolder = row; 161fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(row); 162fb726d48Sopenharmony_ci } 163fb726d48Sopenharmony_ci 164fb726d48Sopenharmony_ci //@ts-ignore 165fb726d48Sopenharmony_ci folderRowSettingConfig(row: TraceRow<unknown>): void { 166fb726d48Sopenharmony_ci row.rowSettingList = [ 167fb726d48Sopenharmony_ci { 168fb726d48Sopenharmony_ci key: '-2', 169fb726d48Sopenharmony_ci title: 'Cpu Usage', 170fb726d48Sopenharmony_ci checked: true, 171fb726d48Sopenharmony_ci }, 172fb726d48Sopenharmony_ci ...this.eventTypeList.map((et) => { 173fb726d48Sopenharmony_ci return { 174fb726d48Sopenharmony_ci key: `${et.id}`, 175fb726d48Sopenharmony_ci title: et.report, 176fb726d48Sopenharmony_ci }; 177fb726d48Sopenharmony_ci }), 178fb726d48Sopenharmony_ci ]; 179fb726d48Sopenharmony_ci row.onRowSettingChangeHandler = (value): void => { 180fb726d48Sopenharmony_ci let drawType = parseInt(value[0]); 181fb726d48Sopenharmony_ci if (this.eventTypeId !== drawType) { 182fb726d48Sopenharmony_ci this.eventTypeId = drawType; 183fb726d48Sopenharmony_ci row.drawType = drawType; 184fb726d48Sopenharmony_ci row.childrenList.forEach((child): void => { 185fb726d48Sopenharmony_ci if (child.drawType !== drawType) { 186fb726d48Sopenharmony_ci child.drawType = drawType; 187fb726d48Sopenharmony_ci child.needRefresh = true; 188fb726d48Sopenharmony_ci child.isComplete = false; 189fb726d48Sopenharmony_ci child.childrenList.forEach((sz) => { 190fb726d48Sopenharmony_ci sz.drawType = drawType; 191fb726d48Sopenharmony_ci sz.isComplete = false; 192fb726d48Sopenharmony_ci sz.needRefresh = true; 193fb726d48Sopenharmony_ci }); 194fb726d48Sopenharmony_ci } 195fb726d48Sopenharmony_ci }); 196fb726d48Sopenharmony_ci TraceRow.range!.refresh = true; 197fb726d48Sopenharmony_ci this.trace.refreshCanvas(false); 198fb726d48Sopenharmony_ci } 199fb726d48Sopenharmony_ci }; 200fb726d48Sopenharmony_ci } 201fb726d48Sopenharmony_ci 202fb726d48Sopenharmony_ci async initCallChart(): Promise<void> { 203fb726d48Sopenharmony_ci await hiperfCallStackCacheSender(); 204fb726d48Sopenharmony_ci await hiperfCallChartDataCacheSender(); 205fb726d48Sopenharmony_ci let perfCallCutRow = TraceRow.skeleton<HiPerfCallChartStruct>(); 206fb726d48Sopenharmony_ci perfCallCutRow.rowId = 'HiPerf-callchart'; 207fb726d48Sopenharmony_ci perfCallCutRow.index = 0; 208fb726d48Sopenharmony_ci perfCallCutRow.rowType = TraceRow.ROW_TYPE_PERF_CALLCHART; 209fb726d48Sopenharmony_ci perfCallCutRow.enableCollapseChart(FOLD_HEIGHT, this.trace); 210fb726d48Sopenharmony_ci perfCallCutRow.rowParentId = 'HiPerf'; 211fb726d48Sopenharmony_ci perfCallCutRow.rowHidden = !this.rowFolder.expansion; 212fb726d48Sopenharmony_ci perfCallCutRow.folder = false; 213fb726d48Sopenharmony_ci perfCallCutRow.drawType = -2; 214fb726d48Sopenharmony_ci perfCallCutRow.name = 'CallChart [cpu0]'; 215fb726d48Sopenharmony_ci perfCallCutRow.funcExpand = false; 216fb726d48Sopenharmony_ci perfCallCutRow.setAttribute('children', ''); 217fb726d48Sopenharmony_ci perfCallCutRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 218fb726d48Sopenharmony_ci perfCallCutRow.selectChangeHandler = this.trace.selectChangeHandler; 219fb726d48Sopenharmony_ci this.rowFolder.addChildTraceRow(perfCallCutRow); 220fb726d48Sopenharmony_ci perfCallCutRow.focusHandler = (): void => { 221fb726d48Sopenharmony_ci this.callChartRowFocusHandler(perfCallCutRow); 222fb726d48Sopenharmony_ci }; 223fb726d48Sopenharmony_ci // @ts-ignore 224fb726d48Sopenharmony_ci perfCallCutRow.supplierFrame = async (): Promise<unknown> => { 225fb726d48Sopenharmony_ci const res = await hiperfCallChartDataSender(perfCallCutRow, { 226fb726d48Sopenharmony_ci startTime: window.recordStartNS, 227fb726d48Sopenharmony_ci eventTypeId: this.eventTypeId, 228fb726d48Sopenharmony_ci type: this.callChartType, 229fb726d48Sopenharmony_ci id: this.callChartId, 230fb726d48Sopenharmony_ci }); 231fb726d48Sopenharmony_ci // @ts-ignore 232fb726d48Sopenharmony_ci let maxHeight = res.maxDepth * FOLD_HEIGHT; 233fb726d48Sopenharmony_ci perfCallCutRow.funcMaxHeight = maxHeight; 234fb726d48Sopenharmony_ci if (perfCallCutRow.funcExpand) { 235fb726d48Sopenharmony_ci perfCallCutRow!.style.height = `${maxHeight}px`; 236fb726d48Sopenharmony_ci if (perfCallCutRow.collect) { 237fb726d48Sopenharmony_ci window.publish(window.SmartEvent.UI.RowHeightChange, { 238fb726d48Sopenharmony_ci expand: true, 239fb726d48Sopenharmony_ci value: perfCallCutRow.funcMaxHeight - FOLD_HEIGHT, 240fb726d48Sopenharmony_ci }); 241fb726d48Sopenharmony_ci } 242fb726d48Sopenharmony_ci } 243fb726d48Sopenharmony_ci // @ts-ignore 244fb726d48Sopenharmony_ci return res.dataList; 245fb726d48Sopenharmony_ci }; 246fb726d48Sopenharmony_ci perfCallCutRow.findHoverStruct = (): void => { 247fb726d48Sopenharmony_ci HiPerfCallChartStruct.hoverPerfCallCutStruct = perfCallCutRow.getHoverStruct(); 248fb726d48Sopenharmony_ci }; 249fb726d48Sopenharmony_ci await this.setCallTotalRow(perfCallCutRow, this.cpuData, this.perfThreads); 250fb726d48Sopenharmony_ci } 251fb726d48Sopenharmony_ci 252fb726d48Sopenharmony_ci callChartRowFocusHandler(perfCallCutRow: TraceRow<HiPerfCallChartStruct>): void { 253fb726d48Sopenharmony_ci let hoverStruct = HiPerfCallChartStruct.hoverPerfCallCutStruct; 254fb726d48Sopenharmony_ci if (hoverStruct) { 255fb726d48Sopenharmony_ci let callName = hoverStruct.name; 256fb726d48Sopenharmony_ci callName = callName.replace(/</g, '<').replace(/>/g, '>'); 257fb726d48Sopenharmony_ci this.trace?.displayTip( 258fb726d48Sopenharmony_ci perfCallCutRow!, 259fb726d48Sopenharmony_ci hoverStruct, 260fb726d48Sopenharmony_ci `<span style="font-weight: bold;color:'#000'">Name: </span> 261fb726d48Sopenharmony_ci <span>${callName}</span><br> 262fb726d48Sopenharmony_ci <span style='font-weight: bold;'>Lib: </span> 263fb726d48Sopenharmony_ci <span>${perfDataQuery.getLibName(hoverStruct!.fileId, hoverStruct!.symbolId)}</span><br> 264fb726d48Sopenharmony_ci <span style='font-weight: bold;'>Self Time: </span> 265fb726d48Sopenharmony_ci <span>${Utils.getProbablyTime(hoverStruct.selfDur || 0)}</span><br> 266fb726d48Sopenharmony_ci <span style='font-weight: bold;'>Duration: </span> 267fb726d48Sopenharmony_ci <span>${Utils.getProbablyTime(hoverStruct.totalTime)}</span><br> 268fb726d48Sopenharmony_ci <span style='font-weight: bold;'>Event Count: </span> 269fb726d48Sopenharmony_ci <span>${hoverStruct.eventCount || ''}</span><br>` 270fb726d48Sopenharmony_ci ); 271fb726d48Sopenharmony_ci } 272fb726d48Sopenharmony_ci } 273fb726d48Sopenharmony_ci 274fb726d48Sopenharmony_ci //@ts-ignore 275fb726d48Sopenharmony_ci async setCallTotalRow(row: TraceRow<unknown>, cpuData: unknown = Array, threadData: unknown = Array): Promise<void> { 276fb726d48Sopenharmony_ci //@ts-ignore 277fb726d48Sopenharmony_ci let pt: Map<string, unknown> = threadData.reduce((map: Map<string, unknown>, current: unknown) => { 278fb726d48Sopenharmony_ci //@ts-ignore 279fb726d48Sopenharmony_ci const key = `${current.processName || 'Process'}(${current.pid})`; 280fb726d48Sopenharmony_ci const thread = { 281fb726d48Sopenharmony_ci //@ts-ignore 282fb726d48Sopenharmony_ci key: `${current.tid}-t`, //@ts-ignore 283fb726d48Sopenharmony_ci title: `${current.threadName || 'Thread'}(${current.tid})`, 284fb726d48Sopenharmony_ci }; 285fb726d48Sopenharmony_ci if (map.has(key)) { 286fb726d48Sopenharmony_ci //@ts-ignore 287fb726d48Sopenharmony_ci if (map.get(key).children) { 288fb726d48Sopenharmony_ci //@ts-ignore 289fb726d48Sopenharmony_ci map.get(key).children.push(thread); 290fb726d48Sopenharmony_ci } else { 291fb726d48Sopenharmony_ci //@ts-ignore 292fb726d48Sopenharmony_ci map.get(key).children = [thread]; 293fb726d48Sopenharmony_ci } 294fb726d48Sopenharmony_ci } else { 295fb726d48Sopenharmony_ci map.set(key, { 296fb726d48Sopenharmony_ci //@ts-ignore 297fb726d48Sopenharmony_ci key: `${current.pid}-p`, 298fb726d48Sopenharmony_ci title: key, 299fb726d48Sopenharmony_ci children: [thread], 300fb726d48Sopenharmony_ci disable: true, 301fb726d48Sopenharmony_ci }); 302fb726d48Sopenharmony_ci } 303fb726d48Sopenharmony_ci return map; 304fb726d48Sopenharmony_ci }, new Map<string, unknown>()); 305fb726d48Sopenharmony_ci row.addTemplateTypes('hiperf-callchart'); 306fb726d48Sopenharmony_ci row.addRowSettingPop(); 307fb726d48Sopenharmony_ci row.rowSetting = 'enable'; //@ts-ignore 308fb726d48Sopenharmony_ci this.setCallChartRowSetting(row, cpuData, pt); 309fb726d48Sopenharmony_ci row.onThreadHandler = rowThreadHandler<HiPerfCallChartRender>( 310fb726d48Sopenharmony_ci 'HiPerf-callchart', 311fb726d48Sopenharmony_ci 'context', 312fb726d48Sopenharmony_ci { 313fb726d48Sopenharmony_ci type: 'HiPerf-callchart', 314fb726d48Sopenharmony_ci }, 315fb726d48Sopenharmony_ci row, 316fb726d48Sopenharmony_ci this.trace 317fb726d48Sopenharmony_ci ); 318fb726d48Sopenharmony_ci } 319fb726d48Sopenharmony_ci 320fb726d48Sopenharmony_ci setCallChartRowSetting( 321fb726d48Sopenharmony_ci row: TraceRow<HiPerfCallChartStruct>, 322fb726d48Sopenharmony_ci cpuData: Array<unknown>, 323fb726d48Sopenharmony_ci pt: Map<string, unknown> 324fb726d48Sopenharmony_ci ): void { 325fb726d48Sopenharmony_ci //@ts-ignore 326fb726d48Sopenharmony_ci row.rowSettingList = [ 327fb726d48Sopenharmony_ci ...cpuData.reverse().map( 328fb726d48Sopenharmony_ci ( 329fb726d48Sopenharmony_ci it: unknown 330fb726d48Sopenharmony_ci ): { 331fb726d48Sopenharmony_ci key: string; 332fb726d48Sopenharmony_ci title: string; 333fb726d48Sopenharmony_ci checked?: boolean; 334fb726d48Sopenharmony_ci } => { 335fb726d48Sopenharmony_ci return { 336fb726d48Sopenharmony_ci //@ts-ignore 337fb726d48Sopenharmony_ci key: `${it.cpu_id}-c`, 338fb726d48Sopenharmony_ci //@ts-ignore 339fb726d48Sopenharmony_ci checked: it.cpu_id === 0, 340fb726d48Sopenharmony_ci //@ts-ignore 341fb726d48Sopenharmony_ci title: `cpu${it.cpu_id}`, 342fb726d48Sopenharmony_ci }; 343fb726d48Sopenharmony_ci } 344fb726d48Sopenharmony_ci ), 345fb726d48Sopenharmony_ci ...Array.from(pt.values()), 346fb726d48Sopenharmony_ci ]; 347fb726d48Sopenharmony_ci row.onRowSettingChangeHandler = (setting: unknown, nodes): void => { 348fb726d48Sopenharmony_ci //@ts-ignore 349fb726d48Sopenharmony_ci if (setting && setting.length > 0) { 350fb726d48Sopenharmony_ci //type 0:cpu,1:process,2:thread 351fb726d48Sopenharmony_ci //@ts-ignore 352fb726d48Sopenharmony_ci let key: string = setting[0]; 353fb726d48Sopenharmony_ci let type = this.callChartType; 354fb726d48Sopenharmony_ci if (key.includes('p')) { 355fb726d48Sopenharmony_ci type = 1; 356fb726d48Sopenharmony_ci } else if (key.includes('t')) { 357fb726d48Sopenharmony_ci type = 2; 358fb726d48Sopenharmony_ci } else { 359fb726d48Sopenharmony_ci type = 0; 360fb726d48Sopenharmony_ci } 361fb726d48Sopenharmony_ci let id = Number(key.split('-')[0]); 362fb726d48Sopenharmony_ci if (this.callChartType === type && this.callChartId === id) { 363fb726d48Sopenharmony_ci return; 364fb726d48Sopenharmony_ci } 365fb726d48Sopenharmony_ci this.callChartType = type; 366fb726d48Sopenharmony_ci this.callChartId = id; // @ts-ignore 367fb726d48Sopenharmony_ci row.name = `CallChart [${nodes[0].title}]`; 368fb726d48Sopenharmony_ci row.isComplete = false; 369fb726d48Sopenharmony_ci row.needRefresh = true; 370fb726d48Sopenharmony_ci row.drawFrame(); 371fb726d48Sopenharmony_ci } 372fb726d48Sopenharmony_ci }; 373fb726d48Sopenharmony_ci } 374fb726d48Sopenharmony_ci 375fb726d48Sopenharmony_ci async initCpuMerge(): Promise<void> { 376fb726d48Sopenharmony_ci let cpuMergeRow = TraceRow.skeleton<HiPerfCpuStruct>(); 377fb726d48Sopenharmony_ci cpuMergeRow.rowId = 'HiPerf-cpu-merge'; 378fb726d48Sopenharmony_ci cpuMergeRow.index = 0; 379fb726d48Sopenharmony_ci cpuMergeRow.rowType = TraceRow.ROW_TYPE_HIPERF_CPU; 380fb726d48Sopenharmony_ci cpuMergeRow.rowParentId = 'HiPerf'; 381fb726d48Sopenharmony_ci cpuMergeRow.rowHidden = !this.rowFolder.expansion; 382fb726d48Sopenharmony_ci cpuMergeRow.folder = false; 383fb726d48Sopenharmony_ci cpuMergeRow.drawType = -2; 384fb726d48Sopenharmony_ci cpuMergeRow.name = 'HiPerf'; 385fb726d48Sopenharmony_ci cpuMergeRow.style.height = '40px'; 386fb726d48Sopenharmony_ci cpuMergeRow.setAttribute('children', ''); 387fb726d48Sopenharmony_ci cpuMergeRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 388fb726d48Sopenharmony_ci cpuMergeRow.selectChangeHandler = this.trace.selectChangeHandler; //@ts-ignore 389fb726d48Sopenharmony_ci cpuMergeRow.supplierFrame = (): Promise<unknown> => { 390fb726d48Sopenharmony_ci return hiperfCpuDataSender( 391fb726d48Sopenharmony_ci -1, 392fb726d48Sopenharmony_ci cpuMergeRow.drawType, 393fb726d48Sopenharmony_ci this.maxCpuId + 1, 394fb726d48Sopenharmony_ci SpHiPerf.stringResult?.fValue || 1, 395fb726d48Sopenharmony_ci TraceRow.range?.scale || 50, 396fb726d48Sopenharmony_ci cpuMergeRow 397fb726d48Sopenharmony_ci ); 398fb726d48Sopenharmony_ci }; 399fb726d48Sopenharmony_ci cpuMergeRow.focusHandler = (): void => this.hoverTip(cpuMergeRow, HiPerfCpuStruct.hoverStruct); 400fb726d48Sopenharmony_ci cpuMergeRow.findHoverStruct = (): void => { 401fb726d48Sopenharmony_ci HiPerfCpuStruct.hoverStruct = cpuMergeRow.getHoverStruct(false, (TraceRow.range?.scale || 50) <= 30_000_000); 402fb726d48Sopenharmony_ci }; 403fb726d48Sopenharmony_ci cpuMergeRow.onThreadHandler = this.rowThreadHandler<HiperfCpuRender2>( 404fb726d48Sopenharmony_ci 'HiPerf-Cpu-2', 405fb726d48Sopenharmony_ci 'context', 406fb726d48Sopenharmony_ci { 407fb726d48Sopenharmony_ci type: 'HiPerf-Cpu-Merge', 408fb726d48Sopenharmony_ci maxCpu: this.maxCpuId + 1, 409fb726d48Sopenharmony_ci intervalPerf: SpHiPerf.stringResult?.fValue || 1, 410fb726d48Sopenharmony_ci }, 411fb726d48Sopenharmony_ci cpuMergeRow, 412fb726d48Sopenharmony_ci this.trace 413fb726d48Sopenharmony_ci ); 414fb726d48Sopenharmony_ci this.rowFolder.addChildTraceRow(cpuMergeRow); 415fb726d48Sopenharmony_ci this.rowList?.push(cpuMergeRow); 416fb726d48Sopenharmony_ci } 417fb726d48Sopenharmony_ci 418fb726d48Sopenharmony_ci //@ts-ignore 419fb726d48Sopenharmony_ci rowThreadHandler<T>(tag: string, contextField: string, arg: unknown, row: TraceRow<unknown>, trace: SpSystemTrace) { 420fb726d48Sopenharmony_ci return (useCache: boolean): void => { 421fb726d48Sopenharmony_ci let context: CanvasRenderingContext2D = getRowContext(row, trace); 422fb726d48Sopenharmony_ci row.canvasSave(context); //@ts-ignore 423fb726d48Sopenharmony_ci arg.useCache = useCache; //@ts-ignore 424fb726d48Sopenharmony_ci arg.scale = TraceRow.range?.scale || 50; //@ts-ignore 425fb726d48Sopenharmony_ci arg.range = TraceRow.range; 426fb726d48Sopenharmony_ci if (contextField) { 427fb726d48Sopenharmony_ci //@ts-ignore 428fb726d48Sopenharmony_ci arg[contextField] = context; 429fb726d48Sopenharmony_ci } //@ts-ignore 430fb726d48Sopenharmony_ci (renders[tag] as unknown).renderMainThread(arg, row); 431fb726d48Sopenharmony_ci row.canvasRestore(context, trace); 432fb726d48Sopenharmony_ci }; 433fb726d48Sopenharmony_ci } 434fb726d48Sopenharmony_ci 435fb726d48Sopenharmony_ci async initCpu(): Promise<void> { 436fb726d48Sopenharmony_ci for (let i = 0; i <= this.maxCpuId; i++) { 437fb726d48Sopenharmony_ci let perfCpuRow = TraceRow.skeleton<HiPerfCpuStruct>(); 438fb726d48Sopenharmony_ci perfCpuRow.rowId = `HiPerf-cpu-${i}`; 439fb726d48Sopenharmony_ci perfCpuRow.index = i; 440fb726d48Sopenharmony_ci perfCpuRow.rowType = TraceRow.ROW_TYPE_HIPERF_CPU; 441fb726d48Sopenharmony_ci perfCpuRow.rowParentId = 'HiPerf'; 442fb726d48Sopenharmony_ci perfCpuRow.rowHidden = !this.rowFolder.expansion; 443fb726d48Sopenharmony_ci perfCpuRow.folder = false; 444fb726d48Sopenharmony_ci perfCpuRow.drawType = -2; 445fb726d48Sopenharmony_ci perfCpuRow.name = `Cpu ${i}`; 446fb726d48Sopenharmony_ci perfCpuRow.setAttribute('children', ''); 447fb726d48Sopenharmony_ci perfCpuRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 448fb726d48Sopenharmony_ci perfCpuRow.selectChangeHandler = this.trace.selectChangeHandler; 449fb726d48Sopenharmony_ci perfCpuRow.style.height = '40px'; //@ts-ignore 450fb726d48Sopenharmony_ci perfCpuRow.supplierFrame = (): Promise<unknown> => { 451fb726d48Sopenharmony_ci return hiperfCpuDataSender( 452fb726d48Sopenharmony_ci i, 453fb726d48Sopenharmony_ci perfCpuRow.drawType, 454fb726d48Sopenharmony_ci this.maxCpuId + 1, 455fb726d48Sopenharmony_ci SpHiPerf.stringResult?.fValue || 1, 456fb726d48Sopenharmony_ci TraceRow.range?.scale || 50, 457fb726d48Sopenharmony_ci perfCpuRow 458fb726d48Sopenharmony_ci ); 459fb726d48Sopenharmony_ci }; 460fb726d48Sopenharmony_ci perfCpuRow.focusHandler = (): void => this.hoverTip(perfCpuRow, HiPerfCpuStruct.hoverStruct); 461fb726d48Sopenharmony_ci perfCpuRow.findHoverStruct = (): void => { 462fb726d48Sopenharmony_ci HiPerfCpuStruct.hoverStruct = perfCpuRow.getHoverStruct(false, (TraceRow.range?.scale || 50) <= 30_000_000); 463fb726d48Sopenharmony_ci }; 464fb726d48Sopenharmony_ci perfCpuRow.onThreadHandler = this.rowThreadHandler<HiperfCpuRender2>( 465fb726d48Sopenharmony_ci 'HiPerf-Cpu-2', 466fb726d48Sopenharmony_ci 'context', 467fb726d48Sopenharmony_ci { 468fb726d48Sopenharmony_ci type: `HiPerf-Cpu-${i}`, 469fb726d48Sopenharmony_ci maxCpu: this.maxCpuId + 1, 470fb726d48Sopenharmony_ci intervalPerf: SpHiPerf.stringResult?.fValue || 1, 471fb726d48Sopenharmony_ci }, 472fb726d48Sopenharmony_ci perfCpuRow, 473fb726d48Sopenharmony_ci this.trace 474fb726d48Sopenharmony_ci ); 475fb726d48Sopenharmony_ci this.rowFolder.addChildTraceRow(perfCpuRow); 476fb726d48Sopenharmony_ci this.rowList?.push(perfCpuRow); 477fb726d48Sopenharmony_ci } 478fb726d48Sopenharmony_ci } 479fb726d48Sopenharmony_ci 480fb726d48Sopenharmony_ci async initProcess(): Promise<void> { 481fb726d48Sopenharmony_ci //@ts-ignore 482fb726d48Sopenharmony_ci Reflect.ownKeys(this.group).forEach((key, index): void => { 483fb726d48Sopenharmony_ci //@ts-ignore 484fb726d48Sopenharmony_ci let array = this.group[key] as Array<PerfThread>; 485fb726d48Sopenharmony_ci let process = array.filter((th): boolean => th.pid === th.tid)[0]; 486fb726d48Sopenharmony_ci let row = TraceRow.skeleton<HiPerfProcessStruct>(); 487fb726d48Sopenharmony_ci row.rowId = `${process.pid}-Perf-Process`; 488fb726d48Sopenharmony_ci row.index = index; 489fb726d48Sopenharmony_ci row.rowType = TraceRow.ROW_TYPE_HIPERF_PROCESS; 490fb726d48Sopenharmony_ci row.rowParentId = 'HiPerf'; 491fb726d48Sopenharmony_ci row.rowHidden = !this.rowFolder.expansion; 492fb726d48Sopenharmony_ci row.folder = true; 493fb726d48Sopenharmony_ci row.drawType = -2; 494fb726d48Sopenharmony_ci if (SpChartManager.APP_STARTUP_PID_ARR.find((pid) => pid === process.pid) !== undefined) { 495fb726d48Sopenharmony_ci row.addTemplateTypes('AppStartup'); 496fb726d48Sopenharmony_ci } 497fb726d48Sopenharmony_ci row.addTemplateTypes('HiPerf'); 498fb726d48Sopenharmony_ci row.name = `${process.processName || 'Process'} [${process.pid}]`; 499fb726d48Sopenharmony_ci row.folderPaddingLeft = 6; 500fb726d48Sopenharmony_ci row.style.height = '40px'; 501fb726d48Sopenharmony_ci row.favoriteChangeHandler = this.trace.favoriteChangeHandler; 502fb726d48Sopenharmony_ci row.selectChangeHandler = this.trace.selectChangeHandler; //@ts-ignore 503fb726d48Sopenharmony_ci row.supplierFrame = (): Promise<unknown> => { 504fb726d48Sopenharmony_ci return hiperfProcessDataSender( 505fb726d48Sopenharmony_ci process.pid, 506fb726d48Sopenharmony_ci row.drawType, 507fb726d48Sopenharmony_ci this.maxCpuId + 1, 508fb726d48Sopenharmony_ci SpHiPerf.stringResult?.fValue || 1, 509fb726d48Sopenharmony_ci TraceRow.range?.scale || 50, 510fb726d48Sopenharmony_ci row 511fb726d48Sopenharmony_ci ); 512fb726d48Sopenharmony_ci }; 513fb726d48Sopenharmony_ci row.focusHandler = (): void => this.hoverTip(row, HiPerfProcessStruct.hoverStruct); 514fb726d48Sopenharmony_ci row.findHoverStruct = (): void => { 515fb726d48Sopenharmony_ci HiPerfProcessStruct.hoverStruct = row.getHoverStruct(false, (TraceRow.range?.scale || 50) <= 30_000_000); 516fb726d48Sopenharmony_ci }; 517fb726d48Sopenharmony_ci row.onThreadHandler = this.rowThreadHandler<HiperfProcessRender2>( 518fb726d48Sopenharmony_ci 'HiPerf-Process-2', 519fb726d48Sopenharmony_ci 'context', 520fb726d48Sopenharmony_ci { 521fb726d48Sopenharmony_ci type: `HiPerf-Process-${row.index}`, 522fb726d48Sopenharmony_ci intervalPerf: SpHiPerf.stringResult?.fValue || 1, 523fb726d48Sopenharmony_ci }, 524fb726d48Sopenharmony_ci row, 525fb726d48Sopenharmony_ci this.trace 526fb726d48Sopenharmony_ci ); 527fb726d48Sopenharmony_ci this.rowFolder.addChildTraceRow(row); 528fb726d48Sopenharmony_ci this.rowList?.push(row); 529fb726d48Sopenharmony_ci this.addHiPerfThreadRow(array, row); 530fb726d48Sopenharmony_ci }); 531fb726d48Sopenharmony_ci } 532fb726d48Sopenharmony_ci 533fb726d48Sopenharmony_ci addHiPerfThreadRow(array: PerfThread[], row: TraceRow<HiPerfProcessStruct>): void { 534fb726d48Sopenharmony_ci array.forEach((thObj, thIdx): void => { 535fb726d48Sopenharmony_ci let thread = TraceRow.skeleton<HiPerfThreadStruct>(); 536fb726d48Sopenharmony_ci thread.rowId = `${thObj.tid}-Perf-Thread`; 537fb726d48Sopenharmony_ci thread.index = thIdx; 538fb726d48Sopenharmony_ci thread.rowType = TraceRow.ROW_TYPE_HIPERF_THREAD; 539fb726d48Sopenharmony_ci thread.rowParentId = row.rowId; 540fb726d48Sopenharmony_ci thread.rowHidden = !row.expansion; 541fb726d48Sopenharmony_ci thread.folder = false; 542fb726d48Sopenharmony_ci thread.drawType = -2; 543fb726d48Sopenharmony_ci thread.name = `${thObj.threadName || 'Thread'} [${thObj.tid}]`; 544fb726d48Sopenharmony_ci thread.setAttribute('children', ''); 545fb726d48Sopenharmony_ci thread.folderPaddingLeft = 0; 546fb726d48Sopenharmony_ci thread.style.height = '40px'; 547fb726d48Sopenharmony_ci thread.favoriteChangeHandler = this.trace.favoriteChangeHandler; 548fb726d48Sopenharmony_ci thread.selectChangeHandler = this.trace.selectChangeHandler; //@ts-ignore 549fb726d48Sopenharmony_ci thread.supplierFrame = (): Promise<unknown> => { 550fb726d48Sopenharmony_ci return hiperfThreadDataSender( 551fb726d48Sopenharmony_ci thObj.tid, 552fb726d48Sopenharmony_ci thread.drawType, 553fb726d48Sopenharmony_ci this.maxCpuId + 1, 554fb726d48Sopenharmony_ci SpHiPerf.stringResult?.fValue || 1, 555fb726d48Sopenharmony_ci TraceRow.range?.scale || 50, 556fb726d48Sopenharmony_ci thread 557fb726d48Sopenharmony_ci ); 558fb726d48Sopenharmony_ci }; 559fb726d48Sopenharmony_ci thread.focusHandler = (): void => this.hoverTip(thread, HiPerfThreadStruct.hoverStruct); 560fb726d48Sopenharmony_ci thread.findHoverStruct = (): void => { 561fb726d48Sopenharmony_ci HiPerfThreadStruct.hoverStruct = thread.getHoverStruct(false, (TraceRow.range?.scale || 50) <= 30_000_000); 562fb726d48Sopenharmony_ci }; 563fb726d48Sopenharmony_ci thread.onThreadHandler = this.rowThreadHandler<HiperfThreadRender2>( 564fb726d48Sopenharmony_ci 'HiPerf-Thread-2', 565fb726d48Sopenharmony_ci 'context', 566fb726d48Sopenharmony_ci { 567fb726d48Sopenharmony_ci type: `HiPerf-Thread-${row.index}-${thread.index}`, 568fb726d48Sopenharmony_ci intervalPerf: SpHiPerf.stringResult?.fValue || 1, 569fb726d48Sopenharmony_ci }, 570fb726d48Sopenharmony_ci thread, 571fb726d48Sopenharmony_ci this.trace 572fb726d48Sopenharmony_ci ); 573fb726d48Sopenharmony_ci row.addChildTraceRow(thread); 574fb726d48Sopenharmony_ci this.rowList?.push(thread); 575fb726d48Sopenharmony_ci }); 576fb726d48Sopenharmony_ci } 577fb726d48Sopenharmony_ci 578fb726d48Sopenharmony_ci //@ts-ignore 579fb726d48Sopenharmony_ci resetChartData(row: TraceRow<unknown>): void { 580fb726d48Sopenharmony_ci row.dataList = []; 581fb726d48Sopenharmony_ci row.dataList2 = []; 582fb726d48Sopenharmony_ci row.dataListCache = []; 583fb726d48Sopenharmony_ci row.isComplete = false; 584fb726d48Sopenharmony_ci } 585fb726d48Sopenharmony_ci 586fb726d48Sopenharmony_ci resetAllChartData(): void { 587fb726d48Sopenharmony_ci const callChartRow = this.rowList?.find(row => row.rowId === 'HiPerf-callchart'); 588fb726d48Sopenharmony_ci if (callChartRow) { 589fb726d48Sopenharmony_ci this.resetChartData(callChartRow); 590fb726d48Sopenharmony_ci } 591fb726d48Sopenharmony_ci } 592fb726d48Sopenharmony_ci 593fb726d48Sopenharmony_ci hoverTip( 594fb726d48Sopenharmony_ci //@ts-ignore 595fb726d48Sopenharmony_ci row: TraceRow<unknown>, 596fb726d48Sopenharmony_ci struct: 597fb726d48Sopenharmony_ci | HiPerfThreadStruct 598fb726d48Sopenharmony_ci | HiPerfProcessStruct 599fb726d48Sopenharmony_ci | HiPerfEventStruct 600fb726d48Sopenharmony_ci | HiPerfReportStruct 601fb726d48Sopenharmony_ci | HiPerfCpuStruct 602fb726d48Sopenharmony_ci | undefined 603fb726d48Sopenharmony_ci ): void { 604fb726d48Sopenharmony_ci let tip = ''; 605fb726d48Sopenharmony_ci let groupBy10MS = (TraceRow.range?.scale || 50) > 30_000_000; 606fb726d48Sopenharmony_ci if (struct) { 607fb726d48Sopenharmony_ci if (groupBy10MS) { 608fb726d48Sopenharmony_ci if (row.drawType === -2) { 609fb726d48Sopenharmony_ci let num: number | string = 0; 610fb726d48Sopenharmony_ci if (struct instanceof HiPerfEventStruct) { 611fb726d48Sopenharmony_ci num = Math.trunc(((struct.sum || 0) / (struct.max || 0)) * 100); 612fb726d48Sopenharmony_ci } else { 613fb726d48Sopenharmony_ci let interval = SpHiPerf.stringResult?.fValue || 1; 614fb726d48Sopenharmony_ci num = ((struct.sampleCount! / (10 / interval)) * 100).toFixed(2); 615fb726d48Sopenharmony_ci } 616fb726d48Sopenharmony_ci tip = `<span>${num}% (10.00ms)</span>`; 617fb726d48Sopenharmony_ci } else { 618fb726d48Sopenharmony_ci tip = `<span>${struct.event_count || struct.eventCount} (10.00ms)</span>`; 619fb726d48Sopenharmony_ci } 620fb726d48Sopenharmony_ci } else { 621fb726d48Sopenharmony_ci let perfCall = perfDataQuery.callChainMap.get(struct.callchain_id || 0); 622fb726d48Sopenharmony_ci if (perfCall) { 623fb726d48Sopenharmony_ci let perfName; 624fb726d48Sopenharmony_ci typeof perfCall.name === 'number' 625fb726d48Sopenharmony_ci ? (perfName = SpSystemTrace.DATA_DICT.get(parseInt(perfCall.name))) 626fb726d48Sopenharmony_ci : (perfName = perfCall.name); 627fb726d48Sopenharmony_ci tip = `<span>${perfCall ? perfName : ''} (${perfCall ? perfCall.depth : '0'} other frames)</span>`; 628fb726d48Sopenharmony_ci } 629fb726d48Sopenharmony_ci } 630fb726d48Sopenharmony_ci } 631fb726d48Sopenharmony_ci this.trace?.displayTip(row, struct, tip); 632fb726d48Sopenharmony_ci } 633fb726d48Sopenharmony_ci} 634