diff options
Diffstat (limited to 'tools/perf/util/sort.c')
-rw-r--r-- | tools/perf/util/sort.c | 105 |
1 files changed, 100 insertions, 5 deletions
diff --git a/tools/perf/util/sort.c b/tools/perf/util/sort.c index cc659ba0e232..22d28c7e0b01 100644 --- a/tools/perf/util/sort.c +++ b/tools/perf/util/sort.c | |||
@@ -1560,6 +1560,62 @@ static int hde_width(struct hpp_dynamic_entry *hde) | |||
1560 | return hde->hpp.len; | 1560 | return hde->hpp.len; |
1561 | } | 1561 | } |
1562 | 1562 | ||
1563 | static char *get_trace_output(struct hist_entry *he) | ||
1564 | { | ||
1565 | struct trace_seq seq; | ||
1566 | struct perf_evsel *evsel; | ||
1567 | struct pevent_record rec = { | ||
1568 | .data = he->raw_data, | ||
1569 | .size = he->raw_size, | ||
1570 | }; | ||
1571 | |||
1572 | evsel = hists_to_evsel(he->hists); | ||
1573 | |||
1574 | trace_seq_init(&seq); | ||
1575 | pevent_event_info(&seq, evsel->tp_format, &rec); | ||
1576 | return seq.buffer; | ||
1577 | } | ||
1578 | |||
1579 | static void update_dynamic_len(struct hpp_dynamic_entry *hde, | ||
1580 | struct hist_entry *he) | ||
1581 | { | ||
1582 | char *str, *pos; | ||
1583 | struct format_field *field = hde->field; | ||
1584 | size_t namelen; | ||
1585 | bool last = false; | ||
1586 | |||
1587 | /* parse pretty print result and update max length */ | ||
1588 | if (!he->trace_output) | ||
1589 | he->trace_output = get_trace_output(he); | ||
1590 | |||
1591 | namelen = strlen(field->name); | ||
1592 | str = he->trace_output; | ||
1593 | |||
1594 | while (str) { | ||
1595 | pos = strchr(str, ' '); | ||
1596 | if (pos == NULL) { | ||
1597 | last = true; | ||
1598 | pos = str + strlen(str); | ||
1599 | } | ||
1600 | |||
1601 | if (!strncmp(str, field->name, namelen)) { | ||
1602 | size_t len; | ||
1603 | |||
1604 | str += namelen + 1; | ||
1605 | len = pos - str; | ||
1606 | |||
1607 | if (len > hde->dynamic_len) | ||
1608 | hde->dynamic_len = len; | ||
1609 | break; | ||
1610 | } | ||
1611 | |||
1612 | if (last) | ||
1613 | str = NULL; | ||
1614 | else | ||
1615 | str = pos + 1; | ||
1616 | } | ||
1617 | } | ||
1618 | |||
1563 | static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, | 1619 | static int __sort__hde_header(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, |
1564 | struct perf_evsel *evsel __maybe_unused) | 1620 | struct perf_evsel *evsel __maybe_unused) |
1565 | { | 1621 | { |
@@ -1594,7 +1650,10 @@ static int __sort__hde_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, | |||
1594 | { | 1650 | { |
1595 | struct hpp_dynamic_entry *hde; | 1651 | struct hpp_dynamic_entry *hde; |
1596 | size_t len = fmt->user_len; | 1652 | size_t len = fmt->user_len; |
1597 | struct trace_seq seq; | 1653 | char *str, *pos; |
1654 | struct format_field *field; | ||
1655 | size_t namelen; | ||
1656 | bool last = false; | ||
1598 | int ret; | 1657 | int ret; |
1599 | 1658 | ||
1600 | hde = container_of(fmt, struct hpp_dynamic_entry, hpp); | 1659 | hde = container_of(fmt, struct hpp_dynamic_entry, hpp); |
@@ -1605,10 +1664,43 @@ static int __sort__hde_entry(struct perf_hpp_fmt *fmt, struct perf_hpp *hpp, | |||
1605 | if (hists_to_evsel(he->hists) != hde->evsel) | 1664 | if (hists_to_evsel(he->hists) != hde->evsel) |
1606 | return scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, "N/A"); | 1665 | return scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, "N/A"); |
1607 | 1666 | ||
1608 | trace_seq_init(&seq); | 1667 | field = hde->field; |
1609 | pevent_print_field(&seq, he->raw_data, hde->field); | 1668 | |
1610 | ret = scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, seq.buffer); | 1669 | namelen = strlen(field->name); |
1611 | trace_seq_destroy(&seq); | 1670 | str = he->trace_output; |
1671 | |||
1672 | while (str) { | ||
1673 | pos = strchr(str, ' '); | ||
1674 | if (pos == NULL) { | ||
1675 | last = true; | ||
1676 | pos = str + strlen(str); | ||
1677 | } | ||
1678 | |||
1679 | if (!strncmp(str, field->name, namelen)) { | ||
1680 | str += namelen + 1; | ||
1681 | str = strndup(str, pos - str); | ||
1682 | |||
1683 | if (str == NULL) | ||
1684 | return scnprintf(hpp->buf, hpp->size, | ||
1685 | "%*.*s", len, len, "ERROR"); | ||
1686 | break; | ||
1687 | } | ||
1688 | |||
1689 | if (last) | ||
1690 | str = NULL; | ||
1691 | else | ||
1692 | str = pos + 1; | ||
1693 | } | ||
1694 | |||
1695 | if (str == NULL) { | ||
1696 | struct trace_seq seq; | ||
1697 | trace_seq_init(&seq); | ||
1698 | pevent_print_field(&seq, he->raw_data, hde->field); | ||
1699 | str = seq.buffer; | ||
1700 | } | ||
1701 | |||
1702 | ret = scnprintf(hpp->buf, hpp->size, "%*.*s", len, len, str); | ||
1703 | free(str); | ||
1612 | return ret; | 1704 | return ret; |
1613 | } | 1705 | } |
1614 | 1706 | ||
@@ -1638,6 +1730,9 @@ static int64_t __sort__hde_cmp(struct perf_hpp_fmt *fmt, | |||
1638 | } else { | 1730 | } else { |
1639 | offset = field->offset; | 1731 | offset = field->offset; |
1640 | size = field->size; | 1732 | size = field->size; |
1733 | |||
1734 | update_dynamic_len(hde, a); | ||
1735 | update_dynamic_len(hde, b); | ||
1641 | } | 1736 | } |
1642 | 1737 | ||
1643 | return memcmp(a->raw_data + offset, b->raw_data + offset, size); | 1738 | return memcmp(a->raw_data + offset, b->raw_data + offset, size); |