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} from "./ProcedureWorkerCommon.js"; 17import {HiPerfCpuStruct} from "./ProcedureWorkerHiPerfCPU.js"; 18 19export function hiPerfThread(arr: Array<any>, res: Array<any>, startNS: number, endNS: number, totalNS: number, frame: any, groupBy10MS: boolean, intervalPerf: number,use:boolean) { 20 if (use && res.length > 0 && !groupBy10MS) { 21 let pns = (endNS - startNS) / frame.width; 22 let y = frame.y; 23 for (let i = 0; i < res.length; i++) { 24 let it = res[i]; 25 if((it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS){ 26 if (!it.frame) { 27 it.frame = {}; 28 it.frame.y = y; 29 } 30 it.frame.height = it.height; 31 HiPerfThreadStruct.setFrame(it, pns, startNS, endNS, frame); 32 }else{ 33 it.frame = null; 34 } 35 } 36 return; 37 } 38 res.length = 0; 39 if (arr) { 40 let list = groupBy10MS ? HiPerfThreadStruct.groupBy10MS(arr, intervalPerf) : arr; 41 let pns = (endNS - startNS) / frame.width; 42 let y = frame.y; 43 for (let i = 0, len = list.length; i < len; i++) { 44 let it = list[i]; 45 if ((it.startNS || 0) + (it.dur || 0) > startNS && (it.startNS || 0) < endNS) { 46 if (!list[i].frame) { 47 list[i].frame = {}; 48 list[i].frame.y = y; 49 } 50 list[i].frame.height = it.height; 51 HiPerfThreadStruct.setFrame(list[i], pns, startNS, endNS, frame) 52 if (groupBy10MS) { 53 if (i > 0 && ((list[i - 1].frame?.x || 0) == (list[i].frame?.x || 0) 54 && ((list[i - 1].frame?.width || 0) == (list[i].frame?.width || 0)) 55 && ((list[i - 1].frame?.height || 0) == (list[i].frame?.height || 0)) 56 )) { 57 58 } else { 59 res.push(list[i]) 60 } 61 } else { 62 if (i > 0 && (Math.abs((list[i - 1].frame?.x || 0) - (list[i].frame?.x || 0)) < 4)) { 63 } else { 64 res.push(list[i]) 65 } 66 } 67 } 68 } 69 } 70} 71 72export class HiPerfThreadStruct extends BaseStruct { 73 static hoverStruct: HiPerfThreadStruct | undefined; 74 static selectStruct: HiPerfThreadStruct | undefined; 75 id: number | undefined; 76 sample_id: number | undefined; 77 timestamp: number | undefined; 78 thread_id: number | undefined; 79 event_count: number | undefined; 80 event_type_id: number | undefined; 81 cpu_id: number | undefined; 82 thread_state: string | undefined; 83 //------------------------------------------------------ 84 startNS: number | undefined; 85 endNS: number | undefined; 86 dur: number | undefined; 87 height: number | undefined; 88 cpu: number | undefined; 89 90 static draw(ctx: CanvasRenderingContext2D, path: Path2D, data: HiPerfThreadStruct, groupBy10MS: boolean) { 91 if (data.frame) { 92 if (groupBy10MS) { 93 let width = data.frame.width; 94 path.rect(data.frame.x, 40 - (data.height || 0), width, data.height || 0) 95 } else { 96 path.moveTo(data.frame.x + 7, 20); 97 HiPerfCpuStruct.drawRoundRectPath(path, data.frame.x - 7, 20 - 7, 14, 14, 3) 98 path.moveTo(data.frame.x, 27); 99 path.lineTo(data.frame.x, 33); 100 } 101 } 102 } 103 104 static setFrame(node: any, pns: number, startNS: number, endNS: number, frame: any) { 105 if ((node.startNS || 0) < startNS) { 106 node.frame.x = 0; 107 } else { 108 node.frame.x = Math.floor(((node.startNS || 0) - startNS) / pns); 109 } 110 if ((node.startNS || 0) + (node.dur || 0) > endNS) { 111 node.frame.width = frame.width - node.frame.x; 112 } else { 113 node.frame.width = Math.ceil(((node.startNS || 0) + (node.dur || 0) - startNS) / pns - node.frame.x); 114 } 115 if (node.frame.width < 1) { 116 node.frame.width = 1; 117 } 118 } 119 120 static groupBy10MS(array: Array<any>, intervalPerf: number): Array<any> { 121 let obj = array.map(it => { 122 it.timestamp_group = Math.trunc(it.startNS / 1_000_000_0) * 1_000_000_0; 123 return it; 124 }).reduce((pre, current) => { 125 (pre[current["timestamp_group"]] = pre[current["timestamp_group"]] || []).push(current); 126 return pre; 127 }, {}); 128 let arr: any[] = []; 129 for (let aKey in obj) { 130 let ns = parseInt(aKey); 131 let height: number = 0; 132 height = Math.floor(obj[aKey].length / (10 / intervalPerf) * 40); 133 arr.push({ 134 startNS: ns, 135 height: height, 136 dur: 1_000_000_0, 137 }) 138 } 139 return arr; 140 } 141} 142