• 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.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