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 { info } from '../../../log/Log'; 18fb726d48Sopenharmony_ciimport { TraceRow } from '../trace/base/TraceRow'; 19fb726d48Sopenharmony_ciimport { procedurePool } from '../../database/Procedure'; 20fb726d48Sopenharmony_ciimport { CpuRender, CpuStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 21fb726d48Sopenharmony_ciimport { renders } from '../../database/ui-worker/ProcedureWorker'; 22fb726d48Sopenharmony_ciimport { Utils } from '../trace/base/Utils'; 23fb726d48Sopenharmony_ciimport { cpuDataSender } from '../../database/data-trafic/CpuDataSender'; 24fb726d48Sopenharmony_ciimport { queryCpuCount, queryCpuMax, queryCpuSchedSlice } from '../../database/sql/Cpu.sql'; 25fb726d48Sopenharmony_ciimport { rowThreadHandler } from './SpChartManager'; 26fb726d48Sopenharmony_ciimport { SpStatisticsHttpUtil } from '../../../statistics/util/SpStatisticsHttpUtil'; 27fb726d48Sopenharmony_ci 28fb726d48Sopenharmony_ciexport class SpCpuChart { 29fb726d48Sopenharmony_ci private trace: SpSystemTrace; 30fb726d48Sopenharmony_ci 31fb726d48Sopenharmony_ci constructor(trace: SpSystemTrace) { 32fb726d48Sopenharmony_ci this.trace = trace; 33fb726d48Sopenharmony_ci } 34fb726d48Sopenharmony_ci 35fb726d48Sopenharmony_ci private cpuSupplierFrame(traceRow: TraceRow<CpuStruct>, cpuId: number): void { 36fb726d48Sopenharmony_ci traceRow.supplierFrame = async (): Promise<CpuStruct[]> => { 37fb726d48Sopenharmony_ci const res = await cpuDataSender(cpuId, traceRow); 38fb726d48Sopenharmony_ci const filterList = SpSystemTrace.keyPathList.filter((item) => { 39fb726d48Sopenharmony_ci return item.cpu === cpuId; 40fb726d48Sopenharmony_ci }); 41fb726d48Sopenharmony_ci res.push(...filterList); 42fb726d48Sopenharmony_ci res.forEach((it, i, arr) => { 43fb726d48Sopenharmony_ci let p = Utils.getInstance().getProcessMap().get(it.processId!); 44fb726d48Sopenharmony_ci let t = Utils.getInstance().getThreadMap().get(it.tid!); 45fb726d48Sopenharmony_ci let slice = Utils.getInstance().getSchedSliceMap().get(`${it.id}-${it.startTime}`); 46fb726d48Sopenharmony_ci if (slice) { 47fb726d48Sopenharmony_ci it.end_state = slice.endState; 48fb726d48Sopenharmony_ci it.priority = slice.priority; 49fb726d48Sopenharmony_ci } 50fb726d48Sopenharmony_ci it.processName = p; 51fb726d48Sopenharmony_ci it.processCmdLine = p; 52fb726d48Sopenharmony_ci it.name = t; 53fb726d48Sopenharmony_ci it.type = 'thread'; 54fb726d48Sopenharmony_ci }); 55fb726d48Sopenharmony_ci return res; 56fb726d48Sopenharmony_ci }; 57fb726d48Sopenharmony_ci } 58fb726d48Sopenharmony_ci 59fb726d48Sopenharmony_ci private cpuThreadHandler(traceRow: TraceRow<CpuStruct>, i1: number): void { 60fb726d48Sopenharmony_ci traceRow.onThreadHandler = (useCache: boolean, buf: ArrayBuffer | undefined | null): void => { 61fb726d48Sopenharmony_ci let context: CanvasRenderingContext2D; 62fb726d48Sopenharmony_ci if (traceRow.currentContext) { 63fb726d48Sopenharmony_ci context = traceRow.currentContext; 64fb726d48Sopenharmony_ci } else { 65fb726d48Sopenharmony_ci context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 66fb726d48Sopenharmony_ci } 67fb726d48Sopenharmony_ci traceRow.canvasSave(context); 68fb726d48Sopenharmony_ci (renders['cpu-data'] as CpuRender).renderMainThread( 69fb726d48Sopenharmony_ci { 70fb726d48Sopenharmony_ci ctx: context, 71fb726d48Sopenharmony_ci useCache: useCache, 72fb726d48Sopenharmony_ci type: `cpu-data-${i1}`, 73fb726d48Sopenharmony_ci translateY: traceRow.translateY, 74fb726d48Sopenharmony_ci }, 75fb726d48Sopenharmony_ci traceRow 76fb726d48Sopenharmony_ci ); 77fb726d48Sopenharmony_ci traceRow.canvasRestore(context, this.trace); 78fb726d48Sopenharmony_ci }; 79fb726d48Sopenharmony_ci } 80fb726d48Sopenharmony_ci 81fb726d48Sopenharmony_ci // @ts-ignore 82fb726d48Sopenharmony_ci async init(cpuDataCount?: Map<number, number>, parentRow?: TraceRow<unknown>, traceId?: string): Promise<void> { 83fb726d48Sopenharmony_ci let CpuStartTime = new Date().getTime(); 84fb726d48Sopenharmony_ci let array = await queryCpuMax(traceId); 85fb726d48Sopenharmony_ci let cpuCountResult = await queryCpuCount(traceId); 86fb726d48Sopenharmony_ci if (cpuCountResult && cpuCountResult.length > 0 && cpuCountResult[0]) { 87fb726d48Sopenharmony_ci // @ts-ignore 88fb726d48Sopenharmony_ci Utils.getInstance().setWinCpuCount(cpuCountResult[0].cpuCount, traceId); 89fb726d48Sopenharmony_ci } else { 90fb726d48Sopenharmony_ci Utils.getInstance().setWinCpuCount(0, traceId); 91fb726d48Sopenharmony_ci } 92fb726d48Sopenharmony_ci let cpuSchedSlice = await queryCpuSchedSlice(traceId); 93fb726d48Sopenharmony_ci this.initSchedSliceData(cpuSchedSlice, traceId); 94fb726d48Sopenharmony_ci info('Cpu trace row data size is: ', array.length); 95fb726d48Sopenharmony_ci if (array && array.length > 0 && array[0]) { 96fb726d48Sopenharmony_ci // 有cpu泳道,统计ftrace插件,cpu插件 97fb726d48Sopenharmony_ci let requestBody = { 98fb726d48Sopenharmony_ci eventData: { 99fb726d48Sopenharmony_ci plugin: ['ftrace-plugin', 'cpu-plugin'] 100fb726d48Sopenharmony_ci } 101fb726d48Sopenharmony_ci }; 102fb726d48Sopenharmony_ci SpStatisticsHttpUtil.recordPluginUsage(requestBody); 103fb726d48Sopenharmony_ci //@ts-ignore 104fb726d48Sopenharmony_ci let cpuMax = array[0].cpu + 1; 105fb726d48Sopenharmony_ci Utils.getInstance().setCpuCount(cpuMax, traceId); 106fb726d48Sopenharmony_ci for (let i1 = 0; i1 < cpuMax; i1++) { 107fb726d48Sopenharmony_ci if (cpuDataCount && (cpuDataCount.get(i1) || 0) > 0) { 108fb726d48Sopenharmony_ci let traceRow = this.createCpuRow(i1, traceId); 109fb726d48Sopenharmony_ci if (parentRow) { 110fb726d48Sopenharmony_ci parentRow.addChildTraceRow(traceRow); 111fb726d48Sopenharmony_ci } else { 112fb726d48Sopenharmony_ci this.trace.rowsEL?.appendChild(traceRow); 113fb726d48Sopenharmony_ci } 114fb726d48Sopenharmony_ci } 115fb726d48Sopenharmony_ci } 116fb726d48Sopenharmony_ci } 117fb726d48Sopenharmony_ci let CpuDurTime = new Date().getTime() - CpuStartTime; 118fb726d48Sopenharmony_ci info('The time to load the Cpu data is: ', CpuDurTime); 119fb726d48Sopenharmony_ci } 120fb726d48Sopenharmony_ci 121fb726d48Sopenharmony_ci createCpuRow(cpuId: number, traceId?: string): TraceRow<CpuStruct> { 122fb726d48Sopenharmony_ci let traceRow = TraceRow.skeleton<CpuStruct>(traceId); 123fb726d48Sopenharmony_ci traceRow.rowId = `${cpuId}`; 124fb726d48Sopenharmony_ci traceRow.rowType = TraceRow.ROW_TYPE_CPU; 125fb726d48Sopenharmony_ci traceRow.rowParentId = ''; 126fb726d48Sopenharmony_ci traceRow.style.height = '30px'; 127fb726d48Sopenharmony_ci traceRow.name = `Cpu ${cpuId}`; 128fb726d48Sopenharmony_ci traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 129fb726d48Sopenharmony_ci traceRow.selectChangeHandler = this.trace.selectChangeHandler; 130fb726d48Sopenharmony_ci traceRow.supplierFrame = async (): Promise<CpuStruct[]> => { 131fb726d48Sopenharmony_ci let res = await cpuDataSender(cpuId, traceRow, traceId); 132fb726d48Sopenharmony_ci const filterList = SpSystemTrace.keyPathList.filter((item): boolean => { 133fb726d48Sopenharmony_ci return item.cpu === cpuId; 134fb726d48Sopenharmony_ci }); 135fb726d48Sopenharmony_ci res.push(...filterList); 136fb726d48Sopenharmony_ci res.forEach((it, i, arr): void => { 137fb726d48Sopenharmony_ci let p = Utils.getInstance().getProcessMap(traceId).get(it.processId!); 138fb726d48Sopenharmony_ci let t = Utils.getInstance().getThreadMap(traceId).get(it.tid!); 139fb726d48Sopenharmony_ci let slice = Utils.getInstance().getSchedSliceMap(traceId).get(`${it.id}-${it.startTime}`); 140fb726d48Sopenharmony_ci if (slice) { 141fb726d48Sopenharmony_ci it.end_state = slice.endState; 142fb726d48Sopenharmony_ci it.priority = slice.priority; 143fb726d48Sopenharmony_ci } 144fb726d48Sopenharmony_ci it.processName = p; 145fb726d48Sopenharmony_ci it.processCmdLine = p; 146fb726d48Sopenharmony_ci it.name = t; 147fb726d48Sopenharmony_ci it.type = 'thread'; 148fb726d48Sopenharmony_ci }); 149fb726d48Sopenharmony_ci return res; 150fb726d48Sopenharmony_ci }; 151fb726d48Sopenharmony_ci traceRow.focusHandler = (): void => { 152fb726d48Sopenharmony_ci this.trace?.displayTip( 153fb726d48Sopenharmony_ci traceRow, 154fb726d48Sopenharmony_ci CpuStruct.hoverCpuStruct, 155fb726d48Sopenharmony_ci `<span>P:${CpuStruct.hoverCpuStruct?.processName || 'Process'} [${CpuStruct.hoverCpuStruct?.processId 156fb726d48Sopenharmony_ci }]</span><span>T:${CpuStruct.hoverCpuStruct?.name} [${CpuStruct.hoverCpuStruct?.tid}] [Prio:${CpuStruct.hoverCpuStruct?.priority || 0 157fb726d48Sopenharmony_ci }]</span>` 158fb726d48Sopenharmony_ci ); 159fb726d48Sopenharmony_ci }; 160fb726d48Sopenharmony_ci traceRow.findHoverStruct = (): void => { 161fb726d48Sopenharmony_ci CpuStruct.hoverCpuStruct = traceRow.getHoverStruct(); 162fb726d48Sopenharmony_ci }; 163fb726d48Sopenharmony_ci traceRow.onThreadHandler = rowThreadHandler<CpuRender>('cpu-data', 'ctx', { 164fb726d48Sopenharmony_ci type: `cpu-data-${cpuId}`, 165fb726d48Sopenharmony_ci translateY: traceRow.translateY, 166fb726d48Sopenharmony_ci }, traceRow, this.trace); 167fb726d48Sopenharmony_ci return traceRow; 168fb726d48Sopenharmony_ci } 169fb726d48Sopenharmony_ci 170fb726d48Sopenharmony_ci initProcessThreadStateData = async (progress: Function): Promise<void> => { 171fb726d48Sopenharmony_ci let time = new Date().getTime(); 172fb726d48Sopenharmony_ci progress('StateProcessThread', 93); 173fb726d48Sopenharmony_ci procedurePool.submitWithName('logic0', 'spt-init', {}, undefined, (res: unknown) => { }); 174fb726d48Sopenharmony_ci let durTime = new Date().getTime() - time; 175fb726d48Sopenharmony_ci info('The time to load the first ProcessThreadState data is: ', durTime); 176fb726d48Sopenharmony_ci }; 177fb726d48Sopenharmony_ci 178fb726d48Sopenharmony_ci initCpuIdle0Data = async (progress: Function): Promise<void> => { 179fb726d48Sopenharmony_ci let time = new Date().getTime(); 180fb726d48Sopenharmony_ci progress('CPU Idle', 94); 181fb726d48Sopenharmony_ci procedurePool.submitWithName( 182fb726d48Sopenharmony_ci 'logic0', 183fb726d48Sopenharmony_ci 'scheduling-getCpuIdle0', 184fb726d48Sopenharmony_ci { 185fb726d48Sopenharmony_ci // @ts-ignore 186fb726d48Sopenharmony_ci endTs: (window as unknown).recordEndNS, // @ts-ignore 187fb726d48Sopenharmony_ci total: (window as unknown).totalNS, 188fb726d48Sopenharmony_ci }, 189fb726d48Sopenharmony_ci undefined, 190fb726d48Sopenharmony_ci (res: unknown) => { } 191fb726d48Sopenharmony_ci ); 192fb726d48Sopenharmony_ci let durTime = new Date().getTime() - time; 193fb726d48Sopenharmony_ci info('The time to load the first CPU Idle0 data is: ', durTime); 194fb726d48Sopenharmony_ci }; 195fb726d48Sopenharmony_ci 196fb726d48Sopenharmony_ci initSchedSliceData(arr: unknown[], traceId?: string): void { 197fb726d48Sopenharmony_ci Utils.getInstance().getSchedSliceMap(traceId).clear(); 198fb726d48Sopenharmony_ci arr.forEach((value) => { 199fb726d48Sopenharmony_ci Utils.getInstance().getSchedSliceMap(traceId). // @ts-ignore 200fb726d48Sopenharmony_ci set(`${value.itid}-${value.ts}`, { endState: value.endState, priority: value.priority }); 201fb726d48Sopenharmony_ci }); 202fb726d48Sopenharmony_ci } 203fb726d48Sopenharmony_ci 204fb726d48Sopenharmony_ci initSchedulingPTData = async (progress: Function): Promise<void> => { 205fb726d48Sopenharmony_ci let time = new Date().getTime(); 206fb726d48Sopenharmony_ci progress('CPU Idle', 94); 207fb726d48Sopenharmony_ci procedurePool.submitWithName('logic0', 'scheduling-getProcessAndThread', {}, undefined, (res: unknown) => { }); 208fb726d48Sopenharmony_ci let durTime = new Date().getTime() - time; 209fb726d48Sopenharmony_ci info('The time to load the first CPU Idle0 data is: ', durTime); 210fb726d48Sopenharmony_ci }; 211fb726d48Sopenharmony_ci 212fb726d48Sopenharmony_ci initSchedulingFreqData = async (progress: Function): Promise<void> => { 213fb726d48Sopenharmony_ci let time = new Date().getTime(); 214fb726d48Sopenharmony_ci progress('CPU Scheduling Freq', 94); 215fb726d48Sopenharmony_ci procedurePool.submitWithName('logic0', 'scheduling-initFreqData', {}, undefined, (res: unknown) => { }); 216fb726d48Sopenharmony_ci let durTime = new Date().getTime() - time; 217fb726d48Sopenharmony_ci info('The time to load the first CPU Idle0 data is: ', durTime); 218fb726d48Sopenharmony_ci }; 219fb726d48Sopenharmony_ci} 220