summaryrefslogtreecommitdiff
path: root/simpleperf/record.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-07-24 14:59:46 -0700
committerYabin Cui <yabinc@google.com>2017-07-24 14:59:46 -0700
commitd3cb3b0c50211ad68459d526fcc32eb11b8f26a5 (patch)
tree027116325b25ecb2552e34122529adf07524801d /simpleperf/record.cpp
parent239663cf9757485fb723e17b10be5c6b12706bd7 (diff)
downloadextras-d3cb3b0c50211ad68459d526fcc32eb11b8f26a5.tar.gz
simpleperf: exclude kernel callchains when needed.
Exclude kernel callchains when users only monitor events in user space. After this change, when users use `record -e cpu-cycles:u --trace-offcpu`, the samples of the implicitly added sched:sched_switch event won't contain any kernel callchain. Bug: http://b/37572306 Test: run simpleperf_unit_test. Change-Id: Iffcb61bac796e734825e68f847f24b4006b44360
Diffstat (limited to 'simpleperf/record.cpp')
-rw-r--r--simpleperf/record.cpp25
1 files changed, 25 insertions, 0 deletions
diff --git a/simpleperf/record.cpp b/simpleperf/record.cpp
index 65e98ea6..f3548150 100644
--- a/simpleperf/record.cpp
+++ b/simpleperf/record.cpp
@@ -594,6 +594,31 @@ void SampleRecord::ReplaceRegAndStackWithCallChain(
*reinterpret_cast<uint64_t*>(p) = callchain_data.ip_nr;
}
+size_t SampleRecord::ExcludeKernelCallChain() {
+ size_t user_callchain_length = 0u;
+ if (sample_type & PERF_SAMPLE_CALLCHAIN) {
+ size_t i;
+ for (i = 0; i < callchain_data.ip_nr; ++i) {
+ if (callchain_data.ips[i] == PERF_CONTEXT_USER) {
+ i++;
+ if (i < callchain_data.ip_nr) {
+ ip_data.ip = callchain_data.ips[i];
+ if (sample_type & PERF_SAMPLE_IP) {
+ *reinterpret_cast<uint64_t*>(const_cast<char*>(binary_ + header_size())) = ip_data.ip;
+ }
+ header.misc = (header.misc & ~PERF_RECORD_MISC_KERNEL) | PERF_RECORD_MISC_USER;
+ reinterpret_cast<perf_event_header*>(const_cast<char*>(binary_))->misc = header.misc;
+ }
+ break;
+ } else {
+ const_cast<uint64_t*>(callchain_data.ips)[i] = PERF_CONTEXT_USER;
+ }
+ }
+ user_callchain_length = callchain_data.ip_nr - i;
+ }
+ return user_callchain_length;
+}
+
void SampleRecord::DumpData(size_t indent) const {
PrintIndented(indent, "sample_type: 0x%" PRIx64 "\n", sample_type);
if (sample_type & PERF_SAMPLE_IP) {