diff options
author | Yabin Cui <yabinc@google.com> | 2017-10-24 03:52:13 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2017-10-24 03:52:13 +0000 |
commit | 2984594cf2a289f820921c60903ecb8b67b4bfc7 (patch) | |
tree | ca74da47c3f03935d61f0ce0c26abd91c698015d | |
parent | 46545c7ec71f746e6cafbd67667fe43b69f939b1 (diff) | |
parent | bee9bac65f649ad0d73828fc3b78b562e3b47454 (diff) | |
download | extras-2984594cf2a289f820921c60903ecb8b67b4bfc7.tar.gz |
Merge "simpleperf: fix unit test."
am: bee9bac65f
Change-Id: Ic4fd3dd53843d206a2537137049888d1ffb61c01
-rw-r--r-- | simpleperf/IOEventLoop.cpp | 21 | ||||
-rw-r--r-- | simpleperf/IOEventLoop.h | 4 | ||||
-rw-r--r-- | simpleperf/IOEventLoop_test.cpp | 32 | ||||
-rw-r--r-- | simpleperf/cmd_stat.cpp | 5 |
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; |