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 154export const getTabCounters = ( 155 processFilterIds: Array<number>, 156 virtualFilterIds: Array<number>, 157 startTime: number 158): //@ts-ignore 159Promise<unknown> => { 160 let processSql = `select 161 t1.filter_id as trackId, 162 t2.name, 163 value, 164 t1.ts - t3.start_ts as startTime 165 from 166 process_measure t1 167 left join 168 process_measure_filter t2 169 on 170 t1.filter_id = t2.id 171 left join 172 trace_range t3 173 where 174 filter_id in (${processFilterIds.join(',')}) 175 and 176 startTime <= ${startTime}`; 177 let virtualSql = `select 178 t1.filter_id as trackId, 179 t2.name, 180 value, 181 t1.ts - t3.start_ts as startTime 182 from 183 sys_mem_measure t1 184 left join 185 sys_event_filter t2 186 on 187 t1.filter_id = t2.id 188 left join 189 trace_range t3 190 where 191 filter_id in (${virtualFilterIds.join(',')}) 192 and 193 startTime <= ${startTime}`; 194 let sql = ''; 195 if (processFilterIds.length > 0 && virtualFilterIds.length > 0) { 196 sql = `${processSql} union ${virtualSql}`; 197 } else { 198 if (processFilterIds.length > 0) { 199 sql = processSql; 200 } else { 201 sql = virtualSql; 202 } 203 } 204 return query<Counter>('getTabCounters', sql, {}); 205}; 206export const getTabCpuByProcess = ( 207 cpus: Array<number>, 208 leftNS: number, 209 rightNS: number 210): //@ts-ignore 211Promise<unknown[]> => //@ts-ignore 212 query<unknown>( 213 'getTabCpuByProcess', 214 ` 215 select 216 B.pid as pid, 217 sum(iif(B.dur = -1 or B.dur is null, 0, B.dur)) as wallDuration, 218 avg(iif(B.dur = -1 or B.dur is null, 0, B.dur)) as avgDuration, 219 count(B.tid) as occurrences 220 from 221 thread_state AS B 222 left join 223 trace_range AS TR 224 where 225 B.cpu in (${cpus.join(',')}) 226 and 227 not ((B.ts - TR.start_ts + iif(B.dur = -1 or B.dur is null, 0, B.dur) < $leftNS) or (B.ts - TR.start_ts > $rightNS )) 228 group by 229 B.pid 230 order by 231 wallDuration desc;`, 232 { $rightNS: rightNS, $leftNS: leftNS } 233 ); 234export const getTabCpuByThread = (cpus: Array<number>, leftNS: number, rightNS: number): Promise<unknown[]> => 235 query<unknown>( 236 'getTabCpuByThread', 237 ` 238 select 239 TS.pid as pid, 240 TS.tid as tid, 241 TS.cpu, 242 sum( min(${rightNS},(TS.ts - TR.start_ts + iif(TS.dur = -1 or TS.dur is null, 0, TS.dur))) - max(${leftNS},TS.ts - TR.start_ts)) wallDuration, 243 count(TS.tid) as occurrences 244 from 245 thread_state AS TS 246 left join 247 trace_range AS TR 248 where 249 TS.cpu in (${cpus.join(',')}) 250 and 251 not ((TS.ts - TR.start_ts + iif(TS.dur = -1 or TS.dur is null, 0, TS.dur) < $leftNS) or (TS.ts - TR.start_ts > $rightNS)) 252 group by 253 TS.cpu, 254 TS.pid, 255 TS.tid 256 order by 257 wallDuration desc;`, 258 { $rightNS: rightNS, $leftNS: leftNS } 259 ); 260export const queryCpuData = (cpu: number, startNS: number, endNS: number): Promise<Array<CpuStruct>> => 261 query( 262 'queryCpuData', 263 ` 264 SELECT 265 B.pid as processId, 266 B.cpu, 267 B.tid, 268 B.itid as id, 269 B.dur, 270 B.ts - TR.start_ts AS startTime, 271 B.arg_setid as argSetID 272from thread_state AS B 273 left join trace_range AS TR 274where B.itid is not null 275 and 276 B.cpu = $cpu 277 and 278 startTime between $startNS and $endNS;`, 279 { 280 $cpu: cpu, 281 $startNS: startNS, 282 $endNS: endNS, 283 } 284 ); 285 286export const queryCpuFreq = (): Promise<Array<{ cpu: number; filterId: number }>> => 287 query( 288 'queryCpuFreq', 289 ` 290 select 291 cpu,id as filterId 292 from 293 cpu_measure_filter 294 where 295 (name='cpufreq' or name='cpu_frequency') 296 order by cpu; 297 ` 298 ); 299 300export const queryCpuFreqData = (cpu: number): Promise<Array<CpuFreqStruct>> => 301 query<CpuFreqStruct>( 302 'queryCpuFreqData', 303 ` 304 select 305 cpu, 306 value, 307 ifnull(dur,tb.end_ts - c.ts) dur, 308 ts-tb.start_ts as startNS 309 from 310 measure c, 311 trace_range tb 312 inner join 313 cpu_measure_filter t 314 on 315 c.filter_id = t.id 316 where 317 (name = 'cpufreq' or name='cpu_frequency') 318 and 319 cpu= $cpu 320 --order by ts; 321 `, 322 { $cpu: cpu } 323 ); 324 325export const queryCpuMax = (): //@ts-ignore 326Promise<Array<unknown>> => 327 query( 328 'queryCpuMax', 329 ` 330 select 331 cpu 332 from 333 sched_slice 334 order by 335 cpu 336 desc limit 1;` 337 ); 338 339export const queryCpuDataCount = (): Promise<unknown[]> => 340 query('queryCpuDataCount', 'select count(1) as count,cpu from thread_state where cpu not null group by cpu'); 341 342export const queryCpuCount = (): //@ts-ignore 343Promise<Array<unknown>> => 344 query( 345 'queryCpuCount', 346 ` 347 select max(cpuCount) cpuCount from 348(select ifnull((max(cpu) + 1),0) cpuCount from cpu_measure_filter where name in ('cpu_frequency','cpu_idle') 349 union all 350 select ifnull((max(callid)+1),0) cpuCount from irq 351) A;` 352 ); 353 354export const queryCpuSchedSlice = (): Promise<Array<unknown>> => 355 query( 356 'queryCpuSchedSlice', 357 ` 358 select (ts - start_ts) as ts, 359 itid, 360 end_state as endState, 361 priority 362 from sched_slice,trace_range;` 363 ); 364 365export const queryCpuStateFilter = (): //@ts-ignore 366Promise<Array<unknown>> => 367 query( 368 'queryCpuStateFilter', 369 `select cpu,id as filterId 370 from cpu_measure_filter 371 where name = 'cpu_idle' order by cpu;`, 372 {} 373 ); 374 375export const queryCpuState = ( 376 cpuFilterId: number 377): //@ts-ignore 378Promise<Array<unknown>> => 379 query( 380 'queryCpuState', 381 ` 382 select (A.ts - B.start_ts) as startTs,ifnull(dur,B.end_ts - A.ts) dur, 383 value 384 from measure A,trace_range B 385 where filter_id = $filterId;`, 386 { $filterId: cpuFilterId } 387 ); 388 389export const queryCpuMaxFreq = (): //@ts-ignore 390Promise<Array<unknown>> => 391 query( 392 'queryCpuMaxFreq', 393 ` 394 select 395 max(value) as maxFreq 396 from 397 measure c 398 inner join 399 cpu_measure_filter t 400 on 401 c.filter_id = t.id 402 where 403 (name = 'cpufreq' or name='cpu_frequency');` 404 ); 405export const queryTraceCpu = (): Promise< 406 Array<{ 407 tid: string; 408 pid: string; 409 cpu: string; 410 dur: string; 411 min_freq: string; 412 max_freq: string; 413 avg_frequency: string; 414 }> 415> => 416 query( 417 'queryTraceCpu', 418 `SELECT 419 itid AS tid, 420 ipid AS pid, 421 group_concat(cpu, ',') AS cpu, 422 group_concat(dur, ',') AS dur, 423 group_concat(min_freq, ',') AS min_freq, 424 group_concat(max_freq, ',') AS max_freq, 425 group_concat(avg_frequency, ',') AS avg_frequency 426 FROM 427 (SELECT 428 itid, 429 ipid, 430 cpu, 431 CAST (SUM(dur) AS INT) AS dur, 432 CAST (MIN(freq) AS INT) AS min_freq, 433 CAST (MAX(freq) AS INT) AS max_freq, 434 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 435 from 436 result 437 group by 438 itid, cpu 439 ) 440 GROUP BY 441 ipid, itid 442 ORDER BY 443 ipid 444 ` 445 ); 446 447export const queryTraceCpuTop = (): Promise< 448 Array<{ 449 tid: string; 450 pid: string; 451 cpu: string; 452 duration: string; 453 min_freq: string; 454 max_freq: string; 455 avg_frequency: string; 456 sumNum: string; 457 }> 458> => 459 query( 460 'queryTraceCpuTop', 461 `SELECT 462 ipid AS pid, 463 itid AS tid, 464 group_concat(cpu, ',') AS cpu, 465 group_concat(dur, ',') AS dur, 466 group_concat(avg_frequency, ',') AS avg_frequency, 467 group_concat(min_freq, ',') AS min_freq, 468 group_concat(max_freq, ',') AS max_freq, 469 sum(dur * avg_frequency) AS sumNum 470 FROM 471 (SELECT 472 itid, 473 ipid, 474 cpu, 475 CAST (SUM(dur) AS INT) AS dur, 476 CAST (MIN(freq) AS INT) AS min_freq, 477 CAST (MAX(freq) AS INT) AS max_freq, 478 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 479 from result group by itid, cpu 480 ) 481 GROUP BY 482 ipid, itid 483 ORDER BY 484 sumNum 485 DESC 486 LIMIT 10; 487 ` 488 ); 489export const queryCpuFreqUsageData = ( 490 Ids: Array<number> 491): Promise< 492 Array<{ 493 startNS: number; 494 filter_id: number; 495 value: number; 496 dur: number; 497 }> 498> => 499 query( 500 'queryCpuFreqUsageData', 501 `select 502 value, 503 ifnull(dur,tb.end_ts - c.ts) dur, 504 ts-tb.start_ts as startNS, 505 filter_id 506 from 507 measure c, 508 trace_range tb 509 where 510 c.filter_id in (${Ids.join(',')}) 511 ` 512 ); 513 514export const queryCpuFreqFilterId = (): Promise< 515 Array<{ 516 id: number; 517 cpu: number; 518 }> 519> => 520 query( 521 'queryCpuFreqFilterId', 522 ` 523 select 524 id, 525 cpu 526 from 527 cpu_measure_filter 528 where 529 name='cpufreq' 530 or 531 name='cpu_frequency' 532 ` 533 ); 534export const searchCpuData = ( 535 keyword: string 536): //@ts-ignore 537Promise<Array<unknown>> => { 538 let id = parseInt(keyword); 539 let sql = ` 540 select B.pid as processId, 541 B.cpu, 542 B.tid, 543 'cpu' as type, 544 B.itid as id, 545 B.dur as dur, 546 B.ts - TR.start_ts as startTime, 547 B.arg_setid as argSetID 548from thread_state AS B, trace_range TR 549 left join process p on B.pid = p.pid 550 left join thread t on B.itid = t.itid 551where B.cpu not null and B.ts between TR.start_ts and TR.end_ts 552 and ( 553 t.name like '%${keyword}%' 554 or B.tid = ${Number.isNaN(id) ? -1 : id} 555 or B.pid = ${Number.isNaN(id) ? -1 : id} 556 or p.name like '%${keyword}%' 557 ) 558order by startTime;`; 559 return query('searchCpuData', sql, {}); 560}; 561export const getTabPaneCounterSampleData = ( 562 leftNs: number, 563 rightNs: number, 564 cpuStateFilterIds: Array<number> 565): //@ts-ignore 566Promise<Array<unknown>> => { 567 let str = ''; 568 if (cpuStateFilterIds.length > 0) { 569 str = ` and filter_id in (${cpuStateFilterIds.join(',')})`; 570 } 571 return query( 572 'getTabPaneCounterSampleData', 573 ` 574 select value, filter_id as filterId, ts, f.cpu 575 from measure left join cpu_measure_filter as f on f.id=filter_id 576 where 577 ts <= $rightNs${str} order by ts asc; 578`, 579 { $leftNs: leftNs, $rightNs: rightNs } 580 ); 581}; 582export const queryJsCpuProfilerConfig = (): //@ts-ignore 583Promise<Array<unknown>> => 584 query('queryJsCpuProfilerConfig', `SELECT pid, type, enable_cpu_Profiler as enableCpuProfiler FROM js_config`); 585export const queryJsCpuProfilerData = (): //@ts-ignore 586Promise<Array<unknown>> => query('queryJsCpuProfilerData', `SELECT 1 WHERE EXISTS(select 1 from js_cpu_profiler_node)`); 587export const querySystemCallsTop = (): Promise< 588 Array<{ 589 tid: string; 590 pid: string; 591 funName: string; 592 frequency: string; 593 minDur: string; 594 maxDur: string; 595 avgDur: string; 596 }> 597> => 598 query( 599 'querySystemCallsTop', 600 `SELECT 601 cpu.tid AS tid, 602 cpu.pid AS pid, 603 callstack.name AS funName, 604 count(callstack.name) AS frequency, 605 min(callstack.dur) AS minDur, 606 max(callstack.dur) AS maxDur, 607 round(avg(callstack.dur)) AS avgDur 608 FROM 609 callstack 610 INNER JOIN 611 (SELECT 612 itid AS tid, 613 ipid AS pid, 614 group_concat(cpu, ',') AS cpu, 615 group_concat(dur, ',') AS dur, 616 group_concat(min_freq, ',') AS min_freq, 617 group_concat(max_freq, ',') AS max_freq, 618 group_concat(avg_frequency, ',') AS avg_frequency, 619 sum(dur * avg_frequency) AS sumNum 620 FROM 621 (SELECT 622 itid, 623 ipid, 624 cpu, 625 CAST (SUM(dur) AS INT) AS dur, 626 CAST (MIN(freq) AS INT) AS min_freq, 627 CAST (MAX(freq) AS INT) AS max_freq, 628 CAST ( (SUM(dur * freq) / SUM(dur) ) AS INT) AS avg_frequency 629 FROM 630 result 631 GROUP BY 632 itid, cpu 633 ) 634 GROUP BY 635 ipid, itid 636 ORDER BY 637 sumNum 638 DESC 639 LIMIT 10 640 ) AS cpu 641 ON 642 callstack.callid = cpu.tid 643 GROUP BY 644 callstack.name 645 ORDER BY 646 frequency 647 DESC 648 LIMIT 10` 649 ); 650export const queryWakeupListPriority = ( 651 itid: number[], 652 ts: number[], 653 cpus: number[] 654): //@ts-ignore 655Promise<Array<unknown>> => 656 query( 657 'queryWakeupListPriority', 658 ` 659 select itid, priority, (ts - start_ts) as ts, dur, cpu 660 from sched_slice,trace_range where cpu in (${cpus.join(',')}) 661 and itid in (${itid.join(',')}) 662 and ts - start_ts in (${ts.join(',')}) 663 `, 664 {} 665 ); 666export const getCpuLimitFreqBoxSelect = ( 667 arr: Array<{ 668 maxFilterId: string; 669 minFilterId: string; 670 cpu: string; 671 }>, 672 rightNS: number 673): //@ts-ignore 674Promise<Array<unknown>> => { 675 let ids = []; 676 let condition = `(case`; 677 for (let item of arr) { 678 condition = `${condition} when filter_id in (${item.maxFilterId}, ${item.minFilterId}) then ${item.cpu}`; 679 ids.push(item.maxFilterId, item.minFilterId); 680 } 681 condition = `${condition} else -1 end) as cpu`; 682 let sql = ` 683 select 684 ts - T.start_ts as startNs, 685 dur, 686 max(value) as max, 687 min(value) as min, 688 ${condition} 689 from measure,trace_range T 690 where filter_id in (${ids.join(',')}) 691 and ts - T.start_ts < ${rightNS} 692 group by ts 693 `; 694 return query('getCpuLimitFreqBoxSelect', sql, {}); 695}; 696export const getCpuLimitFreq = (maxId: number, minId: number, cpu: number): Promise<Array<CpuFreqLimitsStruct>> => 697 query( 698 'getCpuLimitFreq', 699 ` 700 select ts - T.start_ts as startNs, 701 dur, 702 max(value) as max, 703 min(value) as min, 704 $cpu as cpu 705 from measure,trace_range T where filter_id in ($maxId,$minId) group by ts 706`, 707 { $maxId: maxId, $minId: minId, $cpu: cpu } 708 ); 709export const getCpuLimitFreqId = (): Promise<Array<CpuFreqRowLimit>> => 710 query( 711 'getCpuMaxMinFreqId', 712 ` 713 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 714`, 715 {} 716 ); 717 718export const getCpuLimitFreqMax = ( 719 filterIds: string 720): //@ts-ignore 721Promise<Array<unknown>> => { 722 return query( 723 'getCpuLimitFreqMax', 724 ` 725 select max(value) as maxValue,filter_id as filterId from measure where filter_id in (${filterIds}) group by filter_id 726`, 727 {} 728 ); 729}; 730