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 chartHiperfProcessData10MSProtoSql = (args: Args): string => { 18 return `select startNS as startNS, 19 max(event_count) eventCount, 20 sample_count as sampleCount, 21 event_type_id as eventTypeId, 22 callchain_id as callchainId, 23 (startNS / (${Math.floor((args.endNS - args.startNS) / args.width)})) AS px 24 from (SELECT sp.callchain_id, 25 (sp.timestamp_trace - ${args.recordStartNS}) / 10000000 * 10000000 startNS, 26 sum(event_count) event_count, 27 count(event_count) sample_count, 28 event_type_id 29 from perf_sample sp 30 where sp.thread_id in (select thread_id 31 from perf_thread 32 where perf_thread.process_id = ${args.pid}) 33 and sp.thread_id != 0 ${args.drawType >= 0 ? 'and event_type_id =' + args.drawType : ''} 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 chartHiperfProcessDataProtoSql = (args: Args): string => { 40 return `SELECT (sp.timestamp_trace - ${args.recordStartNS}) startNS, 41 event_count as eventCount, 42 1 as sampleCount, 43 event_type_id as eventTypeId, 44 sp.callchain_id as callchainId, 45 (sp.timestamp_trace - ${args.recordStartNS}) / (${Math.floor( 46 (args.endNS - args.startNS) / args.width 47 )}) AS px 48 from perf_sample sp 49 where sp.thread_id in (select thread_id 50 from perf_thread 51 where perf_thread.process_id = ${args.pid}) 52 and sp.thread_id != 0 ${args.drawType >= 0 ? 'and event_type_id =' + args.drawType : ''} 53 and startNS >= ${Math.floor(args.startNS)} 54 and startNS <= ${Math.floor(args.endNS)} 55 group by px;`; 56}; 57 58export function hiperfProcessDataReceiver(data: unknown, proc: Function): void { 59 let sql: string; 60 // @ts-ignore 61 if (data.params.scale > 30_000_000) { 62 // @ts-ignore 63 sql = chartHiperfProcessData10MSProtoSql(data.params); 64 } else { 65 // @ts-ignore 66 sql = chartHiperfProcessDataProtoSql(data.params); 67 } 68 let res = proc(sql); 69 // @ts-ignore 70 arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer); 71} 72 73function arrayBufferHandler(data: unknown, res: unknown[], transfer: boolean): void { 74 // @ts-ignore 75 let maxCpuCount = data.params.maxCpuCount; 76 // @ts-ignore 77 let intervalPerf = data.params.intervalPerf; 78 // @ts-ignore 79 let usage = data.params.drawType === -2; 80 let perfProcess = new PerfProcess(data, transfer, res.length); 81 let maxEventCount = Math.max( 82 ...res.map((it) => { 83 // @ts-ignore 84 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData); 85 // @ts-ignore 86 return it.eventCount; 87 }) 88 ); 89 res.forEach((it, i) => { 90 // @ts-ignore 91 data.params.trafic === TraficEnum.ProtoBuffer && (it = it.hiperfData); 92 // @ts-ignore 93 perfProcess.startNS[i] = it.startNS || it.startNs; 94 // @ts-ignore 95 perfProcess.eventCount[i] = it.eventCount; 96 // @ts-ignore 97 perfProcess.sampleCount[i] = it.sampleCount; 98 // @ts-ignore 99 perfProcess.eventTypeId[i] = it.eventTypeId; 100 // @ts-ignore 101 perfProcess.callChainId[i] = it.callchainId; 102 if (usage) { 103 if (maxCpuCount === -1) { 104 // @ts-ignore 105 perfProcess.height[i] = Math.floor((it.sampleCount / (10 / intervalPerf)) * 40); 106 } else { 107 // @ts-ignore 108 perfProcess.height[i] = Math.floor((it.sampleCount / (10 / intervalPerf) / maxCpuCount) * 40); 109 } 110 } else { 111 // @ts-ignore 112 perfProcess.height[i] = Math.floor((it.eventCount / maxEventCount) * 40); 113 } 114 }); 115 postPerfProcessMessage(data, transfer, perfProcess, res.length); 116} 117function postPerfProcessMessage(data: unknown, transfer: boolean, perfProcess: PerfProcess, len: number): void { 118 (self as unknown as Worker).postMessage( 119 { 120 // @ts-ignore 121 id: data.id, 122 // @ts-ignore 123 action: data.action, 124 results: transfer 125 ? { 126 startNS: perfProcess.startNS.buffer, 127 eventCount: perfProcess.eventCount.buffer, 128 sampleCount: perfProcess.sampleCount.buffer, 129 eventTypeId: perfProcess.eventTypeId.buffer, 130 callChainId: perfProcess.callChainId.buffer, 131 height: perfProcess.height.buffer, 132 } 133 : {}, 134 len: len, 135 transfer: transfer, 136 }, 137 transfer 138 ? [ 139 perfProcess.startNS.buffer, 140 perfProcess.eventCount.buffer, 141 perfProcess.sampleCount.buffer, 142 perfProcess.eventTypeId.buffer, 143 perfProcess.callChainId.buffer, 144 perfProcess.height.buffer, 145 ] 146 : [] 147 ); 148} 149class PerfProcess { 150 startNS: Float64Array; 151 eventCount: Int32Array; 152 sampleCount: Int32Array; 153 eventTypeId: Int32Array; 154 callChainId: Int32Array; 155 height: Int32Array; 156 constructor(data: unknown, transfer: boolean, len: number) { 157 // @ts-ignore 158 this.startNS = new Float64Array(transfer ? len : data.params.sharedArrayBuffers.startNS); 159 // @ts-ignore 160 this.eventCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventCount); 161 // @ts-ignore 162 this.sampleCount = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.sampleCount); 163 // @ts-ignore 164 this.eventTypeId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.eventTypeId); 165 // @ts-ignore 166 this.callChainId = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.callChainId); 167 // @ts-ignore 168 this.height = new Int32Array(transfer ? len : data.params.sharedArrayBuffers.height); 169 } 170} 171