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 */ 15import { PerfCmdLine, PerfFile, PerfSample, PerfStack, PerfThread } from '../../bean/PerfProfile'; 16import { query } from '../SqlLite'; 17import { HiSysEventStruct } from '../ui-worker/ProcedureWorkerHiSysEvent'; 18import { TaskTabStruct } from '../../component/trace/sheet/task/TabPaneTaskFrames'; 19import { GpuCountBean, SearchGpuFuncBean } from '../../bean/GpufreqBean'; 20 21export const queryPerfFiles = (): Promise<Array<PerfFile>> => 22 query('queryPerfFiles', `select file_id as fileId,symbol,path from perf_files`, {}); 23 24export const queryPerfCallChainName = (): //@ts-ignore 25Promise<Array<unknown>> => query('queryPerfCallChainName', `select callchain_id,depth,name from perf_callchain`, {}); 26 27export const queryPerfProcess = (): Promise<Array<PerfThread>> => 28 query( 29 'queryPerfThread', 30 `select process_id as pid,thread_name as processName from perf_thread where process_id = thread_id`, 31 {} 32 ); 33 34export const queryPerfThread = (): Promise<Array<PerfThread>> => 35 query( 36 'queryPerfThread', 37 `select a.thread_id as tid, 38 a.thread_name as threadName, 39 a.process_id as pid, 40 b.thread_name as processName 41from perf_thread a 42 left join (select distinct process_id, thread_name from perf_thread where process_id = thread_id) b 43 on a.process_id = b.process_id 44order by pid;`, 45 {} 46 ); 47export const queryPerfSampleListByTimeRange = ( 48 leftNs: number, 49 rightNs: number, 50 cpus: Array<number>, 51 processes: Array<number>, 52 threads: Array<number>, 53 eventTypeId?: number 54): Promise<Array<PerfSample>> => { 55 let sql = ` 56select A.callchain_id as sampleId, 57 A.thread_id as tid, 58 C.thread_name as threadName, 59 A.thread_state as state, 60 C.process_id as pid, 61 (timestamp_trace - R.start_ts) as time, 62 cpu_id as core 63from perf_sample A,trace_range R 64left join perf_thread C on A.thread_id = C.thread_id 65where time >= $leftNs and time <= $rightNs and A.thread_id != 0 66 `; 67 if (eventTypeId !== undefined) { 68 sql = `${sql} and event_type_id = ${eventTypeId}`; 69 } 70 if (cpus.length !== 0 || processes.length !== 0 || threads.length !== 0) { 71 let arg1 = cpus.length > 0 ? `or core in (${cpus.join(',')}) ` : ''; 72 let arg2 = processes.length > 0 ? `or pid in (${processes.join(',')}) ` : ''; 73 let arg3 = threads.length > 0 ? `or tid in (${threads.join(',')})` : ''; 74 let arg = `${arg1}${arg2}${arg3}`.substring(3); 75 sql = `${sql} and (${arg})`; 76 } 77 return query('queryPerfSampleListByTimeRange', sql, { 78 $leftNs: leftNs, 79 $rightNs: rightNs, 80 }); 81}; 82 83export const queryPerfSampleIdsByTimeRange = ( 84 leftNs: number, 85 rightNs: number, 86 cpus: Array<number>, 87 processes: Array<number>, 88 threads: Array<number> 89): Promise<Array<PerfSample>> => { 90 let sql = ` 91select A.callchain_id as sampleId 92from perf_sample A,trace_range R 93left join perf_thread C on A.thread_id = C.thread_id 94where (timestamp_trace - R.start_ts) >= $leftNs and (timestamp_trace - R.start_ts) <= $rightNs and A.thread_id != 0 95 `; 96 if (cpus.length !== 0 || processes.length !== 0 || threads.length !== 0) { 97 let arg1 = cpus.length > 0 ? `or A.cpu_id in (${cpus.join(',')}) ` : ''; 98 let arg2 = processes.length > 0 ? `or C.process_id in (${processes.join(',')}) ` : ''; 99 let arg3 = threads.length > 0 ? `or A.thread_id in (${threads.join(',')})` : ''; 100 let arg = `${arg1}${arg2}${arg3}`.substring(3); 101 sql = `${sql} and (${arg})`; 102 } 103 return query('queryPerfSampleIdsByTimeRange', sql, { 104 $leftNs: leftNs, 105 $rightNs: rightNs, 106 }); 107}; 108 109export const queryPerfSampleCallChain = (sampleId: number): Promise<Array<PerfStack>> => 110 query( 111 'queryPerfSampleCallChain', 112 ` 113 select 114 callchain_id as callChainId, 115 callchain_id as sampleId, 116 file_id as fileId, 117 symbol_id as symbolId, 118 vaddr_in_file as vaddrInFile, 119 name as symbol 120from perf_callchain where callchain_id = $sampleId; 121 `, 122 { $sampleId: sampleId } 123 ); 124 125export const queryPerfCmdline = (): Promise<Array<PerfCmdLine>> => 126 query( 127 'queryPerfCmdline', 128 ` 129 select report_value from perf_report where report_type = 'cmdline' 130 `, 131 {} 132 ); 133export const queryPerfEventType = (): Promise<Array<{ id: number; report: string }>> => 134 query( 135 'queryPerfEventType', 136 ` 137 select id,report_value as report from perf_report where id in ( 138select distinct event_type_id from perf_sample); 139 `, 140 {} 141 ); 142/** 143 * HiPerf 144 */ 145export const queryHiPerfEventList = (): //@ts-ignore 146Promise<Array<unknown>> => 147 query('queryHiPerfEventList', `select id,report_value from perf_report where report_type='config_name'`, {}); 148export const queryHiPerfEventListData = ( 149 eventTypeId: number 150): //@ts-ignore 151Promise<Array<unknown>> => 152 query( 153 'queryHiPerfEventListData', 154 ` 155 select s.callchain_id, 156 (s.timestamp_trace-t.start_ts) startNS 157 from perf_sample s,trace_range t 158 where 159 event_type_id=${eventTypeId} 160 and s.thread_id != 0 161 and s.callchain_id != -1; 162`, 163 { $eventTypeId: eventTypeId } 164 ); 165export const queryHiPerfEventData = ( 166 eventTypeId: number, 167 cpu: number 168): //@ts-ignore 169Promise<Array<unknown>> => 170 query( 171 'queryHiPerfEventList', 172 ` 173 select s.callchain_id, 174 (s.timestamp_trace-t.start_ts) startNS 175 from perf_sample s,trace_range t 176 where 177 event_type_id=${eventTypeId} 178 and cpu_id=${cpu} 179 and s.thread_id != 0 180 and s.callchain_id != -1; 181`, 182 { $eventTypeId: eventTypeId, $cpu: cpu } 183 ); 184export const queryHiPerfCpuData = ( 185 cpu: number 186): //@ts-ignore 187Promise<Array<unknown>> => 188 query( 189 'queryHiPerfCpuData', 190 ` 191 select s.callchain_id, 192 (s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id 193 from perf_sample s,trace_range t 194 where 195 cpu_id=${cpu} 196 and s.thread_id != 0;`, 197 { $cpu: cpu } 198 ); 199export const queryHiPerfCpuMergeData = (): //@ts-ignore 200Promise<Array<unknown>> => 201 query( 202 'queryHiPerfCpuData', 203 `select s.callchain_id,(s.timestamp_trace-t.start_ts) startNS, event_count, event_type_id from perf_sample s,trace_range t 204where s.thread_id != 0;`, 205 {} 206 ); 207export const queryHiPerfCpuMergeData2 = (): //@ts-ignore 208Promise<Array<unknown>> => 209 query( 210 'queryHiPerfCpuData2', 211 `select distinct cpu_id from perf_sample where thread_id != 0 order by cpu_id desc;`, 212 {} 213 ); 214 215export const queryHiPerfProcessData = ( 216 pid: number 217): //@ts-ignore 218Promise<Array<unknown>> => 219 query( 220 'queryHiPerfProcessData', 221 ` 222SELECT sp.callchain_id, 223 th.thread_name, 224 th.thread_id tid, 225 th.process_id pid, 226 sp.timestamp_trace - tr.start_ts startNS, 227 event_count, 228 event_type_id 229from perf_sample sp, 230 trace_range tr 231 left join perf_thread th on th.thread_id = sp.thread_id 232where pid = ${pid} and sp.thread_id != 0 `, 233 { $pid: pid } 234 ); 235 236export const queryHiPerfThreadData = ( 237 tid: number 238): //@ts-ignore 239Promise<Array<unknown>> => 240 query( 241 'queryHiPerfThreadData', 242 ` 243SELECT sp.callchain_id, 244 th.thread_name, 245 th.thread_id tid, 246 th.process_id pid, 247 sp.timestamp_trace - tr.start_ts startNS, 248 event_count, 249 event_type_id 250from perf_sample sp, 251 trace_range tr 252 left join perf_thread th on th.thread_id = sp.thread_id 253where tid = ${tid} and sp.thread_id != 0 ;`, 254 { $tid: tid } 255 ); 256 257export const getGpufreqDataCut = ( 258 tIds: string, 259 funcName: string, 260 leftNS: number, 261 rightNS: number, 262 single: boolean, 263 loop: boolean 264): Promise<Array<SearchGpuFuncBean>> => { 265 let queryCondition: string = ''; 266 if (single) { 267 queryCondition += `select s.funName,s.startTime,s.dur,s.startTime+s.dur as endTime,s.tid,s.threadName,s.pid from state s 268 where endTime between ${leftNS} and ${rightNS}`; 269 } 270 if (loop) { 271 queryCondition += `select s.funName,s.startTime,s.loopEndTime-s.startTime as dur,s.loopEndTime as endTime,s.tid,s.threadName,s.pid from state s 272 where endTime between ${leftNS} and ${rightNS} `; 273 } 274 return query( 275 'getGpufreqDataCut', 276 ` 277 with state as 278 (select 279 * 280 from 281 (select 282 c.name as funName, 283 c.ts - r.start_ts as startTime, 284 c.dur, 285 lead(c.ts - r.start_ts, 1, null) over( order by c.ts - r.start_ts) loopEndTime, 286 t.tid, 287 t.name as threadName, 288 p.pid 289 from 290 callstack c 291 left join 292 thread t on c.callid = t.id 293 left join 294 process p on t.ipid = p.id 295 left join 296 trace_range r 297 where 298 c.name like '${funcName}%' 299 and 300 tid = '${tIds}' 301 and 302 startTime between ${leftNS} and ${rightNS})) 303 ${queryCondition} 304 `, 305 { $search: funcName } 306 ); 307}; 308export const getGpufreqData = (leftNS: number, rightNS: number, earliest: boolean): Promise<Array<GpuCountBean>> => { 309 let queryCondition: string = ''; 310 if (!earliest) { 311 queryCondition += ` where not ((s.ts - r.start_ts + ifnull(s.dur,0) < ${leftNS}) or (s.ts - r.start_ts > ${rightNS}))`; 312 } 313 return query( 314 'getGpufreqData', 315 ` 316 with state as 317 (select 318 name, 319 filter_id, 320 ts, 321 endts, 322 endts-ts as dur, 323 value as val 324 from 325 (select 326 measure.filter_id, 327 clock_event_filter.name, 328 measure.ts, 329 lead(ts, 1, null) over( order by measure.ts) endts, 330 measure.value 331 from 332 clock_event_filter, 333 trace_range 334 left join 335 measure 336 where 337 clock_event_filter.name = 'gpufreq' 338 and 339 clock_event_filter.type = 'clock_set_rate' 340 and 341 clock_event_filter.id = measure.filter_id 342 order by measure.ts) 343 where 344 endts is not null 345 ) 346 select 347 s.name as thread, 348 s.val/1000000 as freq, 349 s.val*s.dur as value, 350 s.val, 351 s.ts-r.start_ts as startNS, 352 s.dur, 353 s.endts- r.start_ts as endTime 354 from 355 state s, 356 trace_range r 357 ${queryCondition} 358 order by ts 359 `, 360 { $leftNS: leftNS, $rightNS: rightNS } 361 ); 362}; 363 364export const queryHiSysEventTabData = (leftNs: number, rightNs: number): Promise<Array<HiSysEventStruct>> => 365 query( 366 'queryHiSysEventTabData', 367 `SELECT S.id, 368 D2.data AS domain, 369 D.data AS eventName, 370 type AS eventType, 371 time_zone AS tz, 372 pid, 373 tid, 374 uid, 375 info, 376 level, 377 seq, 378 contents, 379 S.ts - TR.start_ts AS startTs, 380 1 AS dur, 381 CASE 382 WHEN level = 'MINOR' THEN 383 0 384 WHEN level = 'CRITICAL' THEN 385 1 386 END AS depth 387 FROM hisys_all_event AS S ,trace_range AS TR 388 LEFT JOIN data_dict AS D on S.event_name_id = D.id 389 LEFT JOIN data_dict AS D2 on S.domain_id = D2.id 390 WHERE S.id is not null 391 and startTs >= ${Math.floor(leftNs)} 392 and startTs <= ${Math.floor(rightNs)} 393 ORDER BY S.ts` 394 ); 395export const queryHiSysEventData = (): Promise<Array<HiSysEventStruct>> => 396 query( 397 'queryHiSysEventData', 398 `SELECT l.ts - tr.start_ts as startNs FROM hisys_all_event AS l, trace_range tr WHERE startNs > 0 LIMIT 1` 399 ); 400export const queryHiPerfProcessCount = ( 401 leftNs: number, 402 rightNs: number, 403 cpus: Array<number>, 404 threads: Array<number>, 405 processes: Array<number> 406): //@ts-ignore 407Promise<Array<unknown>> => { 408 let str = ''; 409 if (processes.length > 0) { 410 str = ` and C.process_id in (${processes.join(',')})`; 411 } 412 if (threads.length > 0) { 413 str = ` and A.thread_id in (${threads.join(',')}) `; 414 } 415 if (processes.length > 0 && threads.length > 0) { 416 str = ` and (C.process_id in (${processes.join(',')}) or A.thread_id in (${threads.join(',')}))`; 417 } 418 if (cpus.length > 0) { 419 str = ` and A.cpu_id in (${cpus.join(',')})`; 420 } 421 if (cpus.length > 0 && processes.length > 0) { 422 str = ` and (C.process_id in (${processes.join(',')}) or A.cpu_id in (${cpus.join(',')}))`; 423 } 424 return query( 425 'queryHiPerfProcessCount', 426 ` 427 select C.process_id as pid, 428 (A.timestamp_trace - R.start_ts) as time, 429 C.thread_name as threadName, 430 A.thread_id as tid, 431 A.id, 432 A.callchain_id 433 from perf_sample A,trace_range R 434 left join perf_thread C on A.thread_id = C.thread_id and A.thread_id != 0 435 where time >= $leftNs and time <= $rightNs and A.callchain_id > 0 436 ${str} 437 `, 438 { $leftNs: leftNs, $rightNs: rightNs } 439 ); 440}; 441export const queryTransferList = (): Promise<Array<{ id: number; cmdStr: string }>> => 442 query('queryTransferList', `select id, report_value as cmdStr from perf_report where report_type = 'config_name'`); 443export const queryConcurrencyTask = ( 444 itid: number, 445 selectStartTime: number, 446 selectEndTime: number 447): Promise<TaskTabStruct[]> => 448 query<TaskTabStruct>( 449 'queryConcurrencyTask', 450 `SELECT thread.tid, 451 thread.ipid, 452 callstack.name AS funName, 453 callstack.ts AS startTs, 454 (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end) as dur, 455 callstack.id, 456 task_pool.priority, 457 task_pool.allocation_task_row AS allocationTaskRow, 458 task_pool.execute_task_row AS executeTaskRow, 459 task_pool.return_task_row AS returnTaskRow, 460 task_pool.task_id AS executeId 461 FROM thread 462 LEFT JOIN callstack ON thread.id = callstack.callid 463 LEFT JOIN task_pool ON callstack.id = task_pool.execute_task_row 464 WHERE ipid in (SELECT thread.ipid 465 FROM thread 466 WHERE thread.itid = $itid) 467 AND thread.name LIKE '%TaskWork%' 468 AND callstack.name LIKE 'H:Task Perform:%' 469 AND -- 左包含 470 (($selectStartTime <= callstack.ts AND $selectEndTime > callstack.ts) 471 OR -- 右包含 472 ($selectStartTime < callstack.ts + callstack.dur AND $selectEndTime >= callstack.ts + callstack.dur) 473 OR -- 包含 474 ($selectStartTime >= callstack.ts AND $selectEndTime <= callstack.ts + 475 (case when callstack.dur = -1 then (SELECT end_ts FROM trace_range) else callstack.dur end)) 476 OR -- 被包含 477 ($selectStartTime <= callstack.ts AND $selectEndTime >= callstack.ts + callstack.dur)) 478 ORDER BY callstack.ts;`, 479 { $itid: itid, $selectStartTime: selectStartTime, $selectEndTime: selectEndTime } 480 ); 481