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 { KeyPathStruct } from "../../bean/KeyPathStruct"; 16import { CpuStruct } from "../ui-worker/cpu/ProcedureWorkerCPU"; 17import { query } from "../SqlLite"; 18import { CpuUsage, Freq } from "../../bean/CpuUsage"; 19import { Counter } from "../../bean/BoxSelection"; 20import { CpuFreqStruct } from "../ui-worker/ProcedureWorkerFreq"; 21import { CpuFreqLimitsStruct } from "../ui-worker/cpu/ProcedureWorkerCpuFreqLimits"; 22import { CpuFreqRowLimit } from "../../component/chart/SpFreqChart"; 23 24export const queryCpuKeyPathData = (threads: Array<KeyPathStruct>): Promise<Array<CpuStruct>> => { 25 const sqlArray: Array<string> = []; 26 sqlArray.push(` 1 = 0`); 27 for (const thread of threads) { 28 sqlArray.push(` or (tid = ${thread.tid} and ts in (${thread.tsArray}))`); 29 } 30 let sql = sqlArray.join(' '); 31 return query( 32 'queryCpuKeyPathData', 33 `SELECT B.pid as processId, 34 B.cpu, 35 B.tid, 36 B.itid as id, 37 B.dur AS dur, 38 B.ts - T.start_ts AS startTime, 39 B.arg_setid as argSetID, 40 1 as isKeyPath 41 from thread_state AS B 42 left join trace_range as T 43 where ${sql}` 44 ); 45}; 46export const getCpuUtilizationRate = ( 47 startNS: number, 48 endNS: number 49): Promise< 50 Array<{ 51 cpu: number; 52 ro: number; 53 rate: number; 54 }> 55> => 56 query( 57 'getCpuUtilizationRate', 58 ` 59 with cpu as ( 60 select 61 cpu, 62 ts, 63 dur, 64 (case when ro < 99 then ro else 99 end) as ro , 65 (case when ro < 99 then stime+ro*cell else stime + 99 * cell end) as st, 66 (case when ro < 99 then stime + (ro+1)*cell else etime end) as et 67 from ( 68 select 69 cpu, 70 ts, 71 A.dur, 72 ((ts+A.dur)-D.start_ts)/((D.end_ts-D.start_ts)/100) as ro, 73 D.start_ts as stime, 74 D.end_ts etime, 75 (D.end_ts-D.start_ts)/100 as cell 76 from 77 sched_slice A 78 left join 79 trace_range D 80 left join 81 thread B on A.itid = B.id 82 where 83 tid != 0 84 and (A.ts) 85 between D.start_ts and D.end_ts)) 86 select cpu,ro, 87 sum(case 88 when ts <= st and ts + dur <= et then (ts + dur - st) 89 when ts <= st and ts + dur > et then et-st 90 when ts > st and ts + dur <= et then dur 91 when ts > st and ts + dur > et then et - ts end)/cast(et-st as float) as rate 92 from cpu 93 group by cpu,ro;`, 94 {} 95 ); 96export const getTabCpuUsage = (cpus: Array<number>, leftNs: number, rightNs: number): Promise<Array<CpuUsage>> => 97 query<CpuUsage>( 98 'getTabCpuUsage', 99 ` 100 select 101 cpu, 102 sum(case 103 when (A.ts - B.start_ts) < $leftNS 104 then (A.ts - B.start_ts + A.dur - $leftNS) 105 when (A.ts - B.start_ts) >= $leftNS 106 and (A.ts - B.start_ts + A.dur) <= $rightNS 107 then A.dur 108 when (A.ts - B.start_ts + A.dur) > $rightNS 109 then ($rightNS - (A.ts - B.start_ts)) end) / cast($rightNS - $leftNS as float) as usage 110 from 111 thread_state A, 112 trace_range B 113 where 114 (A.ts - B.start_ts) > 0 and A.dur > 0 115 and 116 cpu in (${cpus.join(',')}) 117 and 118 (A.ts - B.start_ts + A.dur) > $leftNS 119 and 120 (A.ts - B.start_ts) < $rightNS 121 group by 122 cpu`, 123 { $leftNS: leftNs, $rightNS: rightNs } 124 ); 125 126export const getTabCpuFreq = (cpus: Array<number>, leftNs: number, rightNs: number): Promise<Array<Freq>> => 127 query<Freq>( 128 'getTabCpuFreq', 129 ` 130 select 131 cpu, 132 value, 133 (ts - tr.start_ts) as startNs 134 from 135 measure m, 136 trace_range tr 137 inner join 138 cpu_measure_filter t 139 on 140 m.filter_id = t.id 141 where 142 (name = 'cpufreq' or name='cpu_frequency') 143 and 144 cpu in (${cpus.join(',')}) 145 and 146 startNs > 0 147 and 148 startNs < $rightNS 149 --order by startNs 150 `, 151 { $leftNS: leftNs, $rightNS: rightNs } 152 ); 153 154 155export const getTabCounters = (processFilterIds: Array<number>, virtualFilterIds: Array<number>, startTime: number) => { 156 let processSql = `select 157 t1.filter_id as trackId, 158 t2.name, 159 value, 160 t1.ts - t3.start_ts as startTime 161 from 162 process_measure t1 163 left join 164 process_measure_filter t2 165 on 166 t1.filter_id = t2.id 167 left join 168 trace_range t3 169 where 170 filter_id in (${processFilterIds.join(',')}) 171 and 172 startTime <= ${startTime}`; 173 let virtualSql = `select 174 t1.filter_id as trackId, 175 t2.name, 176 value, 177 t1.ts - t3.start_ts as startTime 178 from 179 sys_mem_measure t1 180 left join 181 sys_event_filter t2 182 on 183 t1.filter_id = t2.id 184 left join 185 trace_range t3 186 where 187 filter_id in (${virtualFilterIds.join(',')}) 188 and 189 startTime <= ${startTime}`; 190 let sql = ''; 191 if (processFilterIds.length > 0 && virtualFilterIds.length > 0) { 192 sql = `${processSql} union ${virtualSql}`; 193 } else { 194 if (processFilterIds.length > 0) { 195 sql = processSql; 196 } else { 197 sql = virtualSql; 198 } 199 } 200 return query<Counter>('getTabCounters', sql, {}); 201}; 202export const getTabCpuByProcess = (cpus: Array<number>, leftNS: number, rightNS: number) => 203 query<any>( 204 'getTabCpuByProcess', 205 ` 206 select 207 B.pid as pid, 208 sum(B.dur) as wallDuration, 209 avg(B.dur) as avgDuration, 210 count(B.tid) as occurrences 211 from 212 thread_state AS B 213 left join 214 trace_range AS TR 215 where 216 B.cpu in (${cpus.join(',')}) 217 and 218 not ((B.ts - TR.start_ts + B.dur < $leftNS) or (B.ts - TR.start_ts > $rightNS )) 219 group by 220 B.pid 221 order by 222 wallDuration desc;`, 223 { $rightNS: rightNS, $leftNS: leftNS } 224 ); 225export const getTabCpuByThread = (cpus: Array<number>, leftNS: number, rightNS: number) => 226 query<any>( 227 'getTabCpuByThread', 228 ` 229 select 230 TS.pid as pid, 231 TS.tid as tid, 232 TS.cpu, 233 sum( min(${rightNS},(TS.ts - TR.start_ts + TS.dur)) - max(${leftNS},TS.ts - TR.start_ts)) wallDuration, 234 count(TS.tid) as occurrences 235 from 236 thread_state AS TS 237 left join 238 trace_range AS TR 239 where 240 TS.cpu in (${cpus.join(',')}) 241 and 242 not ((TS.ts - TR.start_ts + TS.dur < $leftNS) or (TS.ts - TR.start_ts > $rightNS)) 243 group by 244 TS.cpu, 245 TS.pid, 246 TS.tid 247 order by 248 wallDuration desc;`, 249 { $rightNS: rightNS, $leftNS: leftNS } 250 ); 251export const queryCpuData = (cpu: number, startNS: number, endNS: number): Promise<Array<CpuStruct>> => 252 query( 253 'queryCpuData', 254 ` 255 SELECT 256 B.pid as processId, 257 B.cpu, 258 B.tid, 259 B.itid as id, 260 B.dur, 261 B.ts - TR.start_ts AS startTime, 262 B.arg_setid as argSetID 263from thread_state AS B 264 left join trace_range AS TR 265where B.itid is not null 266 and 267 B.cpu = $cpu 268 and 269 startTime between $startNS and $endNS;`, 270 { 271 $cpu: cpu, 272 $startNS: startNS, 273 $endNS: endNS, 274 } 275 ); 276 277export const queryCpuFreq = (): Promise<Array<{ cpu: number; filterId: number }>> => 278 query( 279 'queryCpuFreq', 280 ` 281 select 282 cpu,id as filterId 283 from 284 cpu_measure_filter 285 where 286 (name='cpufreq' or name='cpu_frequency') 287 order by cpu; 288 ` 289 ); 290 291export const queryCpuFreqData = (cpu: number): Promise<Array<CpuFreqStruct>> => 292 query<CpuFreqStruct>( 293 'queryCpuFreqData', 294 ` 295 select 296 cpu, 297 value, 298 ifnull(dur,tb.end_ts - c.ts) dur, 299 ts-tb.start_ts as startNS 300 from 301 measure c, 302 trace_range tb 303 inner join 304 cpu_measure_filter t 305 on 306 c.filter_id = t.id 307 where 308 (name = 'cpufreq' or name='cpu_frequency') 309 and 310 cpu= $cpu 311 --order by ts; 312 `, 313 { $cpu: cpu } 314 ); 315 316export const queryCpuMax = (): Promise<Array<any>> => 317 query( 318 'queryCpuMax', 319 ` 320 select 321 cpu 322 from 323 sched_slice 324 order by 325 cpu 326 desc limit 1;` 327 ); 328 329export const queryCpuDataCount = () => 330 query('queryCpuDataCount', 'select count(1) as count,cpu from thread_state where cpu not null group by cpu'); 331 332export const queryCpuCount = (): Promise<Array<any>> => 333 query( 334 'queryCpuCount', 335 ` 336 select max(cpuCount) cpuCount from 337(select ifnull((max(cpu) + 1),0) cpuCount from cpu_measure_filter where name in ('cpu_frequency','cpu_idle') 338 union all 339 select ifnull((max(callid)+1),0) cpuCount from irq 340) A;` 341 ); 342 343export const queryCpuSchedSlice = (): Promise<Array<any>> => 344 query( 345 'queryCpuSchedSlice', 346 ` 347 select (ts - start_ts) as ts, 348 itid, 349 end_state as endState, 350 priority 351 from sched_slice,trace_range;` 352 ); 353 354export const queryCpuStateFilter = (): Promise<Array<any>> => 355 query( 356 'queryCpuStateFilter', 357 `select cpu,id as filterId from cpu_measure_filter where name = 'cpu_idle' order by cpu;`, 358 {} 359 ); 360 361export const queryCpuState = (cpuFilterId: number): Promise<Array<any>> => 362 query( 363 'queryCpuState', 364 ` 365 select (A.ts - B.start_ts) as startTs,ifnull(dur,B.end_ts - A.ts) dur, 366 value 367 from measure A,trace_range B 368 where filter_id = $filterId;`, 369 { $filterId: cpuFilterId } 370 ); 371 372export const queryCpuMaxFreq = (): Promise<Array<any>> => 373 query( 374 'queryCpuMaxFreq', 375 ` 376 select 377 max(value) as maxFreq 378 from 379 measure c 380 inner join 381 cpu_measure_filter t 382 on 383 c.filter_id = t.id 384 where 385 (name = 'cpufreq' or name='cpu_frequency');` 386 ); 387export const queryTraceCpu = (): Promise< 388 Array<{ 389 tid: string; 390 pid: string; 391 cpu: string; 392 dur: string; 393 min_freq: string; 394 max_freq: string; 395 avg_frequency: string; 396 }> 397> => 398 query( 399 'queryTraceCpu', 400 `SELECT 401 itid AS tid, 402 ipid AS pid, 403 group_concat(cpu, ',') AS cpu, 404 group_concat(dur, ',') AS dur, 405 group_concat(min_freq, ',') AS min_freq, 406 group_concat(max_freq, ',') AS max_freq, 407 group_concat(avg_frequency, ',') AS avg_frequency 408 FROM 409 (SELECT 410 itid, 411 ipid, 412 cpu, 413 CAST (SUM(dur) AS INT) AS dur, 414 CAST (MIN(freq) AS INT) AS min_freq, 415 CAST (MAX(freq) AS INT) AS max_freq, 416 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 417 from 418 result 419 group by 420 itid, cpu 421 ) 422 GROUP BY 423 ipid, itid 424 ORDER BY 425 ipid 426 ` 427 ); 428 429export const queryTraceCpuTop = (): Promise< 430 Array<{ 431 tid: string; 432 pid: string; 433 cpu: string; 434 duration: string; 435 min_freq: string; 436 max_freq: string; 437 avg_frequency: string; 438 sumNum: string; 439 }> 440> => 441 query( 442 'queryTraceCpuTop', 443 `SELECT 444 ipid AS pid, 445 itid AS tid, 446 group_concat(cpu, ',') AS cpu, 447 group_concat(dur, ',') AS dur, 448 group_concat(avg_frequency, ',') AS avg_frequency, 449 group_concat(min_freq, ',') AS min_freq, 450 group_concat(max_freq, ',') AS max_freq, 451 sum(dur * avg_frequency) AS sumNum 452 FROM 453 (SELECT 454 itid, 455 ipid, 456 cpu, 457 CAST (SUM(dur) AS INT) AS dur, 458 CAST (MIN(freq) AS INT) AS min_freq, 459 CAST (MAX(freq) AS INT) AS max_freq, 460 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 461 from result group by itid, cpu 462 ) 463 GROUP BY 464 ipid, itid 465 ORDER BY 466 sumNum 467 DESC 468 LIMIT 10; 469 ` 470 ); 471export const queryCpuFreqUsageData = ( 472 Ids: Array<number> 473): Promise< 474 Array<{ 475 startNS: number; 476 filter_id: number; 477 value: number; 478 dur: number 479 }> 480> => 481 query( 482 'queryCpuFreqUsageData', 483 `select 484 value, 485 ifnull(dur,tb.end_ts - c.ts) dur, 486 ts-tb.start_ts as startNS, 487 filter_id 488 from 489 measure c, 490 trace_range tb 491 where 492 c.filter_id in (${Ids.join(',')}) 493 ` 494 ); 495 496export const queryCpuFreqFilterId = (): Promise< 497 Array<{ 498 id: number; 499 cpu: number 500 }> 501> => 502 query( 503 'queryCpuFreqFilterId', 504 ` 505 select 506 id, 507 cpu 508 from 509 cpu_measure_filter 510 where 511 name='cpufreq' 512 or 513 name='cpu_frequency' 514 ` 515 ); 516export const searchCpuData = (keyword: string): Promise<Array<any>> => { 517 let id = parseInt(keyword); 518 let sql = ` 519 select B.pid as processId, 520 B.cpu, 521 B.tid, 522 'cpu' as type, 523 B.itid as id, 524 B.dur as dur, 525 B.ts - TR.start_ts as startTime, 526 B.arg_setid as argSetID 527from thread_state AS B, trace_range TR 528 left join process p on B.pid = p.pid 529 left join thread t on B.itid = t.itid 530where B.cpu not null and B.ts between TR.start_ts and TR.end_ts 531 and ( 532 t.name like '%${keyword}%' 533 or B.tid = ${Number.isNaN(id) ? -1 : id} 534 or B.pid = ${Number.isNaN(id) ? -1 : id} 535 or p.name like '%${keyword}%' 536 ) 537order by startTime;`; 538 return query('searchCpuData', sql, {}); 539}; 540export const getTabPaneCounterSampleData = ( 541 leftNs: number, 542 rightNs: number, 543 cpuStateFilterIds: Array<number> 544): Promise<Array<any>> => { 545 let str = ''; 546 if (cpuStateFilterIds.length > 0) { 547 str = ` and filter_id in (${cpuStateFilterIds.join(',')})`; 548 } 549 return query( 550 'getTabPaneCounterSampleData', 551 ` 552 select value, filter_id as filterId, ts, f.cpu 553 from measure left join cpu_measure_filter as f on f.id=filter_id 554 where 555 ts <= $rightNs${str} order by ts asc; 556`, 557 { $leftNs: leftNs, $rightNs: rightNs } 558 ); 559}; 560export const queryJsCpuProfilerConfig = (): Promise<Array<any>> => 561 query('queryJsCpuProfilerConfig', `SELECT pid, type, enable_cpu_Profiler as enableCpuProfiler FROM js_config`); 562export const queryJsCpuProfilerData = (): Promise<Array<any>> => 563 query('queryJsCpuProfilerData', `SELECT 1 WHERE EXISTS(select 1 from js_cpu_profiler_node)`); 564export const querySystemCallsTop = (): Promise< 565 Array<{ 566 tid: string; 567 pid: string; 568 funName: string; 569 frequency: string; 570 minDur: string; 571 maxDur: string; 572 avgDur: string; 573 }> 574> => 575 query( 576 'querySystemCallsTop', 577 `SELECT 578 cpu.tid AS tid, 579 cpu.pid AS pid, 580 callstack.name AS funName, 581 count(callstack.name) AS frequency, 582 min(callstack.dur) AS minDur, 583 max(callstack.dur) AS maxDur, 584 round(avg(callstack.dur)) AS avgDur 585 FROM 586 callstack 587 INNER JOIN 588 (SELECT 589 itid AS tid, 590 ipid AS pid, 591 group_concat(cpu, ',') AS cpu, 592 group_concat(dur, ',') AS dur, 593 group_concat(min_freq, ',') AS min_freq, 594 group_concat(max_freq, ',') AS max_freq, 595 group_concat(avg_frequency, ',') AS avg_frequency, 596 sum(dur * avg_frequency) AS sumNum 597 FROM 598 (SELECT 599 itid, 600 ipid, 601 cpu, 602 CAST (SUM(dur) AS INT) AS dur, 603 CAST (MIN(freq) AS INT) AS min_freq, 604 CAST (MAX(freq) AS INT) AS max_freq, 605 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 606 FROM 607 result 608 GROUP BY 609 itid, cpu 610 ) 611 GROUP BY 612 ipid, itid 613 ORDER BY 614 sumNum 615 DESC 616 LIMIT 10 617 ) AS cpu 618 ON 619 callstack.callid = cpu.tid 620 GROUP BY 621 callstack.name 622 ORDER BY 623 frequency 624 DESC 625 LIMIT 10` 626 ); 627export const queryWakeupListPriority = (itid: number[], ts: number[], cpus: number[]): Promise<Array<any>> => 628 query( 629 'queryWakeupListPriority', 630 ` 631 select itid, priority, (ts - start_ts) as ts, dur, cpu 632 from sched_slice,trace_range where cpu in (${cpus.join(',')}) 633 and itid in (${itid.join(',')}) 634 and ts - start_ts in (${ts.join(',')}) 635 `, 636 {} 637 ); 638export const getCpuLimitFreqBoxSelect = ( 639 arr: Array<{ 640 maxFilterId: string; 641 minFilterId: string; 642 cpu: string; 643 }>, 644 rightNS: number 645): Promise<Array<any>> => { 646 let ids = []; 647 let condition = `(case`; 648 for (let item of arr) { 649 condition = `${condition} when filter_id in (${item.maxFilterId}, ${item.minFilterId}) then ${item.cpu}`; 650 ids.push(item.maxFilterId, item.minFilterId); 651 } 652 condition = `${condition} else -1 end) as cpu`; 653 let sql = ` 654 select 655 ts - T.start_ts as startNs, 656 dur, 657 max(value) as max, 658 min(value) as min, 659 ${condition} 660 from measure,trace_range T 661 where filter_id in (${ids.join(',')}) 662 and ts - T.start_ts < ${rightNS} 663 group by ts 664 `; 665 console.log(sql); 666 return query('getCpuLimitFreqBoxSelect', sql, {}); 667}; 668export const getCpuLimitFreq = (maxId: number, minId: number, cpu: number): Promise<Array<CpuFreqLimitsStruct>> => 669 query( 670 'getCpuLimitFreq', 671 ` 672 select ts - T.start_ts as startNs, 673 dur, 674 max(value) as max, 675 min(value) as min, 676 $cpu as cpu 677 from measure,trace_range T where filter_id in ($maxId,$minId) group by ts 678`, 679 { $maxId: maxId, $minId: minId, $cpu: cpu } 680 ); 681export const getCpuLimitFreqId = (): Promise<Array<CpuFreqRowLimit>> => 682 query( 683 'getCpuMaxMinFreqId', 684 ` 685 select cpu,MAX(iif(name = 'cpu_frequency_limits_max',id,0)) as maxFilterId,MAX(iif(name = 'cpu_frequency_limits_min',id,0)) as minFilterId from cpu_measure_filter where name in ('cpu_frequency_limits_max','cpu_frequency_limits_min') group by cpu 686`, 687 {} 688 ); 689 690export const getCpuLimitFreqMax = (filterIds: string): Promise<Array<any>> => { 691 return query( 692 'getCpuLimitFreqMax', 693 ` 694 select max(value) as maxValue,filter_id as filterId from measure where filter_id in (${filterIds}) group by filter_id 695`, 696 {} 697 ); 698};