• 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 {BaseStruct, ColorUtils} from "./ProcedureWorkerCommon.js";
17
18let dec = new TextDecoder();
19export function rtCpu(buf: ArrayBuffer | null | undefined, res: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any) {
20    if (buf) {
21        res.length=0;
22        let pns = (endNS - startNS) / frame.width;
23        let y = frame.y + 5;
24        let height = frame.height - 10;
25
26        let str = dec.decode(buf);
27        str = str.substring(str.indexOf("\n") + 1);
28        let parse = JSON.parse(str);
29        let columns = parse.columns;
30        let values = parse.values;
31        for (let i = 0; i < values.length; i++) {
32            let obj: any = {}
33            for (let j = 0; j < columns.length; j++) {
34                obj[columns[j]] = values[i][j]
35            }
36            obj.frame = {
37                // x: obj.x1,
38                y: frame.y + 5,
39                // width: obj.x2 - obj.x1 > 0 ? obj.x2 - obj.x1 : 1,
40                height: frame.height - 10,
41            }
42            CpuStruct.setCpuFrame(obj, pns, startNS, endNS, frame)
43            res.push(obj);
44        }
45    }else{
46        let pns = (endNS - startNS) / frame.width;
47        res.forEach(it=>{
48            CpuStruct.setCpuFrame(it, pns, startNS, endNS, frame)
49        })
50    }
51}
52
53export function cpu(list: Array<any>, res: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any,use:boolean) {
54    if(use && res.length > 0){
55        let pns = (endNS - startNS) / frame.width;
56        let y = frame.y + 5;
57        let height = frame.height - 10;
58        for (let i = 0, len = res.length; i < len; i++) {
59            let it = res[i];
60            if ((it.startTime || 0) + (it.dur || 0) > startNS && (it.startTime || 0) < endNS) {
61                if (!res[i].frame) {
62                    res[i].frame = {};
63                    res[i].frame.y = y;
64                    res[i].frame.height = height;
65                }
66                CpuStruct.setCpuFrame(res[i], pns, startNS, endNS, frame)
67            }else{
68                res[i].frame = null;
69            }
70        }
71        return;
72    }
73    res.length = 0;
74    if (list) {
75        let pns = (endNS - startNS) / frame.width;
76        let y = frame.y + 5;
77        let height = frame.height - 10;
78        for (let i = 0, len = list.length; i < len; i++) {
79            let it = list[i];
80            if ((it.startTime || 0) + (it.dur || 0) > startNS && (it.startTime || 0) < endNS) {
81                if (!list[i].frame) {
82                    list[i].frame = {};
83                    list[i].frame.y = y;
84                    list[i].frame.height = height;
85                }
86                CpuStruct.setCpuFrame(list[i], pns, startNS, endNS, frame)
87                if (i > 0 && ((list[i - 1].frame?.x || 0) == (list[i].frame?.x || 0) && ((list[i - 1].frame?.width || 0) == (list[i].frame?.width || 0)))) {
88
89                } else {
90                    res.push(list[i])
91                }
92            }else{
93                it.frame = null;
94            }
95        }
96    }
97}
98
99export class CpuStruct extends BaseStruct {
100    static cpuCount: number = 1 //最大cpu数量
101    static hoverCpuStruct: CpuStruct | undefined;
102    static selectCpuStruct: CpuStruct | undefined;
103    cpu: number | undefined
104    dur: number | undefined
105    end_state: string | undefined
106    id: number | undefined
107    name: string | undefined
108    priority: number | undefined
109    processCmdLine: string | undefined
110    processId: number | undefined
111    processName: string | undefined
112    schedId: number | undefined
113    startTime: number | undefined
114    tid: number | undefined
115    type: string | undefined
116
117    static draw(ctx: CanvasRenderingContext2D, data: CpuStruct) {
118        if (data.frame) {
119            let width = data.frame.width || 0;
120            if (data.processId === CpuStruct.hoverCpuStruct?.processId || !CpuStruct.hoverCpuStruct) {
121                ctx.fillStyle = ColorUtils.colorForTid((data.processId || 0) > 0 ? (data.processId || 0) : (data.tid || 0))
122            } else {
123                ctx.fillStyle = "#e0e0e0"
124            }
125            ctx.fillRect(data.frame.x, data.frame.y, width, data.frame.height)
126            if (width > textPadding * 2) {
127                let process = `${(data.processName || "Process")} [${data.processId}]`
128                let thread = `${data.name || "Thread"} [${data.tid}]`
129                let processMeasure = ctx.measureText(process);
130                let threadMeasure = ctx.measureText(thread);
131                let processCharWidth = Math.round(processMeasure.width / process.length)
132                let threadCharWidth = Math.round(threadMeasure.width / thread.length)
133                ctx.fillStyle = "#ffffff"
134                let y = data.frame.height / 2 + data.frame.y;
135                if (processMeasure.width < width - textPadding * 2) {
136                    let x1 = Math.floor(width / 2 - processMeasure.width / 2 + data.frame.x + textPadding)
137                    ctx.textBaseline = "bottom";
138                    ctx.fillText(process, x1, y, width - textPadding * 2)
139                } else if (width - textPadding * 2 > processCharWidth * 4) {
140                    let chatNum = (width - textPadding * 2) / processCharWidth;
141                    let x1 = data.frame.x + textPadding
142                    ctx.textBaseline = "bottom";
143                    ctx.fillText(process.substring(0, chatNum - 4) + '...', x1, y, width - textPadding * 2)
144                }
145                ctx.fillStyle = "#ffffff"
146                ctx.font = "9px sans-serif";
147                if (threadMeasure.width < width - textPadding * 2) {
148                    ctx.textBaseline = "top";
149                    let x2 = Math.floor(width / 2 - threadMeasure.width / 2 + data.frame.x + textPadding)
150                    ctx.fillText(thread, x2, y + 2, width - textPadding * 2)
151                } else if (width - textPadding * 2 > threadCharWidth * 4) {
152                    let chatNum = (width - textPadding * 2) / threadCharWidth;
153                    let x1 = data.frame.x + textPadding
154                    ctx.textBaseline = "top";
155                    ctx.fillText(thread.substring(0, chatNum - 4) + '...', x1, y + 2, width - textPadding * 2)
156                }
157            }
158            if (CpuStruct.selectCpuStruct && CpuStruct.equals(CpuStruct.selectCpuStruct, data)) {
159                ctx.strokeStyle = '#232c5d'
160                ctx.lineWidth = 2
161                ctx.strokeRect(data.frame.x, data.frame.y, width - 2, data.frame.height)
162            }
163        }
164    }
165
166    static setCpuFrame(node: any, pns: number, startNS: number, endNS: number, frame: any) {
167        if ((node.startTime || 0) < startNS) {
168            node.frame.x = 0;
169        } else {
170            node.frame.x = Math.floor(((node.startTime || 0) - startNS) / pns);
171        }
172        if ((node.startTime || 0) + (node.dur || 0) > endNS) {
173            node.frame.width = frame.width - node.frame.x;
174        } else {
175            node.frame.width = Math.ceil(((node.startTime || 0) + (node.dur || 0) - startNS) / pns - node.frame.x);
176        }
177        if (node.frame.width < 1) {
178            node.frame.width = 1;
179        }
180    }
181
182    static equals(d1: CpuStruct, d2: CpuStruct): boolean {
183        if (d1 && d2 && d1.cpu == d2.cpu &&
184            d1.tid == d2.tid &&
185            d1.processId == d2.processId &&
186            d1.startTime == d2.startTime &&
187            d1.dur == d2.dur) {
188            return true;
189        } else {
190            return false;
191        }
192    }
193}
194
195export class WakeupBean {
196    wakeupTime: number | undefined
197    cpu: number | undefined
198    process: string | undefined
199    pid: number | undefined
200    thread: string | undefined
201    tid: number | undefined
202    schedulingLatency: number | undefined
203    schedulingDesc: string | undefined
204
205}
206
207const textPadding = 2;