summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2017-10-24 03:52:13 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-10-24 03:52:13 +0000
commit2984594cf2a289f820921c60903ecb8b67b4bfc7 (patch)
treeca74da47c3f03935d61f0ce0c26abd91c698015d
parent46545c7ec71f746e6cafbd67667fe43b69f939b1 (diff)
parentbee9bac65f649ad0d73828fc3b78b562e3b47454 (diff)
downloadextras-2984594cf2a289f820921c60903ecb8b67b4bfc7.tar.gz
Merge "simpleperf: fix unit test."
am: bee9bac65f Change-Id: Ic4fd3dd53843d206a2537137049888d1ffb61c01
-rw-r--r--simpleperf/IOEventLoop.cpp21
-rw-r--r--simpleperf/IOEventLoop.h4
-rw-r--r--simpleperf/IOEventLoop_test.cpp32
-rw-r--r--simpleperf/cmd_stat.cpp5
4 files changed, 48 insertions, 14 deletions
diff --git a/simpleperf/IOEventLoop.cpp b/simpleperf/IOEventLoop.cpp
index ce259280..c92170e5 100644
--- a/simpleperf/IOEventLoop.cpp
+++ b/simpleperf/IOEventLoop.cpp
@@ -37,7 +37,7 @@ struct IOEvent {
}
};
-IOEventLoop::IOEventLoop() : ebase_(nullptr), has_error_(false) {}
+IOEventLoop::IOEventLoop() : ebase_(nullptr), has_error_(false), use_precise_timer_(false) {}
IOEventLoop::~IOEventLoop() {
events_.clear();
@@ -46,11 +46,26 @@ IOEventLoop::~IOEventLoop() {
}
}
+bool IOEventLoop::UsePreciseTimer() {
+ if (ebase_ != nullptr) {
+ return false; // Too late to set the flag.
+ }
+ use_precise_timer_ = true;
+ return true;
+}
+
bool IOEventLoop::EnsureInit() {
if (ebase_ == nullptr) {
- ebase_ = event_base_new();
+ event_config* cfg = event_config_new();
+ if (cfg != nullptr) {
+ if (use_precise_timer_) {
+ event_config_set_flag(cfg, EVENT_BASE_FLAG_PRECISE_TIMER);
+ }
+ ebase_ = event_base_new_with_config(cfg);
+ event_config_free(cfg);
+ }
if (ebase_ == nullptr) {
- LOG(ERROR) << "failed to call event_base_new()";
+ LOG(ERROR) << "failed to create event_base";
return false;
}
}
diff --git a/simpleperf/IOEventLoop.h b/simpleperf/IOEventLoop.h
index 9b966295..9dc73c3c 100644
--- a/simpleperf/IOEventLoop.h
+++ b/simpleperf/IOEventLoop.h
@@ -35,6 +35,9 @@ class IOEventLoop {
IOEventLoop();
~IOEventLoop();
+ // Use precise timer for periodic events which want precision in ms.
+ bool UsePreciseTimer();
+
// Register a read Event, so [callback] is called when [fd] can be read
// without blocking. If registered successfully, return the reference
// to control the Event, otherwise return nullptr.
@@ -81,6 +84,7 @@ class IOEventLoop {
event_base* ebase_;
std::vector<std::unique_ptr<IOEvent>> events_;
bool has_error_;
+ bool use_precise_timer_;
};
#endif // SIMPLE_PERF_IOEVENT_LOOP_H_
diff --git a/simpleperf/IOEventLoop_test.cpp b/simpleperf/IOEventLoop_test.cpp
index dc7a4dad..32535021 100644
--- a/simpleperf/IOEventLoop_test.cpp
+++ b/simpleperf/IOEventLoop_test.cpp
@@ -119,14 +119,17 @@ TEST(IOEventLoop, signal) {
ASSERT_EQ(100, count);
}
-TEST(IOEventLoop, periodic) {
+void TestPeriodicEvents(int period_in_us, int iterations, bool precise) {
timeval tv;
- tv.tv_sec = 0;
- tv.tv_usec = 1000;
+ tv.tv_sec = period_in_us / 1000000;
+ tv.tv_usec = period_in_us % 1000000;
int count = 0;
IOEventLoop loop;
+ if (precise) {
+ ASSERT_TRUE(loop.UsePreciseTimer());
+ }
ASSERT_TRUE(loop.AddPeriodicEvent(tv, [&]() {
- if (++count == 100) {
+ if (++count == iterations) {
loop.ExitLoop();
}
return true;
@@ -134,14 +137,21 @@ TEST(IOEventLoop, periodic) {
auto start_time = std::chrono::steady_clock::now();
ASSERT_TRUE(loop.RunLoop());
auto end_time = std::chrono::steady_clock::now();
- ASSERT_EQ(100, count);
+ ASSERT_EQ(iterations, count);
double time_used = std::chrono::duration_cast<std::chrono::duration<double>>(
- end_time - start_time)
- .count();
- // time_used is 0.1 if running precisely, and we accept small errors by using
- // a range [0.1, 0.15).
- ASSERT_GE(time_used, 0.1);
- ASSERT_LT(time_used, 0.15);
+ end_time - start_time).count();
+ double min_time_in_sec = period_in_us / 1e6 * iterations;
+ double max_time_in_sec = min_time_in_sec + (precise ? 0.1 : 1);
+ ASSERT_GE(time_used, min_time_in_sec);
+ ASSERT_LT(time_used, max_time_in_sec);
+}
+
+TEST(IOEventLoop, periodic) {
+ TestPeriodicEvents(1000000, 1, false);
+}
+
+TEST(IOEventLoop, periodic_precise) {
+ TestPeriodicEvents(1000, 100, true);
}
TEST(IOEventLoop, read_and_del_event) {
diff --git a/simpleperf/cmd_stat.cpp b/simpleperf/cmd_stat.cpp
index ddd83f7b..fce4fb14 100644
--- a/simpleperf/cmd_stat.cpp
+++ b/simpleperf/cmd_stat.cpp
@@ -427,6 +427,11 @@ bool StatCommand::Run(const std::vector<std::string>& args) {
return false;
}
IOEventLoop* loop = event_selection_set_.GetIOEventLoop();
+ if (interval_in_ms_ != 0) {
+ if (!loop->UsePreciseTimer()) {
+ return false;
+ }
+ }
if (!loop->AddSignalEvents({SIGCHLD, SIGINT, SIGTERM, SIGHUP},
[&]() { return loop->ExitLoop(); })) {
return false;