summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-09-05 22:17:56 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2017-09-05 22:17:56 +0000
commit41e392642f0972b3abf8920660c7c918e9b266b0 (patch)
tree92dd407ed3c24605c79aa4fa98a687d2533312f9
parentc01804d628cc965924bcf528699d3ccb1da64c98 (diff)
parent6d4959c21b0fe3fb4b4ca1758d2a595a43965ee5 (diff)
downloadextras-41e392642f0972b3abf8920660c7c918e9b266b0.tar.gz
Merge "simpleperf: support --clockid option in record cmd."android-o-mr1-preview-2android-o-mr1-preview-1
-rw-r--r--simpleperf/cmd_list.cpp3
-rw-r--r--simpleperf/cmd_record.cpp31
-rw-r--r--simpleperf/cmd_record_test.cpp14
-rw-r--r--simpleperf/event_selection_set.cpp22
-rw-r--r--simpleperf/event_selection_set.h2
5 files changed, 72 insertions, 0 deletions
diff --git a/simpleperf/cmd_list.cpp b/simpleperf/cmd_list.cpp
index 71998146..3b22bdec 100644
--- a/simpleperf/cmd_list.cpp
+++ b/simpleperf/cmd_list.cpp
@@ -165,6 +165,9 @@ void ListCommand::ShowFeatures() {
if (IsDumpingRegsForTracepointEventsSupported()) {
printf("trace-offcpu\n");
}
+ if (IsSettingClockIdSupported()) {
+ printf("set-clockid\n");
+ }
}
void RegisterListCommand() {
diff --git a/simpleperf/cmd_record.cpp b/simpleperf/cmd_record.cpp
index 85e218ca..d83b2104 100644
--- a/simpleperf/cmd_record.cpp
+++ b/simpleperf/cmd_record.cpp
@@ -62,6 +62,13 @@ static std::unordered_map<std::string, uint64_t> branch_sampling_type_map = {
{"ind_call", PERF_SAMPLE_BRANCH_IND_CALL},
};
+static std::unordered_map<std::string, int> clockid_map = {
+ {"realtime", CLOCK_REALTIME},
+ {"monotonic", CLOCK_MONOTONIC},
+ {"monotonic_raw", CLOCK_MONOTONIC_RAW},
+ {"boottime", CLOCK_BOOTTIME},
+};
+
// The max size of records dumped by kernel is 65535, and dump stack size
// should be a multiply of 8, so MAX_DUMP_STACK_SIZE is 65528.
constexpr uint32_t MAX_DUMP_STACK_SIZE = 65528;
@@ -122,6 +129,9 @@ class RecordCommand : public Command {
" frame as the method to parse call graph in stack.\n"
" Default is dwarf,65528.\n"
"-g Same as '--call-graph dwarf'.\n"
+"--clockid clock_id Generate timestamps of samples using selected clock.\n"
+" Possible values are: realtime, monotonic,\n"
+" monotonic_raw, boottime, perf. Default is perf.\n"
"--cpu cpu_item1,cpu_item2,...\n"
" Collect samples only on the selected cpus. cpu_item can be cpu\n"
" number like 1, or cpu range like 0-3.\n"
@@ -183,6 +193,7 @@ class RecordCommand : public Command {
duration_in_sec_(0),
can_dump_kernel_symbols_(true),
dump_symbols_(true),
+ clockid_("perf"),
event_selection_set_(false),
mmap_page_range_(std::make_pair(1, DESIRED_PAGES_IN_MAPPED_BUFFER)),
record_filename_("perf.data"),
@@ -237,6 +248,7 @@ class RecordCommand : public Command {
double duration_in_sec_;
bool can_dump_kernel_symbols_;
bool dump_symbols_;
+ std::string clockid_;
std::vector<int> cpus_;
EventSelectionSet event_selection_set_;
@@ -498,6 +510,21 @@ bool RecordCommand::ParseOptions(const std::vector<std::string>& args,
<< args[i];
return false;
}
+ } else if (args[i] == "--clockid") {
+ if (!NextArgumentOrError(args, &i)) {
+ return false;
+ }
+ if (args[i] != "perf") {
+ if (!IsSettingClockIdSupported()) {
+ LOG(ERROR) << "Setting clockid is not supported by the kernel.";
+ return false;
+ }
+ if (clockid_map.find(args[i]) == clockid_map.end()) {
+ LOG(ERROR) << "Invalid clockid: " << args[i];
+ return false;
+ }
+ }
+ clockid_ = args[i];
} else if (args[i] == "--cpu") {
if (!NextArgumentOrError(args, &i)) {
return false;
@@ -719,6 +746,9 @@ bool RecordCommand::SetEventSelectionFlags() {
}
}
event_selection_set_.SetInherit(child_inherit_);
+ if (clockid_ != "perf") {
+ event_selection_set_.SetClockId(clockid_map[clockid_]);
+ }
return true;
}
@@ -1191,6 +1221,7 @@ bool RecordCommand::DumpMetaInfoFeature() {
android::base::GetProperty("ro.product.model", "").c_str(),
android::base::GetProperty("ro.product.name", "").c_str());
#endif
+ info_map["clockid"] = clockid_;
return record_file_writer_->WriteMetaInfoFeature(info_map);
}
diff --git a/simpleperf/cmd_record_test.cpp b/simpleperf/cmd_record_test.cpp
index 47186a55..61228ac5 100644
--- a/simpleperf/cmd_record_test.cpp
+++ b/simpleperf/cmd_record_test.cpp
@@ -493,3 +493,17 @@ TEST(record_cmd, trace_offcpu_option) {
TEST(record_cmd, exit_with_parent_option) {
ASSERT_TRUE(RunRecordCmd({"--exit-with-parent"}));
}
+
+TEST(record_cmd, clockid_option) {
+ if (!IsSettingClockIdSupported()) {
+ ASSERT_FALSE(RunRecordCmd({"--clockid", "monotonic"}));
+ } else {
+ TemporaryFile tmpfile;
+ ASSERT_TRUE(RunRecordCmd({"--clockid", "monotonic"}, tmpfile.path));
+ std::unique_ptr<RecordFileReader> reader = RecordFileReader::CreateInstance(tmpfile.path);
+ ASSERT_TRUE(reader);
+ std::unordered_map<std::string, std::string> info_map;
+ ASSERT_TRUE(reader->ReadMetaInfoFeature(&info_map));
+ ASSERT_EQ(info_map["clockid"], "monotonic");
+ }
+}
diff --git a/simpleperf/event_selection_set.cpp b/simpleperf/event_selection_set.cpp
index 240f9d42..ebd34773 100644
--- a/simpleperf/event_selection_set.cpp
+++ b/simpleperf/event_selection_set.cpp
@@ -103,6 +103,19 @@ bool IsDumpingRegsForTracepointEventsSupported() {
return false;
}
+bool IsSettingClockIdSupported() {
+ const EventType* type = FindEventTypeByName("cpu-cycles");
+ if (type == nullptr) {
+ return false;
+ }
+ // Check if the kernel supports setting clockid, which was added in kernel 4.0. Just check with
+ // one clockid is enough. Because all needed clockids were supported before kernel 4.0.
+ perf_event_attr attr = CreateDefaultPerfEventAttr(*type);
+ attr.use_clockid = 1;
+ attr.clockid = CLOCK_MONOTONIC;
+ return IsEventAttrSupported(attr);
+}
+
bool EventSelectionSet::BuildAndCheckEventSelection(
const std::string& event_name, EventSelection* selection) {
std::unique_ptr<EventTypeAndModifier> event_type = ParseEventType(event_name);
@@ -372,6 +385,15 @@ void EventSelectionSet::SetInherit(bool enable) {
}
}
+void EventSelectionSet::SetClockId(int clock_id) {
+ for (auto& group : groups_) {
+ for (auto& selection : group) {
+ selection.event_attr.use_clockid = 1;
+ selection.event_attr.clockid = clock_id;
+ }
+ }
+}
+
bool EventSelectionSet::NeedKernelSymbol() const {
for (const auto& group : groups_) {
for (const auto& selection : group) {
diff --git a/simpleperf/event_selection_set.h b/simpleperf/event_selection_set.h
index cc972bea..7397c6fb 100644
--- a/simpleperf/event_selection_set.h
+++ b/simpleperf/event_selection_set.h
@@ -101,6 +101,7 @@ class EventSelectionSet {
void EnableFpCallChainSampling();
bool EnableDwarfCallChainSampling(uint32_t dump_stack_size);
void SetInherit(bool enable);
+ void SetClockId(int clock_id);
bool NeedKernelSymbol() const;
void AddMonitoredProcesses(const std::set<pid_t>& processes) {
@@ -201,5 +202,6 @@ class EventSelectionSet {
bool IsBranchSamplingSupported();
bool IsDwarfCallChainSamplingSupported();
bool IsDumpingRegsForTracepointEventsSupported();
+bool IsSettingClockIdSupported();
#endif // SIMPLE_PERF_EVENT_SELECTION_SET_H_