callchain.c (b49a821ed9e05fa0ccbaec2555052b2a920be517) | callchain.c (a1a8bed32de197801bb861fbf13cd01496df3e05) |
---|---|
1/* 2 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com> 3 * 4 * Handle the callchains from the stream in an ad-hoc radix tree and then 5 * sort them in an rbtree. 6 * 7 * Using a radix for code path provides a fast retrieval and factorizes 8 * memory use. Also that lets us use the paths in a hierarchical graph view. --- 549 unchanged lines hidden (view full) --- 558 } 559 call->ip = cursor_node->ip; 560 call->ms.sym = cursor_node->sym; 561 call->ms.map = map__get(cursor_node->map); 562 563 if (cursor_node->branch) { 564 call->branch_count = 1; 565 | 1/* 2 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com> 3 * 4 * Handle the callchains from the stream in an ad-hoc radix tree and then 5 * sort them in an rbtree. 6 * 7 * Using a radix for code path provides a fast retrieval and factorizes 8 * memory use. Also that lets us use the paths in a hierarchical graph view. --- 549 unchanged lines hidden (view full) --- 558 } 559 call->ip = cursor_node->ip; 560 call->ms.sym = cursor_node->sym; 561 call->ms.map = map__get(cursor_node->map); 562 563 if (cursor_node->branch) { 564 call->branch_count = 1; 565 |
566 if (cursor_node->branch_flags.predicted) 567 call->predicted_count = 1; | 566 if (cursor_node->branch_from) { 567 /* 568 * branch_from is set with value somewhere else 569 * to imply it's "to" of a branch. 570 */ 571 call->brtype_stat.branch_to = true; |
568 | 572 |
569 if (cursor_node->branch_flags.abort) 570 call->abort_count = 1; | 573 if (cursor_node->branch_flags.predicted) 574 call->predicted_count = 1; |
571 | 575 |
572 call->cycles_count = cursor_node->branch_flags.cycles; 573 call->iter_count = cursor_node->nr_loop_iter; 574 call->samples_count = cursor_node->samples; | 576 if (cursor_node->branch_flags.abort) 577 call->abort_count = 1; |
575 | 578 |
576 branch_type_count(&call->brtype_stat, 577 &cursor_node->branch_flags, 578 cursor_node->branch_from, 579 cursor_node->ip); | 579 branch_type_count(&call->brtype_stat, 580 &cursor_node->branch_flags, 581 cursor_node->branch_from, 582 cursor_node->ip); 583 } else { 584 /* 585 * It's "from" of a branch 586 */ 587 call->brtype_stat.branch_to = false; 588 call->cycles_count = 589 cursor_node->branch_flags.cycles; 590 call->iter_count = cursor_node->nr_loop_iter; 591 call->samples_count = cursor_node->samples; 592 } |
580 } 581 582 list_add_tail(&call->list, &node->val); 583 584 callchain_cursor_advance(cursor); 585 cursor_node = callchain_cursor_current(cursor); 586 } 587 return 0; --- 92 unchanged lines hidden (view full) --- 680 left = cnode->ip; 681 right = node->ip; 682 } 683 684 if (left == right) { 685 if (node->branch) { 686 cnode->branch_count++; 687 | 593 } 594 595 list_add_tail(&call->list, &node->val); 596 597 callchain_cursor_advance(cursor); 598 cursor_node = callchain_cursor_current(cursor); 599 } 600 return 0; --- 92 unchanged lines hidden (view full) --- 693 left = cnode->ip; 694 right = node->ip; 695 } 696 697 if (left == right) { 698 if (node->branch) { 699 cnode->branch_count++; 700 |
688 if (node->branch_flags.predicted) 689 cnode->predicted_count++; | 701 if (node->branch_from) { 702 /* 703 * It's "to" of a branch 704 */ 705 cnode->brtype_stat.branch_to = true; |
690 | 706 |
691 if (node->branch_flags.abort) 692 cnode->abort_count++; | 707 if (node->branch_flags.predicted) 708 cnode->predicted_count++; |
693 | 709 |
694 cnode->cycles_count += node->branch_flags.cycles; 695 cnode->iter_count += node->nr_loop_iter; 696 cnode->samples_count += node->samples; | 710 if (node->branch_flags.abort) 711 cnode->abort_count++; |
697 | 712 |
698 branch_type_count(&cnode->brtype_stat, 699 &node->branch_flags, 700 node->branch_from, 701 node->ip); | 713 branch_type_count(&cnode->brtype_stat, 714 &node->branch_flags, 715 node->branch_from, 716 node->ip); 717 } else { 718 /* 719 * It's "from" of a branch 720 */ 721 cnode->brtype_stat.branch_to = false; 722 cnode->cycles_count += 723 node->branch_flags.cycles; 724 cnode->iter_count += node->nr_loop_iter; 725 cnode->samples_count += node->samples; 726 } |
702 } 703 704 return MATCH_EQ; 705 } 706 707 return left > right ? MATCH_GT : MATCH_LT; 708} 709 --- 521 unchanged lines hidden (view full) --- 1231{ 1232 int printed; 1233 1234 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value); 1235 1236 return printed; 1237} 1238 | 727 } 728 729 return MATCH_EQ; 730 } 731 732 return left > right ? MATCH_GT : MATCH_LT; 733} 734 --- 521 unchanged lines hidden (view full) --- 1256{ 1257 int printed; 1258 1259 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value); 1260 1261 return printed; 1262} 1263 |
1239static int count_float_printf(int idx, const char *str, float value, char *bf, int bfsize) | 1264static int count_float_printf(int idx, const char *str, float value, 1265 char *bf, int bfsize, float threshold) |
1240{ 1241 int printed; 1242 | 1266{ 1267 int printed; 1268 |
1269 if (threshold != 0.0 && value < threshold) 1270 return 0; 1271 |
|
1243 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value); 1244 1245 return printed; 1246} 1247 | 1272 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value); 1273 1274 return printed; 1275} 1276 |
1248static int counts_str_build(char *bf, int bfsize, 1249 u64 branch_count, u64 predicted_count, 1250 u64 abort_count, u64 cycles_count, 1251 u64 iter_count, u64 samples_count, 1252 struct branch_type_stat *brtype_stat) | 1277static int branch_to_str(char *bf, int bfsize, 1278 u64 branch_count, u64 predicted_count, 1279 u64 abort_count, 1280 struct branch_type_stat *brtype_stat) |
1253{ | 1281{ |
1254 u64 cycles; | |
1255 int printed, i = 0; 1256 | 1282 int printed, i = 0; 1283 |
1257 if (branch_count == 0) 1258 return scnprintf(bf, bfsize, " (calltrace)"); 1259 | |
1260 printed = branch_type_str(brtype_stat, bf, bfsize); 1261 if (printed) 1262 i++; 1263 1264 if (predicted_count < branch_count) { 1265 printed += count_float_printf(i++, "predicted", 1266 predicted_count * 100.0 / branch_count, | 1284 printed = branch_type_str(brtype_stat, bf, bfsize); 1285 if (printed) 1286 i++; 1287 1288 if (predicted_count < branch_count) { 1289 printed += count_float_printf(i++, "predicted", 1290 predicted_count * 100.0 / branch_count, |
1267 bf + printed, bfsize - printed); | 1291 bf + printed, bfsize - printed, 0.0); |
1268 } 1269 1270 if (abort_count) { 1271 printed += count_float_printf(i++, "abort", 1272 abort_count * 100.0 / branch_count, | 1292 } 1293 1294 if (abort_count) { 1295 printed += count_float_printf(i++, "abort", 1296 abort_count * 100.0 / branch_count, |
1273 bf + printed, bfsize - printed); | 1297 bf + printed, bfsize - printed, 0.1); |
1274 } 1275 | 1298 } 1299 |
1300 if (i) 1301 printed += scnprintf(bf + printed, bfsize - printed, ")"); 1302 1303 return printed; 1304} 1305 1306static int branch_from_str(char *bf, int bfsize, 1307 u64 branch_count, 1308 u64 cycles_count, u64 iter_count, 1309 u64 samples_count) 1310{ 1311 int printed = 0, i = 0; 1312 u64 cycles; 1313 |
|
1276 cycles = cycles_count / branch_count; 1277 if (cycles) { 1278 printed += count_pri64_printf(i++, "cycles", 1279 cycles, 1280 bf + printed, bfsize - printed); 1281 } 1282 1283 if (iter_count && samples_count) { 1284 printed += count_pri64_printf(i++, "iterations", 1285 iter_count / samples_count, 1286 bf + printed, bfsize - printed); 1287 } 1288 1289 if (i) | 1314 cycles = cycles_count / branch_count; 1315 if (cycles) { 1316 printed += count_pri64_printf(i++, "cycles", 1317 cycles, 1318 bf + printed, bfsize - printed); 1319 } 1320 1321 if (iter_count && samples_count) { 1322 printed += count_pri64_printf(i++, "iterations", 1323 iter_count / samples_count, 1324 bf + printed, bfsize - printed); 1325 } 1326 1327 if (i) |
1290 return scnprintf(bf + printed, bfsize - printed, ")"); | 1328 printed += scnprintf(bf + printed, bfsize - printed, ")"); |
1291 | 1329 |
1292 bf[0] = 0; 1293 return 0; | 1330 return printed; |
1294} 1295 | 1331} 1332 |
1333static int counts_str_build(char *bf, int bfsize, 1334 u64 branch_count, u64 predicted_count, 1335 u64 abort_count, u64 cycles_count, 1336 u64 iter_count, u64 samples_count, 1337 struct branch_type_stat *brtype_stat) 1338{ 1339 int printed; 1340 1341 if (branch_count == 0) 1342 return scnprintf(bf, bfsize, " (calltrace)"); 1343 1344 if (brtype_stat->branch_to) { 1345 printed = branch_to_str(bf, bfsize, branch_count, 1346 predicted_count, abort_count, brtype_stat); 1347 } else { 1348 printed = branch_from_str(bf, bfsize, branch_count, 1349 cycles_count, iter_count, samples_count); 1350 } 1351 1352 if (!printed) 1353 bf[0] = 0; 1354 1355 return printed; 1356} 1357 |
|
1296static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, 1297 u64 branch_count, u64 predicted_count, 1298 u64 abort_count, u64 cycles_count, 1299 u64 iter_count, u64 samples_count, 1300 struct branch_type_stat *brtype_stat) 1301{ 1302 char str[256]; 1303 --- 170 unchanged lines hidden --- | 1358static int callchain_counts_printf(FILE *fp, char *bf, int bfsize, 1359 u64 branch_count, u64 predicted_count, 1360 u64 abort_count, u64 cycles_count, 1361 u64 iter_count, u64 samples_count, 1362 struct branch_type_stat *brtype_stat) 1363{ 1364 char str[256]; 1365 --- 170 unchanged lines hidden --- |