diff options
Diffstat (limited to 'tools/perf/scripts/python')
| -rwxr-xr-x | tools/perf/scripts/python/exported-sql-viewer.py | 510 | ||||
| -rw-r--r-- | tools/perf/scripts/python/failed-syscalls-by-pid.py | 21 | ||||
| -rw-r--r-- | tools/perf/scripts/python/mem-phys-addr.py | 24 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/net_dropmonitor.py | 10 | ||||
| -rw-r--r-- | tools/perf/scripts/python/netdev-times.py | 82 | ||||
| -rw-r--r-- | tools/perf/scripts/python/powerpc-hcalls.py | 18 | ||||
| -rw-r--r-- | tools/perf/scripts/python/sctop.py | 24 | ||||
| -rwxr-xr-x | tools/perf/scripts/python/stackcollapse.py | 7 | ||||
| -rw-r--r-- | tools/perf/scripts/python/stat-cpi.py | 10 | ||||
| -rw-r--r-- | tools/perf/scripts/python/syscall-counts-by-pid.py | 22 | ||||
| -rw-r--r-- | tools/perf/scripts/python/syscall-counts.py | 18 |
11 files changed, 482 insertions, 264 deletions
diff --git a/tools/perf/scripts/python/exported-sql-viewer.py b/tools/perf/scripts/python/exported-sql-viewer.py index c3091401df91..09ce73b07d35 100755 --- a/tools/perf/scripts/python/exported-sql-viewer.py +++ b/tools/perf/scripts/python/exported-sql-viewer.py | |||
| @@ -1,3 +1,4 @@ | |||
| 1 | #!/usr/bin/env python2 | ||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | # exported-sql-viewer.py: view data from sql database | 3 | # exported-sql-viewer.py: view data from sql database |
| 3 | # Copyright (c) 2014-2018, Intel Corporation. | 4 | # Copyright (c) 2014-2018, Intel Corporation. |
| @@ -1397,18 +1398,28 @@ class BranchModel(TreeModel): | |||
| 1397 | def HasMoreRecords(self): | 1398 | def HasMoreRecords(self): |
| 1398 | return self.more | 1399 | return self.more |
| 1399 | 1400 | ||
| 1401 | # Report Variables | ||
| 1402 | |||
| 1403 | class ReportVars(): | ||
| 1404 | |||
| 1405 | def __init__(self, name = "", where_clause = "", limit = ""): | ||
| 1406 | self.name = name | ||
| 1407 | self.where_clause = where_clause | ||
| 1408 | self.limit = limit | ||
| 1409 | |||
| 1410 | def UniqueId(self): | ||
| 1411 | return str(self.where_clause + ";" + self.limit) | ||
| 1412 | |||
| 1400 | # Branch window | 1413 | # Branch window |
| 1401 | 1414 | ||
| 1402 | class BranchWindow(QMdiSubWindow): | 1415 | class BranchWindow(QMdiSubWindow): |
| 1403 | 1416 | ||
| 1404 | def __init__(self, glb, event_id, name, where_clause, parent=None): | 1417 | def __init__(self, glb, event_id, report_vars, parent=None): |
| 1405 | super(BranchWindow, self).__init__(parent) | 1418 | super(BranchWindow, self).__init__(parent) |
| 1406 | 1419 | ||
| 1407 | model_name = "Branch Events " + str(event_id) | 1420 | model_name = "Branch Events " + str(event_id) + " " + report_vars.UniqueId() |
| 1408 | if len(where_clause): | ||
| 1409 | model_name = where_clause + " " + model_name | ||
| 1410 | 1421 | ||
| 1411 | self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, where_clause)) | 1422 | self.model = LookupCreateModel(model_name, lambda: BranchModel(glb, event_id, report_vars.where_clause)) |
| 1412 | 1423 | ||
| 1413 | self.view = QTreeView() | 1424 | self.view = QTreeView() |
| 1414 | self.view.setUniformRowHeights(True) | 1425 | self.view.setUniformRowHeights(True) |
| @@ -1426,7 +1437,7 @@ class BranchWindow(QMdiSubWindow): | |||
| 1426 | 1437 | ||
| 1427 | self.setWidget(self.vbox.Widget()) | 1438 | self.setWidget(self.vbox.Widget()) |
| 1428 | 1439 | ||
| 1429 | AddSubWindow(glb.mainwindow.mdi_area, self, name + " Branch Events") | 1440 | AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name + " Branch Events") |
| 1430 | 1441 | ||
| 1431 | def ResizeColumnToContents(self, column, n): | 1442 | def ResizeColumnToContents(self, column, n): |
| 1432 | # Using the view's resizeColumnToContents() here is extrememly slow | 1443 | # Using the view's resizeColumnToContents() here is extrememly slow |
| @@ -1471,47 +1482,134 @@ class BranchWindow(QMdiSubWindow): | |||
| 1471 | else: | 1482 | else: |
| 1472 | self.find_bar.NotFound() | 1483 | self.find_bar.NotFound() |
| 1473 | 1484 | ||
| 1474 | # Dialog data item converted and validated using a SQL table | 1485 | # Line edit data item |
| 1475 | 1486 | ||
| 1476 | class SQLTableDialogDataItem(): | 1487 | class LineEditDataItem(object): |
| 1477 | 1488 | ||
| 1478 | def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): | 1489 | def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""): |
| 1479 | self.glb = glb | 1490 | self.glb = glb |
| 1480 | self.label = label | 1491 | self.label = label |
| 1481 | self.placeholder_text = placeholder_text | 1492 | self.placeholder_text = placeholder_text |
| 1482 | self.table_name = table_name | ||
| 1483 | self.match_column = match_column | ||
| 1484 | self.column_name1 = column_name1 | ||
| 1485 | self.column_name2 = column_name2 | ||
| 1486 | self.parent = parent | 1493 | self.parent = parent |
| 1494 | self.id = id | ||
| 1487 | 1495 | ||
| 1488 | self.value = "" | 1496 | self.value = default |
| 1489 | 1497 | ||
| 1490 | self.widget = QLineEdit() | 1498 | self.widget = QLineEdit(default) |
| 1491 | self.widget.editingFinished.connect(self.Validate) | 1499 | self.widget.editingFinished.connect(self.Validate) |
| 1492 | self.widget.textChanged.connect(self.Invalidate) | 1500 | self.widget.textChanged.connect(self.Invalidate) |
| 1493 | self.red = False | 1501 | self.red = False |
| 1494 | self.error = "" | 1502 | self.error = "" |
| 1495 | self.validated = True | 1503 | self.validated = True |
| 1496 | 1504 | ||
| 1497 | self.last_id = 0 | ||
| 1498 | self.first_time = 0 | ||
| 1499 | self.last_time = 2 ** 64 | ||
| 1500 | if self.table_name == "<timeranges>": | ||
| 1501 | query = QSqlQuery(self.glb.db) | ||
| 1502 | QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1") | ||
| 1503 | if query.next(): | ||
| 1504 | self.last_id = int(query.value(0)) | ||
| 1505 | self.last_time = int(query.value(1)) | ||
| 1506 | QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1") | ||
| 1507 | if query.next(): | ||
| 1508 | self.first_time = int(query.value(0)) | ||
| 1509 | if placeholder_text: | ||
| 1510 | placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time) | ||
| 1511 | |||
| 1512 | if placeholder_text: | 1505 | if placeholder_text: |
| 1513 | self.widget.setPlaceholderText(placeholder_text) | 1506 | self.widget.setPlaceholderText(placeholder_text) |
| 1514 | 1507 | ||
| 1508 | def TurnTextRed(self): | ||
| 1509 | if not self.red: | ||
| 1510 | palette = QPalette() | ||
| 1511 | palette.setColor(QPalette.Text,Qt.red) | ||
| 1512 | self.widget.setPalette(palette) | ||
| 1513 | self.red = True | ||
| 1514 | |||
| 1515 | def TurnTextNormal(self): | ||
| 1516 | if self.red: | ||
| 1517 | palette = QPalette() | ||
| 1518 | self.widget.setPalette(palette) | ||
| 1519 | self.red = False | ||
| 1520 | |||
| 1521 | def InvalidValue(self, value): | ||
| 1522 | self.value = "" | ||
| 1523 | self.TurnTextRed() | ||
| 1524 | self.error = self.label + " invalid value '" + value + "'" | ||
| 1525 | self.parent.ShowMessage(self.error) | ||
| 1526 | |||
| 1527 | def Invalidate(self): | ||
| 1528 | self.validated = False | ||
| 1529 | |||
| 1530 | def DoValidate(self, input_string): | ||
| 1531 | self.value = input_string.strip() | ||
| 1532 | |||
| 1533 | def Validate(self): | ||
| 1534 | self.validated = True | ||
| 1535 | self.error = "" | ||
| 1536 | self.TurnTextNormal() | ||
| 1537 | self.parent.ClearMessage() | ||
| 1538 | input_string = self.widget.text() | ||
| 1539 | if not len(input_string.strip()): | ||
| 1540 | self.value = "" | ||
| 1541 | return | ||
| 1542 | self.DoValidate(input_string) | ||
| 1543 | |||
| 1544 | def IsValid(self): | ||
| 1545 | if not self.validated: | ||
| 1546 | self.Validate() | ||
| 1547 | if len(self.error): | ||
| 1548 | self.parent.ShowMessage(self.error) | ||
| 1549 | return False | ||
| 1550 | return True | ||
| 1551 | |||
| 1552 | def IsNumber(self, value): | ||
| 1553 | try: | ||
| 1554 | x = int(value) | ||
| 1555 | except: | ||
| 1556 | x = 0 | ||
| 1557 | return str(x) == value | ||
| 1558 | |||
| 1559 | # Non-negative integer ranges dialog data item | ||
| 1560 | |||
| 1561 | class NonNegativeIntegerRangesDataItem(LineEditDataItem): | ||
| 1562 | |||
| 1563 | def __init__(self, glb, label, placeholder_text, column_name, parent): | ||
| 1564 | super(NonNegativeIntegerRangesDataItem, self).__init__(glb, label, placeholder_text, parent) | ||
| 1565 | |||
| 1566 | self.column_name = column_name | ||
| 1567 | |||
| 1568 | def DoValidate(self, input_string): | ||
| 1569 | singles = [] | ||
| 1570 | ranges = [] | ||
| 1571 | for value in [x.strip() for x in input_string.split(",")]: | ||
| 1572 | if "-" in value: | ||
| 1573 | vrange = value.split("-") | ||
| 1574 | if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): | ||
| 1575 | return self.InvalidValue(value) | ||
| 1576 | ranges.append(vrange) | ||
| 1577 | else: | ||
| 1578 | if not self.IsNumber(value): | ||
| 1579 | return self.InvalidValue(value) | ||
| 1580 | singles.append(value) | ||
| 1581 | ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges] | ||
| 1582 | if len(singles): | ||
| 1583 | ranges.append(self.column_name + " IN (" + ",".join(singles) + ")") | ||
| 1584 | self.value = " OR ".join(ranges) | ||
| 1585 | |||
| 1586 | # Positive integer dialog data item | ||
| 1587 | |||
| 1588 | class PositiveIntegerDataItem(LineEditDataItem): | ||
| 1589 | |||
| 1590 | def __init__(self, glb, label, placeholder_text, parent, id = "", default = ""): | ||
| 1591 | super(PositiveIntegerDataItem, self).__init__(glb, label, placeholder_text, parent, id, default) | ||
| 1592 | |||
| 1593 | def DoValidate(self, input_string): | ||
| 1594 | if not self.IsNumber(input_string.strip()): | ||
| 1595 | return self.InvalidValue(input_string) | ||
| 1596 | value = int(input_string.strip()) | ||
| 1597 | if value <= 0: | ||
| 1598 | return self.InvalidValue(input_string) | ||
| 1599 | self.value = str(value) | ||
| 1600 | |||
| 1601 | # Dialog data item converted and validated using a SQL table | ||
| 1602 | |||
| 1603 | class SQLTableDataItem(LineEditDataItem): | ||
| 1604 | |||
| 1605 | def __init__(self, glb, label, placeholder_text, table_name, match_column, column_name1, column_name2, parent): | ||
| 1606 | super(SQLTableDataItem, self).__init__(glb, label, placeholder_text, parent) | ||
| 1607 | |||
| 1608 | self.table_name = table_name | ||
| 1609 | self.match_column = match_column | ||
| 1610 | self.column_name1 = column_name1 | ||
| 1611 | self.column_name2 = column_name2 | ||
| 1612 | |||
| 1515 | def ValueToIds(self, value): | 1613 | def ValueToIds(self, value): |
| 1516 | ids = [] | 1614 | ids = [] |
| 1517 | query = QSqlQuery(self.glb.db) | 1615 | query = QSqlQuery(self.glb.db) |
| @@ -1522,6 +1620,42 @@ class SQLTableDialogDataItem(): | |||
| 1522 | ids.append(str(query.value(0))) | 1620 | ids.append(str(query.value(0))) |
| 1523 | return ids | 1621 | return ids |
| 1524 | 1622 | ||
| 1623 | def DoValidate(self, input_string): | ||
| 1624 | all_ids = [] | ||
| 1625 | for value in [x.strip() for x in input_string.split(",")]: | ||
| 1626 | ids = self.ValueToIds(value) | ||
| 1627 | if len(ids): | ||
| 1628 | all_ids.extend(ids) | ||
| 1629 | else: | ||
| 1630 | return self.InvalidValue(value) | ||
| 1631 | self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")" | ||
| 1632 | if self.column_name2: | ||
| 1633 | self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )" | ||
| 1634 | |||
| 1635 | # Sample time ranges dialog data item converted and validated using 'samples' SQL table | ||
| 1636 | |||
| 1637 | class SampleTimeRangesDataItem(LineEditDataItem): | ||
| 1638 | |||
| 1639 | def __init__(self, glb, label, placeholder_text, column_name, parent): | ||
| 1640 | self.column_name = column_name | ||
| 1641 | |||
| 1642 | self.last_id = 0 | ||
| 1643 | self.first_time = 0 | ||
| 1644 | self.last_time = 2 ** 64 | ||
| 1645 | |||
| 1646 | query = QSqlQuery(glb.db) | ||
| 1647 | QueryExec(query, "SELECT id, time FROM samples ORDER BY id DESC LIMIT 1") | ||
| 1648 | if query.next(): | ||
| 1649 | self.last_id = int(query.value(0)) | ||
| 1650 | self.last_time = int(query.value(1)) | ||
| 1651 | QueryExec(query, "SELECT time FROM samples WHERE time != 0 ORDER BY id LIMIT 1") | ||
| 1652 | if query.next(): | ||
| 1653 | self.first_time = int(query.value(0)) | ||
| 1654 | if placeholder_text: | ||
| 1655 | placeholder_text += ", between " + str(self.first_time) + " and " + str(self.last_time) | ||
| 1656 | |||
| 1657 | super(SampleTimeRangesDataItem, self).__init__(glb, label, placeholder_text, parent) | ||
| 1658 | |||
| 1525 | def IdBetween(self, query, lower_id, higher_id, order): | 1659 | def IdBetween(self, query, lower_id, higher_id, order): |
| 1526 | QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1") | 1660 | QueryExec(query, "SELECT id FROM samples WHERE id > " + str(lower_id) + " AND id < " + str(higher_id) + " ORDER BY id " + order + " LIMIT 1") |
| 1527 | if query.next(): | 1661 | if query.next(): |
| @@ -1559,7 +1693,6 @@ class SQLTableDialogDataItem(): | |||
| 1559 | return str(lower_id) | 1693 | return str(lower_id) |
| 1560 | 1694 | ||
| 1561 | def ConvertRelativeTime(self, val): | 1695 | def ConvertRelativeTime(self, val): |
| 1562 | print "val ", val | ||
| 1563 | mult = 1 | 1696 | mult = 1 |
| 1564 | suffix = val[-2:] | 1697 | suffix = val[-2:] |
| 1565 | if suffix == "ms": | 1698 | if suffix == "ms": |
| @@ -1581,29 +1714,23 @@ class SQLTableDialogDataItem(): | |||
| 1581 | return str(val) | 1714 | return str(val) |
| 1582 | 1715 | ||
| 1583 | def ConvertTimeRange(self, vrange): | 1716 | def ConvertTimeRange(self, vrange): |
| 1584 | print "vrange ", vrange | ||
| 1585 | if vrange[0] == "": | 1717 | if vrange[0] == "": |
| 1586 | vrange[0] = str(self.first_time) | 1718 | vrange[0] = str(self.first_time) |
| 1587 | if vrange[1] == "": | 1719 | if vrange[1] == "": |
| 1588 | vrange[1] = str(self.last_time) | 1720 | vrange[1] = str(self.last_time) |
| 1589 | vrange[0] = self.ConvertRelativeTime(vrange[0]) | 1721 | vrange[0] = self.ConvertRelativeTime(vrange[0]) |
| 1590 | vrange[1] = self.ConvertRelativeTime(vrange[1]) | 1722 | vrange[1] = self.ConvertRelativeTime(vrange[1]) |
| 1591 | print "vrange2 ", vrange | ||
| 1592 | if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): | 1723 | if not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): |
| 1593 | return False | 1724 | return False |
| 1594 | print "ok1" | ||
| 1595 | beg_range = max(int(vrange[0]), self.first_time) | 1725 | beg_range = max(int(vrange[0]), self.first_time) |
| 1596 | end_range = min(int(vrange[1]), self.last_time) | 1726 | end_range = min(int(vrange[1]), self.last_time) |
| 1597 | if beg_range > self.last_time or end_range < self.first_time: | 1727 | if beg_range > self.last_time or end_range < self.first_time: |
| 1598 | return False | 1728 | return False |
| 1599 | print "ok2" | ||
| 1600 | vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True) | 1729 | vrange[0] = self.BinarySearchTime(0, self.last_id, beg_range, True) |
| 1601 | vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False) | 1730 | vrange[1] = self.BinarySearchTime(1, self.last_id + 1, end_range, False) |
| 1602 | print "vrange3 ", vrange | ||
| 1603 | return True | 1731 | return True |
| 1604 | 1732 | ||
| 1605 | def AddTimeRange(self, value, ranges): | 1733 | def AddTimeRange(self, value, ranges): |
| 1606 | print "value ", value | ||
| 1607 | n = value.count("-") | 1734 | n = value.count("-") |
| 1608 | if n == 1: | 1735 | if n == 1: |
| 1609 | pass | 1736 | pass |
| @@ -1621,111 +1748,31 @@ class SQLTableDialogDataItem(): | |||
| 1621 | return True | 1748 | return True |
| 1622 | return False | 1749 | return False |
| 1623 | 1750 | ||
| 1624 | def InvalidValue(self, value): | 1751 | def DoValidate(self, input_string): |
| 1625 | self.value = "" | 1752 | ranges = [] |
| 1626 | palette = QPalette() | 1753 | for value in [x.strip() for x in input_string.split(",")]: |
| 1627 | palette.setColor(QPalette.Text,Qt.red) | 1754 | if not self.AddTimeRange(value, ranges): |
| 1628 | self.widget.setPalette(palette) | 1755 | return self.InvalidValue(value) |
| 1629 | self.red = True | 1756 | ranges = [("(" + self.column_name + " >= " + r[0] + " AND " + self.column_name + " <= " + r[1] + ")") for r in ranges] |
| 1630 | self.error = self.label + " invalid value '" + value + "'" | 1757 | self.value = " OR ".join(ranges) |
| 1631 | self.parent.ShowMessage(self.error) | ||
| 1632 | 1758 | ||
| 1633 | def IsNumber(self, value): | 1759 | # Report Dialog Base |
| 1634 | try: | ||
| 1635 | x = int(value) | ||
| 1636 | except: | ||
| 1637 | x = 0 | ||
| 1638 | return str(x) == value | ||
| 1639 | 1760 | ||
| 1640 | def Invalidate(self): | 1761 | class ReportDialogBase(QDialog): |
| 1641 | self.validated = False | ||
| 1642 | 1762 | ||
| 1643 | def Validate(self): | 1763 | def __init__(self, glb, title, items, partial, parent=None): |
| 1644 | input_string = self.widget.text() | 1764 | super(ReportDialogBase, self).__init__(parent) |
| 1645 | self.validated = True | ||
| 1646 | if self.red: | ||
| 1647 | palette = QPalette() | ||
| 1648 | self.widget.setPalette(palette) | ||
| 1649 | self.red = False | ||
| 1650 | if not len(input_string.strip()): | ||
| 1651 | self.error = "" | ||
| 1652 | self.value = "" | ||
| 1653 | return | ||
| 1654 | if self.table_name == "<timeranges>": | ||
| 1655 | ranges = [] | ||
| 1656 | for value in [x.strip() for x in input_string.split(",")]: | ||
| 1657 | if not self.AddTimeRange(value, ranges): | ||
| 1658 | return self.InvalidValue(value) | ||
| 1659 | ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] | ||
| 1660 | self.value = " OR ".join(ranges) | ||
| 1661 | elif self.table_name == "<ranges>": | ||
| 1662 | singles = [] | ||
| 1663 | ranges = [] | ||
| 1664 | for value in [x.strip() for x in input_string.split(",")]: | ||
| 1665 | if "-" in value: | ||
| 1666 | vrange = value.split("-") | ||
| 1667 | if len(vrange) != 2 or not self.IsNumber(vrange[0]) or not self.IsNumber(vrange[1]): | ||
| 1668 | return self.InvalidValue(value) | ||
| 1669 | ranges.append(vrange) | ||
| 1670 | else: | ||
| 1671 | if not self.IsNumber(value): | ||
| 1672 | return self.InvalidValue(value) | ||
| 1673 | singles.append(value) | ||
| 1674 | ranges = [("(" + self.column_name1 + " >= " + r[0] + " AND " + self.column_name1 + " <= " + r[1] + ")") for r in ranges] | ||
| 1675 | if len(singles): | ||
| 1676 | ranges.append(self.column_name1 + " IN (" + ",".join(singles) + ")") | ||
| 1677 | self.value = " OR ".join(ranges) | ||
| 1678 | elif self.table_name: | ||
| 1679 | all_ids = [] | ||
| 1680 | for value in [x.strip() for x in input_string.split(",")]: | ||
| 1681 | ids = self.ValueToIds(value) | ||
| 1682 | if len(ids): | ||
| 1683 | all_ids.extend(ids) | ||
| 1684 | else: | ||
| 1685 | return self.InvalidValue(value) | ||
| 1686 | self.value = self.column_name1 + " IN (" + ",".join(all_ids) + ")" | ||
| 1687 | if self.column_name2: | ||
| 1688 | self.value = "( " + self.value + " OR " + self.column_name2 + " IN (" + ",".join(all_ids) + ") )" | ||
| 1689 | else: | ||
| 1690 | self.value = input_string.strip() | ||
| 1691 | self.error = "" | ||
| 1692 | self.parent.ClearMessage() | ||
| 1693 | |||
| 1694 | def IsValid(self): | ||
| 1695 | if not self.validated: | ||
| 1696 | self.Validate() | ||
| 1697 | if len(self.error): | ||
| 1698 | self.parent.ShowMessage(self.error) | ||
| 1699 | return False | ||
| 1700 | return True | ||
| 1701 | |||
| 1702 | # Selected branch report creation dialog | ||
| 1703 | |||
| 1704 | class SelectedBranchDialog(QDialog): | ||
| 1705 | |||
| 1706 | def __init__(self, glb, parent=None): | ||
| 1707 | super(SelectedBranchDialog, self).__init__(parent) | ||
| 1708 | 1765 | ||
| 1709 | self.glb = glb | 1766 | self.glb = glb |
| 1710 | 1767 | ||
| 1711 | self.name = "" | 1768 | self.report_vars = ReportVars() |
| 1712 | self.where_clause = "" | ||
| 1713 | 1769 | ||
| 1714 | self.setWindowTitle("Selected Branches") | 1770 | self.setWindowTitle(title) |
| 1715 | self.setMinimumWidth(600) | 1771 | self.setMinimumWidth(600) |
| 1716 | 1772 | ||
| 1717 | items = ( | 1773 | self.data_items = [x(glb, self) for x in items] |
| 1718 | ("Report name:", "Enter a name to appear in the window title bar", "", "", "", ""), | 1774 | |
| 1719 | ("Time ranges:", "Enter time ranges", "<timeranges>", "", "samples.id", ""), | 1775 | self.partial = partial |
| 1720 | ("CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "<ranges>", "", "cpu", ""), | ||
| 1721 | ("Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", ""), | ||
| 1722 | ("PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", ""), | ||
| 1723 | ("TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", ""), | ||
| 1724 | ("DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id"), | ||
| 1725 | ("Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id"), | ||
| 1726 | ("Raw SQL clause: ", "Enter a raw SQL WHERE clause", "", "", "", ""), | ||
| 1727 | ) | ||
| 1728 | self.data_items = [SQLTableDialogDataItem(glb, *x, parent=self) for x in items] | ||
| 1729 | 1776 | ||
| 1730 | self.grid = QGridLayout() | 1777 | self.grid = QGridLayout() |
| 1731 | 1778 | ||
| @@ -1757,23 +1804,28 @@ class SelectedBranchDialog(QDialog): | |||
| 1757 | self.setLayout(self.vbox); | 1804 | self.setLayout(self.vbox); |
| 1758 | 1805 | ||
| 1759 | def Ok(self): | 1806 | def Ok(self): |
| 1760 | self.name = self.data_items[0].value | 1807 | vars = self.report_vars |
| 1761 | if not self.name: | 1808 | for d in self.data_items: |
| 1809 | if d.id == "REPORTNAME": | ||
| 1810 | vars.name = d.value | ||
| 1811 | if not vars.name: | ||
| 1762 | self.ShowMessage("Report name is required") | 1812 | self.ShowMessage("Report name is required") |
| 1763 | return | 1813 | return |
| 1764 | for d in self.data_items: | 1814 | for d in self.data_items: |
| 1765 | if not d.IsValid(): | 1815 | if not d.IsValid(): |
| 1766 | return | 1816 | return |
| 1767 | for d in self.data_items[1:]: | 1817 | for d in self.data_items[1:]: |
| 1768 | if len(d.value): | 1818 | if d.id == "LIMIT": |
| 1769 | if len(self.where_clause): | 1819 | vars.limit = d.value |
| 1770 | self.where_clause += " AND " | 1820 | elif len(d.value): |
| 1771 | self.where_clause += d.value | 1821 | if len(vars.where_clause): |
| 1772 | if len(self.where_clause): | 1822 | vars.where_clause += " AND " |
| 1773 | self.where_clause = " AND ( " + self.where_clause + " ) " | 1823 | vars.where_clause += d.value |
| 1774 | else: | 1824 | if len(vars.where_clause): |
| 1775 | self.ShowMessage("No selection") | 1825 | if self.partial: |
| 1776 | return | 1826 | vars.where_clause = " AND ( " + vars.where_clause + " ) " |
| 1827 | else: | ||
| 1828 | vars.where_clause = " WHERE " + vars.where_clause + " " | ||
| 1777 | self.accept() | 1829 | self.accept() |
| 1778 | 1830 | ||
| 1779 | def ShowMessage(self, msg): | 1831 | def ShowMessage(self, msg): |
| @@ -1782,6 +1834,23 @@ class SelectedBranchDialog(QDialog): | |||
| 1782 | def ClearMessage(self): | 1834 | def ClearMessage(self): |
| 1783 | self.status.setText("") | 1835 | self.status.setText("") |
| 1784 | 1836 | ||
| 1837 | # Selected branch report creation dialog | ||
| 1838 | |||
| 1839 | class SelectedBranchDialog(ReportDialogBase): | ||
| 1840 | |||
| 1841 | def __init__(self, glb, parent=None): | ||
| 1842 | title = "Selected Branches" | ||
| 1843 | items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"), | ||
| 1844 | lambda g, p: SampleTimeRangesDataItem(g, "Time ranges:", "Enter time ranges", "samples.id", p), | ||
| 1845 | lambda g, p: NonNegativeIntegerRangesDataItem(g, "CPUs:", "Enter CPUs or ranges e.g. 0,5-6", "cpu", p), | ||
| 1846 | lambda g, p: SQLTableDataItem(g, "Commands:", "Only branches with these commands will be included", "comms", "comm", "comm_id", "", p), | ||
| 1847 | lambda g, p: SQLTableDataItem(g, "PIDs:", "Only branches with these process IDs will be included", "threads", "pid", "thread_id", "", p), | ||
| 1848 | lambda g, p: SQLTableDataItem(g, "TIDs:", "Only branches with these thread IDs will be included", "threads", "tid", "thread_id", "", p), | ||
| 1849 | lambda g, p: SQLTableDataItem(g, "DSOs:", "Only branches with these DSOs will be included", "dsos", "short_name", "samples.dso_id", "to_dso_id", p), | ||
| 1850 | lambda g, p: SQLTableDataItem(g, "Symbols:", "Only branches with these symbols will be included", "symbols", "name", "symbol_id", "to_symbol_id", p), | ||
| 1851 | lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p)) | ||
| 1852 | super(SelectedBranchDialog, self).__init__(glb, title, items, True, parent) | ||
| 1853 | |||
| 1785 | # Event list | 1854 | # Event list |
| 1786 | 1855 | ||
| 1787 | def GetEventList(db): | 1856 | def GetEventList(db): |
| @@ -1792,6 +1861,16 @@ def GetEventList(db): | |||
| 1792 | events.append(query.value(0)) | 1861 | events.append(query.value(0)) |
| 1793 | return events | 1862 | return events |
| 1794 | 1863 | ||
| 1864 | # Is a table selectable | ||
| 1865 | |||
| 1866 | def IsSelectable(db, table): | ||
| 1867 | query = QSqlQuery(db) | ||
| 1868 | try: | ||
| 1869 | QueryExec(query, "SELECT * FROM " + table + " LIMIT 1") | ||
| 1870 | except: | ||
| 1871 | return False | ||
| 1872 | return True | ||
| 1873 | |||
| 1795 | # SQL data preparation | 1874 | # SQL data preparation |
| 1796 | 1875 | ||
| 1797 | def SQLTableDataPrep(query, count): | 1876 | def SQLTableDataPrep(query, count): |
| @@ -1817,12 +1896,13 @@ class SQLTableModel(TableModel): | |||
| 1817 | 1896 | ||
| 1818 | progress = Signal(object) | 1897 | progress = Signal(object) |
| 1819 | 1898 | ||
| 1820 | def __init__(self, glb, sql, column_count, parent=None): | 1899 | def __init__(self, glb, sql, column_headers, parent=None): |
| 1821 | super(SQLTableModel, self).__init__(parent) | 1900 | super(SQLTableModel, self).__init__(parent) |
| 1822 | self.glb = glb | 1901 | self.glb = glb |
| 1823 | self.more = True | 1902 | self.more = True |
| 1824 | self.populated = 0 | 1903 | self.populated = 0 |
| 1825 | self.fetcher = SQLFetcher(glb, sql, lambda x, y=column_count: SQLTableDataPrep(x, y), self.AddSample) | 1904 | self.column_headers = column_headers |
| 1905 | self.fetcher = SQLFetcher(glb, sql, lambda x, y=len(column_headers): SQLTableDataPrep(x, y), self.AddSample) | ||
| 1826 | self.fetcher.done.connect(self.Update) | 1906 | self.fetcher.done.connect(self.Update) |
| 1827 | self.fetcher.Fetch(glb_chunk_sz) | 1907 | self.fetcher.Fetch(glb_chunk_sz) |
| 1828 | 1908 | ||
| @@ -1860,6 +1940,12 @@ class SQLTableModel(TableModel): | |||
| 1860 | def HasMoreRecords(self): | 1940 | def HasMoreRecords(self): |
| 1861 | return self.more | 1941 | return self.more |
| 1862 | 1942 | ||
| 1943 | def columnCount(self, parent=None): | ||
| 1944 | return len(self.column_headers) | ||
| 1945 | |||
| 1946 | def columnHeader(self, column): | ||
| 1947 | return self.column_headers[column] | ||
| 1948 | |||
| 1863 | # SQL automatic table data model | 1949 | # SQL automatic table data model |
| 1864 | 1950 | ||
| 1865 | class SQLAutoTableModel(SQLTableModel): | 1951 | class SQLAutoTableModel(SQLTableModel): |
| @@ -1869,12 +1955,12 @@ class SQLAutoTableModel(SQLTableModel): | |||
| 1869 | if table_name == "comm_threads_view": | 1955 | if table_name == "comm_threads_view": |
| 1870 | # For now, comm_threads_view has no id column | 1956 | # For now, comm_threads_view has no id column |
| 1871 | sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz) | 1957 | sql = "SELECT * FROM " + table_name + " WHERE comm_id > $$last_id$$ ORDER BY comm_id LIMIT " + str(glb_chunk_sz) |
| 1872 | self.column_headers = [] | 1958 | column_headers = [] |
| 1873 | query = QSqlQuery(glb.db) | 1959 | query = QSqlQuery(glb.db) |
| 1874 | if glb.dbref.is_sqlite3: | 1960 | if glb.dbref.is_sqlite3: |
| 1875 | QueryExec(query, "PRAGMA table_info(" + table_name + ")") | 1961 | QueryExec(query, "PRAGMA table_info(" + table_name + ")") |
| 1876 | while query.next(): | 1962 | while query.next(): |
| 1877 | self.column_headers.append(query.value(1)) | 1963 | column_headers.append(query.value(1)) |
| 1878 | if table_name == "sqlite_master": | 1964 | if table_name == "sqlite_master": |
| 1879 | sql = "SELECT * FROM " + table_name | 1965 | sql = "SELECT * FROM " + table_name |
| 1880 | else: | 1966 | else: |
| @@ -1887,14 +1973,8 @@ class SQLAutoTableModel(SQLTableModel): | |||
| 1887 | schema = "public" | 1973 | schema = "public" |
| 1888 | QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'") | 1974 | QueryExec(query, "SELECT column_name FROM information_schema.columns WHERE table_schema = '" + schema + "' and table_name = '" + select_table_name + "'") |
| 1889 | while query.next(): | 1975 | while query.next(): |
| 1890 | self.column_headers.append(query.value(0)) | 1976 | column_headers.append(query.value(0)) |
| 1891 | super(SQLAutoTableModel, self).__init__(glb, sql, len(self.column_headers), parent) | 1977 | super(SQLAutoTableModel, self).__init__(glb, sql, column_headers, parent) |
| 1892 | |||
| 1893 | def columnCount(self, parent=None): | ||
| 1894 | return len(self.column_headers) | ||
| 1895 | |||
| 1896 | def columnHeader(self, column): | ||
| 1897 | return self.column_headers[column] | ||
| 1898 | 1978 | ||
| 1899 | # Base class for custom ResizeColumnsToContents | 1979 | # Base class for custom ResizeColumnsToContents |
| 1900 | 1980 | ||
| @@ -1997,6 +2077,103 @@ def GetTableList(glb): | |||
| 1997 | tables.append("information_schema.columns") | 2077 | tables.append("information_schema.columns") |
| 1998 | return tables | 2078 | return tables |
| 1999 | 2079 | ||
| 2080 | # Top Calls data model | ||
| 2081 | |||
| 2082 | class TopCallsModel(SQLTableModel): | ||
| 2083 | |||
| 2084 | def __init__(self, glb, report_vars, parent=None): | ||
| 2085 | text = "" | ||
| 2086 | if not glb.dbref.is_sqlite3: | ||
| 2087 | text = "::text" | ||
| 2088 | limit = "" | ||
| 2089 | if len(report_vars.limit): | ||
| 2090 | limit = " LIMIT " + report_vars.limit | ||
| 2091 | sql = ("SELECT comm, pid, tid, name," | ||
| 2092 | " CASE" | ||
| 2093 | " WHEN (short_name = '[kernel.kallsyms]') THEN '[kernel]'" + text + | ||
| 2094 | " ELSE short_name" | ||
| 2095 | " END AS dso," | ||
| 2096 | " call_time, return_time, (return_time - call_time) AS elapsed_time, branch_count, " | ||
| 2097 | " CASE" | ||
| 2098 | " WHEN (calls.flags = 1) THEN 'no call'" + text + | ||
| 2099 | " WHEN (calls.flags = 2) THEN 'no return'" + text + | ||
| 2100 | " WHEN (calls.flags = 3) THEN 'no call/return'" + text + | ||
| 2101 | " ELSE ''" + text + | ||
| 2102 | " END AS flags" | ||
| 2103 | " FROM calls" | ||
| 2104 | " INNER JOIN call_paths ON calls.call_path_id = call_paths.id" | ||
| 2105 | " INNER JOIN symbols ON call_paths.symbol_id = symbols.id" | ||
| 2106 | " INNER JOIN dsos ON symbols.dso_id = dsos.id" | ||
| 2107 | " INNER JOIN comms ON calls.comm_id = comms.id" | ||
| 2108 | " INNER JOIN threads ON calls.thread_id = threads.id" + | ||
| 2109 | report_vars.where_clause + | ||
| 2110 | " ORDER BY elapsed_time DESC" + | ||
| 2111 | limit | ||
| 2112 | ) | ||
| 2113 | column_headers = ("Command", "PID", "TID", "Symbol", "Object", "Call Time", "Return Time", "Elapsed Time (ns)", "Branch Count", "Flags") | ||
| 2114 | self.alignment = (Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignLeft, Qt.AlignRight, Qt.AlignRight, Qt.AlignLeft) | ||
| 2115 | super(TopCallsModel, self).__init__(glb, sql, column_headers, parent) | ||
| 2116 | |||
| 2117 | def columnAlignment(self, column): | ||
| 2118 | return self.alignment[column] | ||
| 2119 | |||
| 2120 | # Top Calls report creation dialog | ||
| 2121 | |||
| 2122 | class TopCallsDialog(ReportDialogBase): | ||
| 2123 | |||
| 2124 | def __init__(self, glb, parent=None): | ||
| 2125 | title = "Top Calls by Elapsed Time" | ||
| 2126 | items = (lambda g, p: LineEditDataItem(g, "Report name:", "Enter a name to appear in the window title bar", p, "REPORTNAME"), | ||
| 2127 | lambda g, p: SQLTableDataItem(g, "Commands:", "Only calls with these commands will be included", "comms", "comm", "comm_id", "", p), | ||
| 2128 | lambda g, p: SQLTableDataItem(g, "PIDs:", "Only calls with these process IDs will be included", "threads", "pid", "thread_id", "", p), | ||
| 2129 | lambda g, p: SQLTableDataItem(g, "TIDs:", "Only calls with these thread IDs will be included", "threads", "tid", "thread_id", "", p), | ||
| 2130 | lambda g, p: SQLTableDataItem(g, "DSOs:", "Only calls with these DSOs will be included", "dsos", "short_name", "dso_id", "", p), | ||
| 2131 | lambda g, p: SQLTableDataItem(g, "Symbols:", "Only calls with these symbols will be included", "symbols", "name", "symbol_id", "", p), | ||
| 2132 | lambda g, p: LineEditDataItem(g, "Raw SQL clause: ", "Enter a raw SQL WHERE clause", p), | ||
| 2133 | lambda g, p: PositiveIntegerDataItem(g, "Record limit:", "Limit selection to this number of records", p, "LIMIT", "100")) | ||
| 2134 | super(TopCallsDialog, self).__init__(glb, title, items, False, parent) | ||
| 2135 | |||
| 2136 | # Top Calls window | ||
| 2137 | |||
| 2138 | class TopCallsWindow(QMdiSubWindow, ResizeColumnsToContentsBase): | ||
| 2139 | |||
| 2140 | def __init__(self, glb, report_vars, parent=None): | ||
| 2141 | super(TopCallsWindow, self).__init__(parent) | ||
| 2142 | |||
| 2143 | self.data_model = LookupCreateModel("Top Calls " + report_vars.UniqueId(), lambda: TopCallsModel(glb, report_vars)) | ||
| 2144 | self.model = self.data_model | ||
| 2145 | |||
| 2146 | self.view = QTableView() | ||
| 2147 | self.view.setModel(self.model) | ||
| 2148 | self.view.setEditTriggers(QAbstractItemView.NoEditTriggers) | ||
| 2149 | self.view.verticalHeader().setVisible(False) | ||
| 2150 | |||
| 2151 | self.ResizeColumnsToContents() | ||
| 2152 | |||
| 2153 | self.find_bar = FindBar(self, self, True) | ||
| 2154 | |||
| 2155 | self.finder = ChildDataItemFinder(self.model) | ||
| 2156 | |||
| 2157 | self.fetch_bar = FetchMoreRecordsBar(self.data_model, self) | ||
| 2158 | |||
| 2159 | self.vbox = VBox(self.view, self.find_bar.Widget(), self.fetch_bar.Widget()) | ||
| 2160 | |||
| 2161 | self.setWidget(self.vbox.Widget()) | ||
| 2162 | |||
| 2163 | AddSubWindow(glb.mainwindow.mdi_area, self, report_vars.name) | ||
| 2164 | |||
| 2165 | def Find(self, value, direction, pattern, context): | ||
| 2166 | self.view.setFocus() | ||
| 2167 | self.find_bar.Busy() | ||
| 2168 | self.finder.Find(value, direction, pattern, context, self.FindDone) | ||
| 2169 | |||
| 2170 | def FindDone(self, row): | ||
| 2171 | self.find_bar.Idle() | ||
| 2172 | if row >= 0: | ||
| 2173 | self.view.setCurrentIndex(self.model.index(row, 0, QModelIndex())) | ||
| 2174 | else: | ||
| 2175 | self.find_bar.NotFound() | ||
| 2176 | |||
| 2000 | # Action Definition | 2177 | # Action Definition |
| 2001 | 2178 | ||
| 2002 | def CreateAction(label, tip, callback, parent=None, shortcut=None): | 2179 | def CreateAction(label, tip, callback, parent=None, shortcut=None): |
| @@ -2100,6 +2277,7 @@ p.c2 { | |||
| 2100 | <p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p> | 2277 | <p class=c2><a href=#callgraph>1.1 Context-Sensitive Call Graph</a></p> |
| 2101 | <p class=c2><a href=#allbranches>1.2 All branches</a></p> | 2278 | <p class=c2><a href=#allbranches>1.2 All branches</a></p> |
| 2102 | <p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> | 2279 | <p class=c2><a href=#selectedbranches>1.3 Selected branches</a></p> |
| 2280 | <p class=c2><a href=#topcallsbyelapsedtime>1.4 Top calls by elapsed time</a></p> | ||
| 2103 | <p class=c1><a href=#tables>2. Tables</a></p> | 2281 | <p class=c1><a href=#tables>2. Tables</a></p> |
| 2104 | <h1 id=reports>1. Reports</h1> | 2282 | <h1 id=reports>1. Reports</h1> |
| 2105 | <h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> | 2283 | <h2 id=callgraph>1.1 Context-Sensitive Call Graph</h2> |
| @@ -2175,6 +2353,10 @@ ms, us or ns. Also, negative values are relative to the end of trace. Examples: | |||
| 2175 | -10ms- The last 10ms | 2353 | -10ms- The last 10ms |
| 2176 | </pre> | 2354 | </pre> |
| 2177 | N.B. Due to the granularity of timestamps, there could be no branches in any given time range. | 2355 | N.B. Due to the granularity of timestamps, there could be no branches in any given time range. |
| 2356 | <h2 id=topcallsbyelapsedtime>1.4 Top calls by elapsed time</h2> | ||
| 2357 | The Top calls by elapsed time report displays calls in descending order of time elapsed between when the function was called and when it returned. | ||
| 2358 | The data is reduced by various selection criteria. A dialog box displays available criteria which are AND'ed together. | ||
| 2359 | If not all data is fetched, a Fetch bar is provided. Ctrl-F displays a Find bar. | ||
| 2178 | <h1 id=tables>2. Tables</h1> | 2360 | <h1 id=tables>2. Tables</h1> |
| 2179 | The Tables menu shows all tables and views in the database. Most tables have an associated view | 2361 | The Tables menu shows all tables and views in the database. Most tables have an associated view |
| 2180 | which displays the information in a more friendly way. Not all data for large tables is fetched | 2362 | which displays the information in a more friendly way. Not all data for large tables is fetched |
| @@ -2304,10 +2486,14 @@ class MainWindow(QMainWindow): | |||
| 2304 | edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")])) | 2486 | edit_menu.addAction(CreateAction("&Enlarge Font", "Make text bigger", self.EnlargeFont, self, [QKeySequence("Ctrl++")])) |
| 2305 | 2487 | ||
| 2306 | reports_menu = menu.addMenu("&Reports") | 2488 | reports_menu = menu.addMenu("&Reports") |
| 2307 | reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) | 2489 | if IsSelectable(glb.db, "calls"): |
| 2490 | reports_menu.addAction(CreateAction("Context-Sensitive Call &Graph", "Create a new window containing a context-sensitive call graph", self.NewCallGraph, self)) | ||
| 2308 | 2491 | ||
| 2309 | self.EventMenu(GetEventList(glb.db), reports_menu) | 2492 | self.EventMenu(GetEventList(glb.db), reports_menu) |
| 2310 | 2493 | ||
| 2494 | if IsSelectable(glb.db, "calls"): | ||
| 2495 | reports_menu.addAction(CreateAction("&Top calls by elapsed time", "Create a new window displaying top calls by elapsed time", self.NewTopCalls, self)) | ||
| 2496 | |||
| 2311 | self.TableMenu(GetTableList(glb), menu) | 2497 | self.TableMenu(GetTableList(glb), menu) |
| 2312 | 2498 | ||
| 2313 | self.window_menu = WindowMenu(self.mdi_area, menu) | 2499 | self.window_menu = WindowMenu(self.mdi_area, menu) |
| @@ -2363,14 +2549,20 @@ class MainWindow(QMainWindow): | |||
| 2363 | def NewCallGraph(self): | 2549 | def NewCallGraph(self): |
| 2364 | CallGraphWindow(self.glb, self) | 2550 | CallGraphWindow(self.glb, self) |
| 2365 | 2551 | ||
| 2552 | def NewTopCalls(self): | ||
| 2553 | dialog = TopCallsDialog(self.glb, self) | ||
| 2554 | ret = dialog.exec_() | ||
| 2555 | if ret: | ||
| 2556 | TopCallsWindow(self.glb, dialog.report_vars, self) | ||
| 2557 | |||
| 2366 | def NewBranchView(self, event_id): | 2558 | def NewBranchView(self, event_id): |
| 2367 | BranchWindow(self.glb, event_id, "", "", self) | 2559 | BranchWindow(self.glb, event_id, ReportVars(), self) |
| 2368 | 2560 | ||
| 2369 | def NewSelectedBranchView(self, event_id): | 2561 | def NewSelectedBranchView(self, event_id): |
| 2370 | dialog = SelectedBranchDialog(self.glb, self) | 2562 | dialog = SelectedBranchDialog(self.glb, self) |
| 2371 | ret = dialog.exec_() | 2563 | ret = dialog.exec_() |
| 2372 | if ret: | 2564 | if ret: |
| 2373 | BranchWindow(self.glb, event_id, dialog.name, dialog.where_clause, self) | 2565 | BranchWindow(self.glb, event_id, dialog.report_vars, self) |
| 2374 | 2566 | ||
| 2375 | def NewTableView(self, table_name): | 2567 | def NewTableView(self, table_name): |
| 2376 | TableWindow(self.glb, table_name, self) | 2568 | TableWindow(self.glb, table_name, self) |
diff --git a/tools/perf/scripts/python/failed-syscalls-by-pid.py b/tools/perf/scripts/python/failed-syscalls-by-pid.py index cafeff3d74db..3648e8b986ec 100644 --- a/tools/perf/scripts/python/failed-syscalls-by-pid.py +++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | # Displays system-wide failed system call totals, broken down by pid. | 5 | # Displays system-wide failed system call totals, broken down by pid. |
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. |
| 7 | 7 | ||
| 8 | from __future__ import print_function | ||
| 9 | |||
| 8 | import os | 10 | import os |
| 9 | import sys | 11 | import sys |
| 10 | 12 | ||
| @@ -32,7 +34,7 @@ if len(sys.argv) > 1: | |||
| 32 | syscalls = autodict() | 34 | syscalls = autodict() |
| 33 | 35 | ||
| 34 | def trace_begin(): | 36 | def trace_begin(): |
| 35 | print "Press control+C to stop and show the summary" | 37 | print("Press control+C to stop and show the summary") |
| 36 | 38 | ||
| 37 | def trace_end(): | 39 | def trace_end(): |
| 38 | print_error_totals() | 40 | print_error_totals() |
| @@ -57,22 +59,21 @@ def syscalls__sys_exit(event_name, context, common_cpu, | |||
| 57 | 59 | ||
| 58 | def print_error_totals(): | 60 | def print_error_totals(): |
| 59 | if for_comm is not None: | 61 | if for_comm is not None: |
| 60 | print "\nsyscall errors for %s:\n\n" % (for_comm), | 62 | print("\nsyscall errors for %s:\n" % (for_comm)) |
| 61 | else: | 63 | else: |
| 62 | print "\nsyscall errors:\n\n", | 64 | print("\nsyscall errors:\n") |
| 63 | 65 | ||
| 64 | print "%-30s %10s\n" % ("comm [pid]", "count"), | 66 | print("%-30s %10s" % ("comm [pid]", "count")) |
| 65 | print "%-30s %10s\n" % ("------------------------------", \ | 67 | print("%-30s %10s" % ("------------------------------", "----------")) |
| 66 | "----------"), | ||
| 67 | 68 | ||
| 68 | comm_keys = syscalls.keys() | 69 | comm_keys = syscalls.keys() |
| 69 | for comm in comm_keys: | 70 | for comm in comm_keys: |
| 70 | pid_keys = syscalls[comm].keys() | 71 | pid_keys = syscalls[comm].keys() |
| 71 | for pid in pid_keys: | 72 | for pid in pid_keys: |
| 72 | print "\n%s [%d]\n" % (comm, pid), | 73 | print("\n%s [%d]" % (comm, pid)) |
| 73 | id_keys = syscalls[comm][pid].keys() | 74 | id_keys = syscalls[comm][pid].keys() |
| 74 | for id in id_keys: | 75 | for id in id_keys: |
| 75 | print " syscall: %-16s\n" % syscall_name(id), | 76 | print(" syscall: %-16s" % syscall_name(id)) |
| 76 | ret_keys = syscalls[comm][pid][id].keys() | 77 | ret_keys = syscalls[comm][pid][id].keys() |
| 77 | for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True): | 78 | for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True): |
| 78 | print " err = %-20s %10d\n" % (strerror(ret), val), | 79 | print(" err = %-20s %10d" % (strerror(ret), val)) |
diff --git a/tools/perf/scripts/python/mem-phys-addr.py b/tools/perf/scripts/python/mem-phys-addr.py index ebee2c5ae496..fb0bbcbfa0f0 100644 --- a/tools/perf/scripts/python/mem-phys-addr.py +++ b/tools/perf/scripts/python/mem-phys-addr.py | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | # Copyright (c) 2018, Intel Corporation. | 4 | # Copyright (c) 2018, Intel Corporation. |
| 5 | 5 | ||
| 6 | from __future__ import division | 6 | from __future__ import division |
| 7 | from __future__ import print_function | ||
| 8 | |||
| 7 | import os | 9 | import os |
| 8 | import sys | 10 | import sys |
| 9 | import struct | 11 | import struct |
| @@ -31,21 +33,23 @@ def parse_iomem(): | |||
| 31 | for i, j in enumerate(f): | 33 | for i, j in enumerate(f): |
| 32 | m = re.split('-|:',j,2) | 34 | m = re.split('-|:',j,2) |
| 33 | if m[2].strip() == 'System RAM': | 35 | if m[2].strip() == 'System RAM': |
| 34 | system_ram.append(long(m[0], 16)) | 36 | system_ram.append(int(m[0], 16)) |
| 35 | system_ram.append(long(m[1], 16)) | 37 | system_ram.append(int(m[1], 16)) |
| 36 | if m[2].strip() == 'Persistent Memory': | 38 | if m[2].strip() == 'Persistent Memory': |
| 37 | pmem.append(long(m[0], 16)) | 39 | pmem.append(int(m[0], 16)) |
| 38 | pmem.append(long(m[1], 16)) | 40 | pmem.append(int(m[1], 16)) |
| 39 | 41 | ||
| 40 | def print_memory_type(): | 42 | def print_memory_type(): |
| 41 | print "Event: %s" % (event_name) | 43 | print("Event: %s" % (event_name)) |
| 42 | print "%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), | 44 | print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='') |
| 43 | print "%-40s %10s %10s\n" % ("----------------------------------------", \ | 45 | print("%-40s %10s %10s\n" % ("----------------------------------------", |
| 44 | "-----------", "-----------"), | 46 | "-----------", "-----------"), |
| 47 | end=''); | ||
| 45 | total = sum(load_mem_type_cnt.values()) | 48 | total = sum(load_mem_type_cnt.values()) |
| 46 | for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ | 49 | for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ |
| 47 | key = lambda(k, v): (v, k), reverse = True): | 50 | key = lambda kv: (kv[1], kv[0]), reverse = True): |
| 48 | print "%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), | 51 | print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), |
| 52 | end='') | ||
| 49 | 53 | ||
| 50 | def trace_begin(): | 54 | def trace_begin(): |
| 51 | parse_iomem() | 55 | parse_iomem() |
| @@ -80,7 +84,7 @@ def find_memory_type(phys_addr): | |||
| 80 | f.seek(0, 0) | 84 | f.seek(0, 0) |
| 81 | for j in f: | 85 | for j in f: |
| 82 | m = re.split('-|:',j,2) | 86 | m = re.split('-|:',j,2) |
| 83 | if long(m[0], 16) <= phys_addr <= long(m[1], 16): | 87 | if int(m[0], 16) <= phys_addr <= int(m[1], 16): |
| 84 | return m[2] | 88 | return m[2] |
| 85 | return "N/A" | 89 | return "N/A" |
| 86 | 90 | ||
diff --git a/tools/perf/scripts/python/net_dropmonitor.py b/tools/perf/scripts/python/net_dropmonitor.py index a150164b44a3..212557a02c50 100755 --- a/tools/perf/scripts/python/net_dropmonitor.py +++ b/tools/perf/scripts/python/net_dropmonitor.py | |||
| @@ -1,6 +1,8 @@ | |||
| 1 | # Monitor the system for dropped packets and proudce a report of drop locations and counts | 1 | # Monitor the system for dropped packets and proudce a report of drop locations and counts |
| 2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | 3 | ||
| 4 | from __future__ import print_function | ||
| 5 | |||
| 4 | import os | 6 | import os |
| 5 | import sys | 7 | import sys |
| 6 | 8 | ||
| @@ -50,19 +52,19 @@ def get_sym(sloc): | |||
| 50 | return (None, 0) | 52 | return (None, 0) |
| 51 | 53 | ||
| 52 | def print_drop_table(): | 54 | def print_drop_table(): |
| 53 | print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") | 55 | print("%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")) |
| 54 | for i in drop_log.keys(): | 56 | for i in drop_log.keys(): |
| 55 | (sym, off) = get_sym(i) | 57 | (sym, off) = get_sym(i) |
| 56 | if sym == None: | 58 | if sym == None: |
| 57 | sym = i | 59 | sym = i |
| 58 | print "%25s %25s %25s" % (sym, off, drop_log[i]) | 60 | print("%25s %25s %25s" % (sym, off, drop_log[i])) |
| 59 | 61 | ||
| 60 | 62 | ||
| 61 | def trace_begin(): | 63 | def trace_begin(): |
| 62 | print "Starting trace (Ctrl-C to dump results)" | 64 | print("Starting trace (Ctrl-C to dump results)") |
| 63 | 65 | ||
| 64 | def trace_end(): | 66 | def trace_end(): |
| 65 | print "Gathering kallsyms data" | 67 | print("Gathering kallsyms data") |
| 66 | get_kallsyms_table() | 68 | get_kallsyms_table() |
| 67 | print_drop_table() | 69 | print_drop_table() |
| 68 | 70 | ||
diff --git a/tools/perf/scripts/python/netdev-times.py b/tools/perf/scripts/python/netdev-times.py index 9b2050f778f1..267bda49325d 100644 --- a/tools/perf/scripts/python/netdev-times.py +++ b/tools/perf/scripts/python/netdev-times.py | |||
| @@ -8,6 +8,8 @@ | |||
| 8 | # dev=: show only thing related to specified device | 8 | # dev=: show only thing related to specified device |
| 9 | # debug: work with debug mode. It shows buffer status. | 9 | # debug: work with debug mode. It shows buffer status. |
| 10 | 10 | ||
| 11 | from __future__ import print_function | ||
| 12 | |||
| 11 | import os | 13 | import os |
| 12 | import sys | 14 | import sys |
| 13 | 15 | ||
| @@ -17,6 +19,7 @@ sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | |||
| 17 | from perf_trace_context import * | 19 | from perf_trace_context import * |
| 18 | from Core import * | 20 | from Core import * |
| 19 | from Util import * | 21 | from Util import * |
| 22 | from functools import cmp_to_key | ||
| 20 | 23 | ||
| 21 | all_event_list = []; # insert all tracepoint event related with this script | 24 | all_event_list = []; # insert all tracepoint event related with this script |
| 22 | irq_dic = {}; # key is cpu and value is a list which stacks irqs | 25 | irq_dic = {}; # key is cpu and value is a list which stacks irqs |
| @@ -61,12 +64,12 @@ def diff_msec(src, dst): | |||
| 61 | def print_transmit(hunk): | 64 | def print_transmit(hunk): |
| 62 | if dev != 0 and hunk['dev'].find(dev) < 0: | 65 | if dev != 0 and hunk['dev'].find(dev) < 0: |
| 63 | return | 66 | return |
| 64 | print "%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % \ | 67 | print("%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % |
| 65 | (hunk['dev'], hunk['len'], | 68 | (hunk['dev'], hunk['len'], |
| 66 | nsecs_secs(hunk['queue_t']), | 69 | nsecs_secs(hunk['queue_t']), |
| 67 | nsecs_nsecs(hunk['queue_t'])/1000, | 70 | nsecs_nsecs(hunk['queue_t'])/1000, |
| 68 | diff_msec(hunk['queue_t'], hunk['xmit_t']), | 71 | diff_msec(hunk['queue_t'], hunk['xmit_t']), |
| 69 | diff_msec(hunk['xmit_t'], hunk['free_t'])) | 72 | diff_msec(hunk['xmit_t'], hunk['free_t']))) |
| 70 | 73 | ||
| 71 | # Format for displaying rx packet processing | 74 | # Format for displaying rx packet processing |
| 72 | PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)" | 75 | PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)" |
| @@ -98,55 +101,55 @@ def print_receive(hunk): | |||
| 98 | if show_hunk == 0: | 101 | if show_hunk == 0: |
| 99 | return | 102 | return |
| 100 | 103 | ||
| 101 | print "%d.%06dsec cpu=%d" % \ | 104 | print("%d.%06dsec cpu=%d" % |
| 102 | (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu) | 105 | (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu)) |
| 103 | for i in range(len(irq_list)): | 106 | for i in range(len(irq_list)): |
| 104 | print PF_IRQ_ENTRY % \ | 107 | print(PF_IRQ_ENTRY % |
| 105 | (diff_msec(base_t, irq_list[i]['irq_ent_t']), | 108 | (diff_msec(base_t, irq_list[i]['irq_ent_t']), |
| 106 | irq_list[i]['irq'], irq_list[i]['name']) | 109 | irq_list[i]['irq'], irq_list[i]['name'])) |
| 107 | print PF_JOINT | 110 | print(PF_JOINT) |
| 108 | irq_event_list = irq_list[i]['event_list'] | 111 | irq_event_list = irq_list[i]['event_list'] |
| 109 | for j in range(len(irq_event_list)): | 112 | for j in range(len(irq_event_list)): |
| 110 | irq_event = irq_event_list[j] | 113 | irq_event = irq_event_list[j] |
| 111 | if irq_event['event'] == 'netif_rx': | 114 | if irq_event['event'] == 'netif_rx': |
| 112 | print PF_NET_RX % \ | 115 | print(PF_NET_RX % |
| 113 | (diff_msec(base_t, irq_event['time']), | 116 | (diff_msec(base_t, irq_event['time']), |
| 114 | irq_event['skbaddr']) | 117 | irq_event['skbaddr'])) |
| 115 | print PF_JOINT | 118 | print(PF_JOINT) |
| 116 | print PF_SOFT_ENTRY % \ | 119 | print(PF_SOFT_ENTRY % |
| 117 | diff_msec(base_t, hunk['sirq_ent_t']) | 120 | diff_msec(base_t, hunk['sirq_ent_t'])) |
| 118 | print PF_JOINT | 121 | print(PF_JOINT) |
| 119 | event_list = hunk['event_list'] | 122 | event_list = hunk['event_list'] |
| 120 | for i in range(len(event_list)): | 123 | for i in range(len(event_list)): |
| 121 | event = event_list[i] | 124 | event = event_list[i] |
| 122 | if event['event_name'] == 'napi_poll': | 125 | if event['event_name'] == 'napi_poll': |
| 123 | print PF_NAPI_POLL % \ | 126 | print(PF_NAPI_POLL % |
| 124 | (diff_msec(base_t, event['event_t']), event['dev']) | 127 | (diff_msec(base_t, event['event_t']), event['dev'])) |
| 125 | if i == len(event_list) - 1: | 128 | if i == len(event_list) - 1: |
| 126 | print "" | 129 | print("") |
| 127 | else: | 130 | else: |
| 128 | print PF_JOINT | 131 | print(PF_JOINT) |
| 129 | else: | 132 | else: |
| 130 | print PF_NET_RECV % \ | 133 | print(PF_NET_RECV % |
| 131 | (diff_msec(base_t, event['event_t']), event['skbaddr'], | 134 | (diff_msec(base_t, event['event_t']), event['skbaddr'], |
| 132 | event['len']) | 135 | event['len'])) |
| 133 | if 'comm' in event.keys(): | 136 | if 'comm' in event.keys(): |
| 134 | print PF_WJOINT | 137 | print(PF_WJOINT) |
| 135 | print PF_CPY_DGRAM % \ | 138 | print(PF_CPY_DGRAM % |
| 136 | (diff_msec(base_t, event['comm_t']), | 139 | (diff_msec(base_t, event['comm_t']), |
| 137 | event['pid'], event['comm']) | 140 | event['pid'], event['comm'])) |
| 138 | elif 'handle' in event.keys(): | 141 | elif 'handle' in event.keys(): |
| 139 | print PF_WJOINT | 142 | print(PF_WJOINT) |
| 140 | if event['handle'] == "kfree_skb": | 143 | if event['handle'] == "kfree_skb": |
| 141 | print PF_KFREE_SKB % \ | 144 | print(PF_KFREE_SKB % |
| 142 | (diff_msec(base_t, | 145 | (diff_msec(base_t, |
| 143 | event['comm_t']), | 146 | event['comm_t']), |
| 144 | event['location']) | 147 | event['location'])) |
| 145 | elif event['handle'] == "consume_skb": | 148 | elif event['handle'] == "consume_skb": |
| 146 | print PF_CONS_SKB % \ | 149 | print(PF_CONS_SKB % |
| 147 | diff_msec(base_t, | 150 | diff_msec(base_t, |
| 148 | event['comm_t']) | 151 | event['comm_t'])) |
| 149 | print PF_JOINT | 152 | print(PF_JOINT) |
| 150 | 153 | ||
| 151 | def trace_begin(): | 154 | def trace_begin(): |
| 152 | global show_tx | 155 | global show_tx |
| @@ -172,8 +175,7 @@ def trace_begin(): | |||
| 172 | 175 | ||
| 173 | def trace_end(): | 176 | def trace_end(): |
| 174 | # order all events in time | 177 | # order all events in time |
| 175 | all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME], | 178 | all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME])) |
| 176 | b[EINFO_IDX_TIME])) | ||
| 177 | # process all events | 179 | # process all events |
| 178 | for i in range(len(all_event_list)): | 180 | for i in range(len(all_event_list)): |
| 179 | event_info = all_event_list[i] | 181 | event_info = all_event_list[i] |
| @@ -210,19 +212,19 @@ def trace_end(): | |||
| 210 | print_receive(receive_hunk_list[i]) | 212 | print_receive(receive_hunk_list[i]) |
| 211 | # display transmit hunks | 213 | # display transmit hunks |
| 212 | if show_tx: | 214 | if show_tx: |
| 213 | print " dev len Qdisc " \ | 215 | print(" dev len Qdisc " |
| 214 | " netdevice free" | 216 | " netdevice free") |
| 215 | for i in range(len(tx_free_list)): | 217 | for i in range(len(tx_free_list)): |
| 216 | print_transmit(tx_free_list[i]) | 218 | print_transmit(tx_free_list[i]) |
| 217 | if debug: | 219 | if debug: |
| 218 | print "debug buffer status" | 220 | print("debug buffer status") |
| 219 | print "----------------------------" | 221 | print("----------------------------") |
| 220 | print "xmit Qdisc:remain:%d overflow:%d" % \ | 222 | print("xmit Qdisc:remain:%d overflow:%d" % |
| 221 | (len(tx_queue_list), of_count_tx_queue_list) | 223 | (len(tx_queue_list), of_count_tx_queue_list)) |
| 222 | print "xmit netdevice:remain:%d overflow:%d" % \ | 224 | print("xmit netdevice:remain:%d overflow:%d" % |
| 223 | (len(tx_xmit_list), of_count_tx_xmit_list) | 225 | (len(tx_xmit_list), of_count_tx_xmit_list)) |
| 224 | print "receive:remain:%d overflow:%d" % \ | 226 | print("receive:remain:%d overflow:%d" % |
| 225 | (len(rx_skb_list), of_count_rx_skb_list) | 227 | (len(rx_skb_list), of_count_rx_skb_list)) |
| 226 | 228 | ||
| 227 | # called from perf, when it finds a correspoinding event | 229 | # called from perf, when it finds a correspoinding event |
| 228 | def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec): | 230 | def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec): |
diff --git a/tools/perf/scripts/python/powerpc-hcalls.py b/tools/perf/scripts/python/powerpc-hcalls.py index 00e0e7476e55..8b78dc790adb 100644 --- a/tools/perf/scripts/python/powerpc-hcalls.py +++ b/tools/perf/scripts/python/powerpc-hcalls.py | |||
| @@ -4,6 +4,8 @@ | |||
| 4 | # | 4 | # |
| 5 | # Hypervisor call statisics | 5 | # Hypervisor call statisics |
| 6 | 6 | ||
| 7 | from __future__ import print_function | ||
| 8 | |||
| 7 | import os | 9 | import os |
| 8 | import sys | 10 | import sys |
| 9 | 11 | ||
| @@ -149,7 +151,7 @@ hcall_table = { | |||
| 149 | } | 151 | } |
| 150 | 152 | ||
| 151 | def hcall_table_lookup(opcode): | 153 | def hcall_table_lookup(opcode): |
| 152 | if (hcall_table.has_key(opcode)): | 154 | if (opcode in hcall_table): |
| 153 | return hcall_table[opcode] | 155 | return hcall_table[opcode] |
| 154 | else: | 156 | else: |
| 155 | return opcode | 157 | return opcode |
| @@ -157,8 +159,8 @@ def hcall_table_lookup(opcode): | |||
| 157 | print_ptrn = '%-28s%10s%10s%10s%10s' | 159 | print_ptrn = '%-28s%10s%10s%10s%10s' |
| 158 | 160 | ||
| 159 | def trace_end(): | 161 | def trace_end(): |
| 160 | print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)') | 162 | print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)')) |
| 161 | print '-' * 68 | 163 | print('-' * 68) |
| 162 | for opcode in output: | 164 | for opcode in output: |
| 163 | h_name = hcall_table_lookup(opcode) | 165 | h_name = hcall_table_lookup(opcode) |
| 164 | time = output[opcode]['time'] | 166 | time = output[opcode]['time'] |
| @@ -166,14 +168,14 @@ def trace_end(): | |||
| 166 | min_t = output[opcode]['min'] | 168 | min_t = output[opcode]['min'] |
| 167 | max_t = output[opcode]['max'] | 169 | max_t = output[opcode]['max'] |
| 168 | 170 | ||
| 169 | print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt) | 171 | print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt)) |
| 170 | 172 | ||
| 171 | def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, | 173 | def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, |
| 172 | opcode, retval): | 174 | opcode, retval): |
| 173 | if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)): | 175 | if (cpu in d_enter and opcode in d_enter[cpu]): |
| 174 | diff = nsecs(sec, nsec) - d_enter[cpu][opcode] | 176 | diff = nsecs(sec, nsec) - d_enter[cpu][opcode] |
| 175 | 177 | ||
| 176 | if (output.has_key(opcode)): | 178 | if (opcode in output): |
| 177 | output[opcode]['time'] += diff | 179 | output[opcode]['time'] += diff |
| 178 | output[opcode]['cnt'] += 1 | 180 | output[opcode]['cnt'] += 1 |
| 179 | if (output[opcode]['min'] > diff): | 181 | if (output[opcode]['min'] > diff): |
| @@ -190,11 +192,11 @@ def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, | |||
| 190 | 192 | ||
| 191 | del d_enter[cpu][opcode] | 193 | del d_enter[cpu][opcode] |
| 192 | # else: | 194 | # else: |
| 193 | # print "Can't find matching hcall_enter event. Ignoring sample" | 195 | # print("Can't find matching hcall_enter event. Ignoring sample") |
| 194 | 196 | ||
| 195 | def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm, | 197 | def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm, |
| 196 | callchain, opcode): | 198 | callchain, opcode): |
| 197 | if (d_enter.has_key(cpu)): | 199 | if (cpu in d_enter): |
| 198 | d_enter[cpu][opcode] = nsecs(sec, nsec) | 200 | d_enter[cpu][opcode] = nsecs(sec, nsec) |
| 199 | else: | 201 | else: |
| 200 | d_enter[cpu] = {opcode: nsecs(sec, nsec)} | 202 | d_enter[cpu] = {opcode: nsecs(sec, nsec)} |
diff --git a/tools/perf/scripts/python/sctop.py b/tools/perf/scripts/python/sctop.py index 61621b93affb..987ffae7c8ca 100644 --- a/tools/perf/scripts/python/sctop.py +++ b/tools/perf/scripts/python/sctop.py | |||
| @@ -8,7 +8,14 @@ | |||
| 8 | # will be refreshed every [interval] seconds. The default interval is | 8 | # will be refreshed every [interval] seconds. The default interval is |
| 9 | # 3 seconds. | 9 | # 3 seconds. |
| 10 | 10 | ||
| 11 | import os, sys, thread, time | 11 | from __future__ import print_function |
| 12 | |||
| 13 | import os, sys, time | ||
| 14 | |||
| 15 | try: | ||
| 16 | import thread | ||
| 17 | except ImportError: | ||
| 18 | import _thread as thread | ||
| 12 | 19 | ||
| 13 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | 20 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ |
| 14 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') | 21 | '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') |
| @@ -62,18 +69,19 @@ def print_syscall_totals(interval): | |||
| 62 | while 1: | 69 | while 1: |
| 63 | clear_term() | 70 | clear_term() |
| 64 | if for_comm is not None: | 71 | if for_comm is not None: |
| 65 | print "\nsyscall events for %s:\n\n" % (for_comm), | 72 | print("\nsyscall events for %s:\n" % (for_comm)) |
| 66 | else: | 73 | else: |
| 67 | print "\nsyscall events:\n\n", | 74 | print("\nsyscall events:\n") |
| 68 | 75 | ||
| 69 | print "%-40s %10s\n" % ("event", "count"), | 76 | print("%-40s %10s" % ("event", "count")) |
| 70 | print "%-40s %10s\n" % ("----------------------------------------", \ | 77 | print("%-40s %10s" % |
| 71 | "----------"), | 78 | ("----------------------------------------", |
| 79 | "----------")) | ||
| 72 | 80 | ||
| 73 | for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ | 81 | for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ |
| 74 | reverse = True): | 82 | reverse = True): |
| 75 | try: | 83 | try: |
| 76 | print "%-40s %10d\n" % (syscall_name(id), val), | 84 | print("%-40s %10d" % (syscall_name(id), val)) |
| 77 | except TypeError: | 85 | except TypeError: |
| 78 | pass | 86 | pass |
| 79 | syscalls.clear() | 87 | syscalls.clear() |
diff --git a/tools/perf/scripts/python/stackcollapse.py b/tools/perf/scripts/python/stackcollapse.py index 1697b5e18c96..5e703efaddcc 100755 --- a/tools/perf/scripts/python/stackcollapse.py +++ b/tools/perf/scripts/python/stackcollapse.py | |||
| @@ -19,6 +19,8 @@ | |||
| 19 | # Written by Paolo Bonzini <pbonzini@redhat.com> | 19 | # Written by Paolo Bonzini <pbonzini@redhat.com> |
| 20 | # Based on Brendan Gregg's stackcollapse-perf.pl script. | 20 | # Based on Brendan Gregg's stackcollapse-perf.pl script. |
| 21 | 21 | ||
| 22 | from __future__ import print_function | ||
| 23 | |||
| 22 | import os | 24 | import os |
| 23 | import sys | 25 | import sys |
| 24 | from collections import defaultdict | 26 | from collections import defaultdict |
| @@ -120,7 +122,6 @@ def process_event(param_dict): | |||
| 120 | lines[stack_string] = lines[stack_string] + 1 | 122 | lines[stack_string] = lines[stack_string] + 1 |
| 121 | 123 | ||
| 122 | def trace_end(): | 124 | def trace_end(): |
| 123 | list = lines.keys() | 125 | list = sorted(lines) |
| 124 | list.sort() | ||
| 125 | for stack in list: | 126 | for stack in list: |
| 126 | print "%s %d" % (stack, lines[stack]) | 127 | print("%s %d" % (stack, lines[stack])) |
diff --git a/tools/perf/scripts/python/stat-cpi.py b/tools/perf/scripts/python/stat-cpi.py index a81ad8835a74..01fa933ff3cf 100644 --- a/tools/perf/scripts/python/stat-cpi.py +++ b/tools/perf/scripts/python/stat-cpi.py | |||
| @@ -1,5 +1,7 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | 2 | ||
| 3 | from __future__ import print_function | ||
| 4 | |||
| 3 | data = {} | 5 | data = {} |
| 4 | times = [] | 6 | times = [] |
| 5 | threads = [] | 7 | threads = [] |
| @@ -19,8 +21,8 @@ def store_key(time, cpu, thread): | |||
| 19 | threads.append(thread) | 21 | threads.append(thread) |
| 20 | 22 | ||
| 21 | def store(time, event, cpu, thread, val, ena, run): | 23 | def store(time, event, cpu, thread, val, ena, run): |
| 22 | #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \ | 24 | #print("event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % |
| 23 | # (event, cpu, thread, time, val, ena, run) | 25 | # (event, cpu, thread, time, val, ena, run)) |
| 24 | 26 | ||
| 25 | store_key(time, cpu, thread) | 27 | store_key(time, cpu, thread) |
| 26 | key = get_key(time, event, cpu, thread) | 28 | key = get_key(time, event, cpu, thread) |
| @@ -58,7 +60,7 @@ def stat__interval(time): | |||
| 58 | if ins != 0: | 60 | if ins != 0: |
| 59 | cpi = cyc/float(ins) | 61 | cpi = cyc/float(ins) |
| 60 | 62 | ||
| 61 | print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins) | 63 | print("%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins)) |
| 62 | 64 | ||
| 63 | def trace_end(): | 65 | def trace_end(): |
| 64 | pass | 66 | pass |
| @@ -74,4 +76,4 @@ def trace_end(): | |||
| 74 | # if ins != 0: | 76 | # if ins != 0: |
| 75 | # cpi = cyc/float(ins) | 77 | # cpi = cyc/float(ins) |
| 76 | # | 78 | # |
| 77 | # print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi) | 79 | # print("time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)) |
diff --git a/tools/perf/scripts/python/syscall-counts-by-pid.py b/tools/perf/scripts/python/syscall-counts-by-pid.py index daf314cc5dd3..42782487b0e9 100644 --- a/tools/perf/scripts/python/syscall-counts-by-pid.py +++ b/tools/perf/scripts/python/syscall-counts-by-pid.py | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | # Displays system-wide system call totals, broken down by syscall. | 5 | # Displays system-wide system call totals, broken down by syscall. |
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. |
| 7 | 7 | ||
| 8 | from __future__ import print_function | ||
| 9 | |||
| 8 | import os, sys | 10 | import os, sys |
| 9 | 11 | ||
| 10 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ | 12 | sys.path.append(os.environ['PERF_EXEC_PATH'] + \ |
| @@ -31,7 +33,7 @@ if len(sys.argv) > 1: | |||
| 31 | syscalls = autodict() | 33 | syscalls = autodict() |
| 32 | 34 | ||
| 33 | def trace_begin(): | 35 | def trace_begin(): |
| 34 | print "Press control+C to stop and show the summary" | 36 | print("Press control+C to stop and show the summary") |
| 35 | 37 | ||
| 36 | def trace_end(): | 38 | def trace_end(): |
| 37 | print_syscall_totals() | 39 | print_syscall_totals() |
| @@ -55,20 +57,20 @@ def syscalls__sys_enter(event_name, context, common_cpu, | |||
| 55 | 57 | ||
| 56 | def print_syscall_totals(): | 58 | def print_syscall_totals(): |
| 57 | if for_comm is not None: | 59 | if for_comm is not None: |
| 58 | print "\nsyscall events for %s:\n\n" % (for_comm), | 60 | print("\nsyscall events for %s:\n" % (for_comm)) |
| 59 | else: | 61 | else: |
| 60 | print "\nsyscall events by comm/pid:\n\n", | 62 | print("\nsyscall events by comm/pid:\n") |
| 61 | 63 | ||
| 62 | print "%-40s %10s\n" % ("comm [pid]/syscalls", "count"), | 64 | print("%-40s %10s" % ("comm [pid]/syscalls", "count")) |
| 63 | print "%-40s %10s\n" % ("----------------------------------------", \ | 65 | print("%-40s %10s" % ("----------------------------------------", |
| 64 | "----------"), | 66 | "----------")) |
| 65 | 67 | ||
| 66 | comm_keys = syscalls.keys() | 68 | comm_keys = syscalls.keys() |
| 67 | for comm in comm_keys: | 69 | for comm in comm_keys: |
| 68 | pid_keys = syscalls[comm].keys() | 70 | pid_keys = syscalls[comm].keys() |
| 69 | for pid in pid_keys: | 71 | for pid in pid_keys: |
| 70 | print "\n%s [%d]\n" % (comm, pid), | 72 | print("\n%s [%d]" % (comm, pid)) |
| 71 | id_keys = syscalls[comm][pid].keys() | 73 | id_keys = syscalls[comm][pid].keys() |
| 72 | for id, val in sorted(syscalls[comm][pid].iteritems(), \ | 74 | for id, val in sorted(syscalls[comm][pid].items(), \ |
| 73 | key = lambda(k, v): (v, k), reverse = True): | 75 | key = lambda kv: (kv[1], kv[0]), reverse = True): |
| 74 | print " %-38s %10d\n" % (syscall_name(id), val), | 76 | print(" %-38s %10d" % (syscall_name(id), val)) |
diff --git a/tools/perf/scripts/python/syscall-counts.py b/tools/perf/scripts/python/syscall-counts.py index e66a7730aeb5..0ebd89cfd42c 100644 --- a/tools/perf/scripts/python/syscall-counts.py +++ b/tools/perf/scripts/python/syscall-counts.py | |||
| @@ -5,6 +5,8 @@ | |||
| 5 | # Displays system-wide system call totals, broken down by syscall. | 5 | # Displays system-wide system call totals, broken down by syscall. |
| 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. | 6 | # If a [comm] arg is specified, only syscalls called by [comm] are displayed. |
| 7 | 7 | ||
| 8 | from __future__ import print_function | ||
| 9 | |||
| 8 | import os | 10 | import os |
| 9 | import sys | 11 | import sys |
| 10 | 12 | ||
| @@ -28,7 +30,7 @@ if len(sys.argv) > 1: | |||
| 28 | syscalls = autodict() | 30 | syscalls = autodict() |
| 29 | 31 | ||
| 30 | def trace_begin(): | 32 | def trace_begin(): |
| 31 | print "Press control+C to stop and show the summary" | 33 | print("Press control+C to stop and show the summary") |
| 32 | 34 | ||
| 33 | def trace_end(): | 35 | def trace_end(): |
| 34 | print_syscall_totals() | 36 | print_syscall_totals() |
| @@ -51,14 +53,14 @@ def syscalls__sys_enter(event_name, context, common_cpu, | |||
| 51 | 53 | ||
| 52 | def print_syscall_totals(): | 54 | def print_syscall_totals(): |
| 53 | if for_comm is not None: | 55 | if for_comm is not None: |
| 54 | print "\nsyscall events for %s:\n\n" % (for_comm), | 56 | print("\nsyscall events for %s:\n" % (for_comm)) |
| 55 | else: | 57 | else: |
| 56 | print "\nsyscall events:\n\n", | 58 | print("\nsyscall events:\n") |
| 57 | 59 | ||
| 58 | print "%-40s %10s\n" % ("event", "count"), | 60 | print("%-40s %10s" % ("event", "count")) |
| 59 | print "%-40s %10s\n" % ("----------------------------------------", \ | 61 | print("%-40s %10s" % ("----------------------------------------", |
| 60 | "-----------"), | 62 | "-----------")) |
| 61 | 63 | ||
| 62 | for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ | 64 | for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ |
| 63 | reverse = True): | 65 | reverse = True): |
| 64 | print "%-40s %10d\n" % (syscall_name(id), val), | 66 | print("%-40s %10d" % (syscall_name(id), val)) |
