1// Copyright (c) 2021 Huawei Device Co., Ltd. 2// Licensed under the Apache License, Version 2.0 (the "License"); 3// you may not use this file except in compliance with the License. 4// You may obtain a copy of the License at 5// 6// http://www.apache.org/licenses/LICENSE-2.0 7// 8// Unless required by applicable law or agreed to in writing, software 9// distributed under the License is distributed on an "AS IS" BASIS, 10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11// See the License for the specific language governing permissions and 12// limitations under the License. 13 14import { Args } from '../CommonArgs'; 15import { TraficEnum } from '../utils/QueryEnum'; 16 17export const chartHiperfCpuData10MSProtoSql = (args: Args): string => { 18 return `select 19 startNS as startNS, 20 max(event_count) as eventCount, 21 sample_count as sampleCount, 22 event_type_id as eventTypeId, 23 callchain_id as callchainId, 24 (startNS / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px 25 from (select s.callchain_id, 26 (s.timestamp_trace - ${args.recordStartNS}) / 10000000 * 10000000 startNS, 27 sum(event_count) event_count, 28 count(event_count) sample_count, 29 event_type_id 30 from perf_sample s 31 where s.thread_id != 0 ${args.cpu >= 0 ? 'and cpu_id =' + args.cpu : ''} ${ 32 args.drawType >= 0 ? 'and event_type_id =' + args.drawType : '' 33 } 34 group by startNS) 35 where startNS + 10000000 >= ${Math.floor(args.startNS)} 36 and startNS <= ${Math.floor(args.endNS)} 37 group by px;`; 38}; 39export const chartHiperfCpuDataProtoSql = (args: Args): string => { 40 return `select 41 (s.timestamp_trace - ${args.recordStartNS}) startNS, 42 event_count as eventCount, 43 1 as sampleCount, 44 event_type_id as eventTypeId, 45 s.callchain_id as callchainId, 46 (s.timestamp_trace - ${args.recordStartNS}) / (${Math.floor( 47 (args.endNS - args.startNS) / args.width 48 )}) AS px 49 from perf_sample s 50 where s.thread_id != 0 ${args.cpu >= 0 ? 'and cpu_id =' + args.cpu : ''} ${ 51 args.drawType >= 0 ? 'and event_type_id =' + args.drawType : '' 52 } 53 and startNS >= ${Math.floor(args.startNS)} 54 and startNS <= ${Math.floor(args.endNS)} 55 group by px; 56 `; 57}; 58 59export function hiperfCpuDataReceiver(data: unknown, proc: Function): void { 60 let sql: string; 61 // @ts-ignore 62 if (data.params.scale > 30_000_000) { 63 // @ts-ignore 64 sql = chartHiperfCpuData10MSProtoSql(data.params); 65 } else { 66 // @ts-ignore 67 sql = chartHiperfCpuDataProtoSql(data.params); 68 } 69 let res = proc(sql); 70 // @ts-ignore 71 arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer); 72} 73 74function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void { 75 // @ts-ignore 76 let maxCpuCount = data.params.maxCpuCount; 77 // @ts-ignore 78 let intervalPerf = data.params.intervalPerf; 79 // @ts-ignore 80 let usage = data.params.drawType === -2; 81 let perfCpu = new PerfCpu(data, transfer, res.length); 82 let maxEventCount = Math.max( 83 ...res.map((it) => { 84 // @ts-ignore 85 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData); 86 // @ts-ignore 87 return it.eventCount; 88 }) 89 ); 90 res.forEach((it, i) => { 91 // @ts-ignore 92 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData); 93 // @ts-ignore 94 perfCpu.startNS[i] = it.startNS || it.startNs; //startNS 95 // @ts-ignore 96 perfCpu.eventCount[i] = it.eventCount; //event_count 97 // @ts-ignore 98 perfCpu.sampleCount[i] = it.sampleCount; //sample_count 99 // @ts-ignore 100 perfCpu.eventTypeId[i] = it.eventTypeId; //event_type_id 101 // @ts-ignore 102 perfCpu.callChainId[i] = it.callchainId; //callchain_id 103 if (usage) { 104 if (maxCpuCount === -1) { 105 // @ts-ignore 106 perfCpu.height[i] = Math.floor((it.sampleCount / (10 / intervalPerf)) * 40); 107 } else { 108 // @ts-ignore 109 perfCpu.height[i] = Math.floor((it.sampleCount / (10 / intervalPerf) / maxCpuCount) * 40); 110 } 111 } else { 112 // @ts-ignore 113 perfCpu.height[i] = Math.floor((it.eventCount / maxEventCount) * 40); 114 } 115 }); 116 postPerfCpuMessage(data, transfer, perfCpu, res.length); 117} 118function postPerfCpuMessage(data: unknown, transfer: boolean, perfCpu: PerfCpu, len: number): void { 119 (self as unknown as Worker).postMessage( 120 { 121 transfer: transfer, 122 // @ts-ignore 123 id: data.id, 124 // @ts-ignore 125 action: data.action, 126 results: transfer 127 ? { 128 startNS: perfCpu.startNS.buffer, 129 eventCount: perfCpu.eventCount.buffer, 130 sampleCount: perfCpu.sampleCount.buffer, 131 eventTypeId: perfCpu.eventTypeId.buffer, 132 callChainId: perfCpu.callChainId.buffer, 133 height: perfCpu.height.buffer, 134 } 135 : {}, 136 len: len, 137 }, 138 transfer 139 ? [ 140 perfCpu.startNS.buffer, 141 perfCpu.eventCount.buffer, 142 perfCpu.sampleCount.buffer, 143 perfCpu.eventTypeId.buffer, 144 perfCpu.callChainId.buffer, 145 perfCpu.height.buffer, 146 ] 147 : [] 148 ); 149} 150class PerfCpu { 151 startNS: Float64Array; 152 eventCount: Int32Array; 153 sampleCount: Int32Array; 154 eventTypeId: Int32Array; 155 callChainId: Int32Array; 156 height: Int32Array; 157 constructor(data: unknown, transfer: boolean, len: number) { 158 // @ts-ignore 159 this.startNS = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.startNS); 160 // @ts-ignore 161 this.eventCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventCount); 162 // @ts-ignore 163 this.sampleCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.sampleCount); 164 // @ts-ignore 165 this.eventTypeId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventTypeId); 166 // @ts-ignore 167 this.callChainId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.callChainId); 168 // @ts-ignore 169 this.height = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.height); 170 } 171} 172