• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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