diff options
author | Ian Rogers <irogers@google.com> | 2024-08-13 01:41:19 +0300 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2024-08-13 21:28:19 +0300 |
commit | 1a9d080d19c3303569614ed4c3b43a39aacd90d7 (patch) | |
tree | 55f9f118a64f6c39c10cbd8edeaae7763392316b | |
parent | b2738fda24543777a623a7d1cc2a9985ab81b448 (diff) | |
download | linux-1a9d080d19c3303569614ed4c3b43a39aacd90d7.tar.xz |
perf callchain: Add a for_each callback style API
Add a for_each callback style API to callchain with
sample__for_each_callchain_node().
Possibly in the future such an API can avoid the overhead of
constructing the call chain list.
Signed-off-by: Ian Rogers <irogers@google.com>
Acked-by: Namhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Casey Chen <cachen@purestorage.com>
Cc: Colin Ian King <colin.i.king@gmail.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Tom Zanussi <tzanussi@gmail.com>
Link: https://lore.kernel.org/r/20240812224119.744968-1-irogers@google.com
[ Split from a larger patch that introduced the API and use it ]
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
-rw-r--r-- | tools/perf/util/callchain.c | 35 | ||||
-rw-r--r-- | tools/perf/util/callchain.h | 6 |
2 files changed, 41 insertions, 0 deletions
diff --git a/tools/perf/util/callchain.c b/tools/perf/util/callchain.c index 6d075648d2cc..0d608e875fe9 100644 --- a/tools/perf/util/callchain.c +++ b/tools/perf/util/callchain.c @@ -1797,3 +1797,38 @@ s64 callchain_avg_cycles(struct callchain_node *cnode) return cycles; } + +int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel, + struct perf_sample *sample, int max_stack, + callchain_iter_fn cb, void *data) +{ + struct callchain_cursor *cursor = get_tls_callchain_cursor(); + int ret; + + if (!cursor) + return -ENOMEM; + + /* Fill in the callchain. */ + ret = thread__resolve_callchain(thread, cursor, evsel, sample, + /*parent=*/NULL, /*root_al=*/NULL, + max_stack); + if (ret) + return ret; + + /* Switch from writing the callchain to reading it. */ + callchain_cursor_commit(cursor); + + while (1) { + struct callchain_cursor_node *node = callchain_cursor_current(cursor); + + if (!node) + break; + + ret = cb(node, data); + if (ret) + return ret; + + callchain_cursor_advance(cursor); + } + return 0; +} diff --git a/tools/perf/util/callchain.h b/tools/perf/util/callchain.h index d5c66345ae31..76891f8e2373 100644 --- a/tools/perf/util/callchain.h +++ b/tools/perf/util/callchain.h @@ -311,4 +311,10 @@ u64 callchain_total_hits(struct hists *hists); s64 callchain_avg_cycles(struct callchain_node *cnode); +typedef int (*callchain_iter_fn)(struct callchain_cursor_node *node, void *data); + +int sample__for_each_callchain_node(struct thread *thread, struct evsel *evsel, + struct perf_sample *sample, int max_stack, + callchain_iter_fn cb, void *data); + #endif /* __PERF_CALLCHAIN_H */ |