1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 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 */ 15 16import { SpSystemTrace } from '../SpSystemTrace'; 17import { info } from '../../../log/Log'; 18import { TraceRow } from '../trace/base/TraceRow'; 19import { procedurePool } from '../../database/Procedure'; 20import { CpuRender, CpuStruct } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 21import { renders } from '../../database/ui-worker/ProcedureWorker'; 22import { Utils } from '../trace/base/Utils'; 23import { cpuDataSender } from '../../database/data-trafic/CpuDataSender'; 24import { TraficEnum } from '../../database/data-trafic/utils/QueryEnum'; 25import {cpuList} from "../../database/data-trafic/utils/AllMemoryCache"; 26import {queryCpuCount, queryCpuDataCount, queryCpuMax, queryCpuSchedSlice} from "../../database/sql/Cpu.sql"; 27 28export class SpCpuChart { 29 private trace: SpSystemTrace; 30 31 constructor(trace: SpSystemTrace) { 32 this.trace = trace; 33 } 34 35 async init() { 36 let CpuStartTime = new Date().getTime(); 37 let array = await queryCpuMax(); 38 let cpuCountResult = await queryCpuCount(); 39 if (cpuCountResult && cpuCountResult.length > 0 && cpuCountResult[0]) { 40 (window as any).cpuCount = cpuCountResult[0].cpuCount; 41 } else { 42 (window as any).cpuCount = 0; 43 } 44 let dataCount: { count: number; cpu: number }[] = (await queryCpuDataCount()) as { count: number; cpu: number }[]; 45 let cpuSchedSlice = await queryCpuSchedSlice(); 46 this.initSchedSliceData(cpuSchedSlice); 47 info('Cpu trace row data size is: ', array.length); 48 if (array && array.length > 0 && array[0]) { 49 let cpuMax = array[0].cpu; 50 CpuStruct.cpuCount = cpuMax + 1; 51 for (let i1 = 0; i1 < CpuStruct.cpuCount; i1++) { 52 if (dataCount.find((it) => it.cpu === i1 && it.count > 0)) { 53 const cpuId = i1; 54 let traceRow = TraceRow.skeleton<CpuStruct>(); 55 traceRow.rowId = `${cpuId}`; 56 traceRow.rowType = TraceRow.ROW_TYPE_CPU; 57 traceRow.rowParentId = ''; 58 traceRow.style.height = '40px'; 59 traceRow.name = `Cpu ${cpuId}`; 60 traceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 61 traceRow.selectChangeHandler = this.trace.selectChangeHandler; 62 traceRow.supplierFrame = () => { 63 return cpuDataSender(cpuId, traceRow).then((res) => { 64 const filterList = SpSystemTrace.keyPathList.filter((item) => { 65 return item.cpu === cpuId; 66 }); 67 res.push(...filterList); 68 res.forEach((it, i, arr) => { 69 let p = Utils.PROCESS_MAP.get(it.processId!); 70 let t = Utils.THREAD_MAP.get(it.tid!); 71 let slice = Utils.SCHED_SLICE_MAP.get(`${it.id}-${it.startTime}`); 72 if (slice) { 73 it.end_state = slice.endState; 74 it.priority = slice.priority; 75 } 76 it.processName = p; 77 it.processCmdLine = p; 78 it.name = t; 79 it.type = 'thread'; 80 }); 81 return res; 82 }); 83 }; 84 traceRow.focusHandler = () => { 85 this.trace?.displayTip( 86 traceRow, 87 CpuStruct.hoverCpuStruct, 88 `<span>P:${CpuStruct.hoverCpuStruct?.processName || 'Process'} [${ 89 CpuStruct.hoverCpuStruct?.processId 90 }]</span><span>T:${CpuStruct.hoverCpuStruct?.name} [${CpuStruct.hoverCpuStruct?.tid}] [Prio:${ 91 CpuStruct.hoverCpuStruct?.priority || 0 92 }]</span>` 93 ); 94 }; 95 traceRow.findHoverStruct = () => { 96 CpuStruct.hoverCpuStruct = traceRow.getHoverStruct(); 97 }; 98 traceRow.onThreadHandler = (useCache: boolean, buf: ArrayBuffer | undefined | null) => { 99 let context: CanvasRenderingContext2D; 100 if (traceRow.currentContext) { 101 context = traceRow.currentContext; 102 } else { 103 context = traceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 104 } 105 traceRow.canvasSave(context); 106 (renders['cpu-data'] as CpuRender).renderMainThread( 107 { 108 ctx: context, 109 useCache: useCache, 110 type: `cpu-data-${i1}`, 111 translateY: traceRow.translateY, 112 }, 113 traceRow 114 ); 115 traceRow.canvasRestore(context, this.trace); 116 }; 117 this.trace.rowsEL?.appendChild(traceRow); 118 } 119 } 120 } 121 let CpuDurTime = new Date().getTime() - CpuStartTime; 122 info('The time to load the Cpu data is: ', CpuDurTime); 123 } 124 125 initProcessThreadStateData = async (progress: Function) => { 126 let time = new Date().getTime(); 127 progress('StateProcessThread', 93); 128 procedurePool.submitWithName('logic0', 'spt-init', {}, undefined, (res: any) => {}); 129 let durTime = new Date().getTime() - time; 130 info('The time to load the first ProcessThreadState data is: ', durTime); 131 }; 132 133 initCpuIdle0Data = async (progress: Function) => { 134 let time = new Date().getTime(); 135 progress('CPU Idle', 94); 136 procedurePool.submitWithName( 137 'logic0', 138 'scheduling-getCpuIdle0', 139 { 140 endTs: (window as any).recordEndNS, 141 total: (window as any).totalNS, 142 }, 143 undefined, 144 (res: any) => {} 145 ); 146 let durTime = new Date().getTime() - time; 147 info('The time to load the first CPU Idle0 data is: ', durTime); 148 }; 149 150 initSchedSliceData(arr: any[]) { 151 Utils.SCHED_SLICE_MAP.clear(); 152 arr.forEach((value) => { 153 Utils.SCHED_SLICE_MAP.set(`${value.itid}-${value.ts}`, { endState: value.endState, priority: value.priority }); 154 }); 155 } 156 157 initSchedulingPTData = async (progress: Function) => { 158 let time = new Date().getTime(); 159 progress('CPU Idle', 94); 160 procedurePool.submitWithName('logic0', 'scheduling-getProcessAndThread', {}, undefined, (res: any) => {}); 161 let durTime = new Date().getTime() - time; 162 info('The time to load the first CPU Idle0 data is: ', durTime); 163 }; 164 165 initSchedulingFreqData = async (progress: Function) => { 166 let time = new Date().getTime(); 167 progress('CPU Scheduling Freq', 94); 168 procedurePool.submitWithName('logic0', 'scheduling-initFreqData', {}, undefined, (res: any) => {}); 169 let durTime = new Date().getTime() - time; 170 info('The time to load the first CPU Idle0 data is: ', durTime); 171 }; 172} 173