• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <base/bind.h>
18 #include <base/run_loop.h>
19 #include <base/threading/thread.h>
20 #include <benchmark/benchmark.h>
21 #include <future>
22 
23 #include "common/message_loop_thread.h"
24 #include "common/once_timer.h"
25 #include "common/repeating_timer.h"
26 #include "common/time_util.h"
27 #include "osi/include/alarm.h"
28 
29 using ::benchmark::State;
30 using bluetooth::common::MessageLoopThread;
31 using bluetooth::common::OnceTimer;
32 using bluetooth::common::RepeatingTimer;
33 using bluetooth::common::time_get_os_boottime_us;
34 
get_main_thread()35 bluetooth::common::MessageLoopThread* get_main_thread() { return nullptr; }
36 
37 namespace {
38 std::unordered_map<int, int> g_map;
39 std::shared_ptr<std::promise<void>> g_promise;
40 uint64_t g_start_time;
41 int g_scheduled_tasks;
42 int g_task_length;
43 int g_task_interval;
44 int g_task_counter;
45 
TimerFire(void *)46 void TimerFire(void*) { g_promise->set_value(); }
47 
AlarmSleepAndCountDelayedTime(void *)48 void AlarmSleepAndCountDelayedTime(void*) {
49   auto end_time_us = time_get_os_boottime_us();
50   auto time_after_start_ms = (end_time_us - g_start_time) / 1000;
51   g_task_counter++;
52   g_map[time_after_start_ms - g_task_counter * g_task_interval]++;
53   std::this_thread::sleep_for(std::chrono::milliseconds(g_task_length));
54   if (g_task_counter >= g_scheduled_tasks) {
55     g_promise->set_value();
56   }
57 }
58 
59 }  // namespace
60 
61 class BM_OsiAlarmTimer : public ::benchmark::Fixture {
62  protected:
SetUp(State & st)63   void SetUp(State& st) override {
64     ::benchmark::Fixture::SetUp(st);
65     alarm_ = alarm_new("osi_alarm_timer_test");
66     g_promise = std::make_shared<std::promise<void>>();
67   }
68 
TearDown(State & st)69   void TearDown(State& st) override {
70     g_promise = nullptr;
71     alarm_free(alarm_);
72     ::benchmark::Fixture::TearDown(st);
73   }
74 
75   alarm_t* alarm_ = nullptr;
76 };
77 
BENCHMARK_DEFINE_F(BM_OsiAlarmTimer,timer_performance_ms)78 BENCHMARK_DEFINE_F(BM_OsiAlarmTimer, timer_performance_ms)(State& state) {
79   auto milliseconds = static_cast<int>(state.range(0));
80   for (auto _ : state) {
81     auto start_time_point = time_get_os_boottime_us();
82     alarm_set(alarm_, milliseconds, &TimerFire, nullptr);
83     g_promise->get_future().get();
84     auto end_time_point = time_get_os_boottime_us();
85     auto duration = end_time_point - start_time_point;
86     state.SetIterationTime(duration * 1e-6);
87   }
88 };
89 
90 BENCHMARK_REGISTER_F(BM_OsiAlarmTimer, timer_performance_ms)
91     ->Arg(1)
92     ->Arg(5)
93     ->Arg(10)
94     ->Arg(20)
95     ->Arg(100)
96     ->Arg(1000)
97     ->Arg(2000)
98     ->Iterations(1)
99     ->UseManualTime();
100 
101 class BM_AlarmTaskTimer : public ::benchmark::Fixture {
102  protected:
SetUp(State & st)103   void SetUp(State& st) override {
104     ::benchmark::Fixture::SetUp(st);
105     message_loop_thread_ = new MessageLoopThread("timer_benchmark");
106     message_loop_thread_->StartUp();
107     message_loop_thread_->EnableRealTimeScheduling();
108     once_timer_ = new OnceTimer();
109     repeating_timer_ = new RepeatingTimer();
110     g_promise = std::make_shared<std::promise<void>>();
111   }
112 
TearDown(State & st)113   void TearDown(State& st) override {
114     g_promise = nullptr;
115     delete once_timer_;
116     once_timer_ = nullptr;
117     delete repeating_timer_;
118     repeating_timer_ = nullptr;
119     message_loop_thread_->ShutDown();
120     delete message_loop_thread_;
121     message_loop_thread_ = nullptr;
122     ::benchmark::Fixture::TearDown(st);
123   }
124 
125   MessageLoopThread* message_loop_thread_;
126   OnceTimer* once_timer_;
127   RepeatingTimer* repeating_timer_;
128 };
129 
BENCHMARK_DEFINE_F(BM_AlarmTaskTimer,timer_performance_ms)130 BENCHMARK_DEFINE_F(BM_AlarmTaskTimer, timer_performance_ms)(State& state) {
131   auto milliseconds = static_cast<int>(state.range(0));
132   for (auto _ : state) {
133     auto start_time_point = time_get_os_boottime_us();
134     once_timer_->Schedule(message_loop_thread_->GetWeakPtr(), FROM_HERE,
135                           base::BindOnce(&TimerFire, nullptr),
136 #if BASE_VER < 931007
137                           base::TimeDelta::FromMilliseconds(milliseconds));
138 #else
139                           base::Milliseconds(milliseconds));
140 #endif
141     g_promise->get_future().get();
142     once_timer_->Cancel();
143     auto end_time_point = time_get_os_boottime_us();
144     auto duration = end_time_point - start_time_point;
145     state.SetIterationTime(duration * 1e-6);
146   }
147 };
148 
149 BENCHMARK_REGISTER_F(BM_AlarmTaskTimer, timer_performance_ms)
150     ->Arg(1)
151     ->Arg(5)
152     ->Arg(10)
153     ->Arg(20)
154     ->Arg(100)
155     ->Arg(1000)
156     ->Arg(2000)
157     ->Iterations(1)
158     ->UseManualTime();
159 
160 class BM_OsiPeriodicAlarmTimer : public ::benchmark::Fixture {
161  protected:
SetUp(State & st)162   void SetUp(State& st) override {
163     ::benchmark::Fixture::SetUp(st);
164     alarm_ = alarm_new_periodic("osi_alarm_timer_test");
165     g_map.clear();
166     g_promise = std::make_shared<std::promise<void>>();
167     g_scheduled_tasks = 0;
168     g_task_length = 0;
169     g_task_interval = 0;
170     g_task_counter = 0;
171   }
172 
TearDown(State & st)173   void TearDown(State& st) override {
174     g_promise = nullptr;
175     alarm_free(alarm_);
176     ::benchmark::Fixture::TearDown(st);
177   }
178 
179   alarm_t* alarm_ = nullptr;
180 };
181 
BENCHMARK_DEFINE_F(BM_OsiPeriodicAlarmTimer,periodic_accuracy)182 BENCHMARK_DEFINE_F(BM_OsiPeriodicAlarmTimer, periodic_accuracy)(State& state) {
183   for (auto _ : state) {
184     g_scheduled_tasks = state.range(0);
185     g_task_length = state.range(1);
186     g_task_interval = state.range(2);
187     g_start_time = time_get_os_boottime_us();
188     alarm_set(alarm_, g_task_interval, &AlarmSleepAndCountDelayedTime, nullptr);
189     g_promise->get_future().get();
190     alarm_cancel(alarm_);
191   }
192   for (const auto& delay : g_map) {
193     state.counters[std::to_string(delay.first)] = delay.second;
194   }
195 };
196 
197 BENCHMARK_REGISTER_F(BM_OsiPeriodicAlarmTimer, periodic_accuracy)
198     ->Args({2000, 1, 5})
199     ->Args({2000, 3, 5})
200     ->Args({2000, 1, 7})
201     ->Args({2000, 3, 7})
202     ->Args({2000, 1, 20})
203     ->Args({2000, 5, 20})
204     ->Args({2000, 10, 20})
205     ->Args({2000, 15, 20})
206     ->Iterations(1)
207     ->UseRealTime();
208 
209 class BM_AlarmTaskPeriodicTimer : public ::benchmark::Fixture {
210  protected:
SetUp(State & st)211   void SetUp(State& st) override {
212     ::benchmark::Fixture::SetUp(st);
213     message_loop_thread_ = new MessageLoopThread("timer_benchmark");
214     message_loop_thread_->StartUp();
215     message_loop_thread_->EnableRealTimeScheduling();
216     once_timer_ = new OnceTimer();
217     repeating_timer_ = new RepeatingTimer();
218     g_map.clear();
219     g_promise = std::make_shared<std::promise<void>>();
220     g_scheduled_tasks = 0;
221     g_task_length = 0;
222     g_task_interval = 0;
223     g_task_counter = 0;
224   }
225 
TearDown(State & st)226   void TearDown(State& st) override {
227     g_promise = nullptr;
228     delete once_timer_;
229     once_timer_ = nullptr;
230     delete repeating_timer_;
231     repeating_timer_ = nullptr;
232     message_loop_thread_->ShutDown();
233     delete message_loop_thread_;
234     message_loop_thread_ = nullptr;
235     ::benchmark::Fixture::TearDown(st);
236   }
237 
238   MessageLoopThread* message_loop_thread_;
239   OnceTimer* once_timer_;
240   RepeatingTimer* repeating_timer_;
241 };
242 
BENCHMARK_DEFINE_F(BM_AlarmTaskPeriodicTimer,periodic_accuracy)243 BENCHMARK_DEFINE_F(BM_AlarmTaskPeriodicTimer, periodic_accuracy)
244 (State& state) {
245   for (auto _ : state) {
246     g_scheduled_tasks = state.range(0);
247     g_task_length = state.range(1);
248     g_task_interval = state.range(2);
249     g_start_time = time_get_os_boottime_us();
250     repeating_timer_->SchedulePeriodic(
251         message_loop_thread_->GetWeakPtr(), FROM_HERE,
252         base::BindRepeating(&AlarmSleepAndCountDelayedTime, nullptr),
253 #if BASE_VER < 931007
254         base::TimeDelta::FromMilliseconds(g_task_interval));
255 #else
256         base::Milliseconds(g_task_interval));
257 #endif
258     g_promise->get_future().get();
259     repeating_timer_->Cancel();
260   }
261   for (const auto& delay : g_map) {
262     state.counters[std::to_string(delay.first)] = delay.second;
263   }
264 };
265 
266 BENCHMARK_REGISTER_F(BM_AlarmTaskPeriodicTimer, periodic_accuracy)
267     ->Args({2000, 1, 5})
268     ->Args({2000, 3, 5})
269     ->Args({2000, 1, 7})
270     ->Args({2000, 3, 7})
271     ->Args({2000, 1, 20})
272     ->Args({2000, 5, 20})
273     ->Args({2000, 10, 20})
274     ->Args({2000, 15, 20})
275     ->Iterations(1)
276     ->UseRealTime();
277 
main(int argc,char ** argv)278 int main(int argc, char** argv) {
279   // Disable LOG() output from libchrome
280   logging::LoggingSettings log_settings;
281   log_settings.logging_dest = logging::LoggingDestination::LOG_NONE;
282   CHECK(logging::InitLogging(log_settings)) << "Failed to set up logging";
283   ::benchmark::Initialize(&argc, argv);
284   if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
285     return 1;
286   }
287   ::benchmark::RunSpecifiedBenchmarks();
288 }
289