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