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 { TraficEnum } from './utils/QueryEnum'; 15import { clockList, hangList } from './utils/AllMemoryCache'; 16import { Args } from './CommonArgs'; 17 18export const chartHangDataSql = (args: Args): string => ` 19SELECT 20 c.id as id, 21 c.ts - r.start_ts as startNS, 22 c.dur as dur, 23 t.tid as tid, 24 t.name as tname, 25 p.pid as pid, 26 p.name as pname 27FROM 28 callstack c, trace_range r 29LEFT JOIN thread t ON 30 t.itid = c.callid 31LEFT JOIN process p ON 32 p.ipid = t.ipid 33WHERE 34 c.dur >= ${args.minDur} 35 AND c.name LIKE 'H:Et:%' 36 AND t.is_main_thread = 1 37 AND p.pid = ${args.pid} 38`.trim(); 39 40export interface HangSQLStruct { 41 id: number; 42 startNS: number; 43 dur: number; 44 tid: number; 45 pid: number; 46} 47 48export function hangDataReceiver(data: unknown, proc: Function): void { 49 // @ts-ignore 50 if (data.params.trafic === TraficEnum.Memory) { 51 let res: HangSQLStruct[]; 52 let list: HangSQLStruct[]; 53 54 // @ts-ignore 55 if (!hangList.has(data.params.pid)) { 56 // @ts-ignore 57 let sql = chartHangDataSql(data.params); 58 list = proc(sql); 59 // @ts-ignore 60 hangList.set(data.params.pid, list); 61 } 62 else { 63 // @ts-ignore 64 list = hangList.get(data.params.pid) || []; 65 } 66 67 // @ts-ignore 68 if (data.params.queryAll) { 69 res = list.filter( 70 //@ts-ignore 71 (it) => it.startNS + it.dur >= data.params.selectStartNS && it.startNS <= data.params.selectEndNS 72 ); 73 } 74 else { 75 res = list; 76 } 77 78 arrayBufferHandler(data, res, true); 79 } 80 else { 81 // @ts-ignore 82 let sql = chartHangDataSql(data.params); 83 let res: HangSQLStruct[] = proc(sql); 84 // @ts-ignore 85 arrayBufferHandler(data, res, data.params.trafic !== TraficEnum.SharedArrayBuffer); 86 } 87} 88 89function arrayBufferHandler(data: unknown, res: HangSQLStruct[], transfer: boolean = true): void { 90 // @ts-ignore 91 let id = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.id); 92 // @ts-ignore 93 let startNS = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.startNS); 94 // @ts-ignore 95 let dur = new Float64Array(transfer ? res.length : data.params.sharedArrayBuffers.dur); 96 // @ts-ignore 97 let tid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.tid); 98 // @ts-ignore 99 let pid = new Int32Array(transfer ? res.length : data.params.sharedArrayBuffers.pid); 100 res.forEach((it, i) => { 101 id[i] = it.id; 102 startNS[i] = it.startNS; 103 dur[i] = it.dur; 104 tid[i] = it.tid; 105 pid[i] = it.pid; 106 }); 107 108 let arg1 = { 109 // @ts-ignore 110 id: data.id, 111 // @ts-ignore 112 action: data.action, 113 results: { 114 id: id.buffer, 115 startNS: startNS.buffer, 116 dur: dur.buffer, 117 tid: tid.buffer, 118 pid: pid.buffer, 119 }, 120 len: res.length, 121 transfer: transfer, 122 }; 123 let arg2 = [ 124 id.buffer, 125 startNS.buffer, 126 dur.buffer, 127 tid.buffer, 128 pid.buffer, 129 ]; 130 (self as unknown as Worker).postMessage( 131 arg1, arg2, 132 ); 133}