1 /*
2  * Copyright 2019 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 <future>
18 #include <memory>
19 #include <thread>
20 
21 #include "benchmark/benchmark.h"
22 #include "common/bind.h"
23 #include "os/handler.h"
24 #include "os/thread.h"
25 
26 using ::benchmark::State;
27 using ::bluetooth::common::BindOnce;
28 using ::bluetooth::os::Handler;
29 using ::bluetooth::os::Thread;
30 
31 #define NUM_MESSAGES_TO_SEND 100000
32 
33 class BM_ThreadPerformance : public ::benchmark::Fixture {
34  protected:
SetUp(State & st)35   void SetUp(State& st) override {
36     benchmark::Fixture::SetUp(st);
37     counter_promise_ = std::promise<void>();
38     counter_ = 0;
39   }
TearDown(State & st)40   void TearDown(State& st) override {
41     benchmark::Fixture::TearDown(st);
42   }
callback_batch()43   void callback_batch() {
44     counter_++;
45     if (counter_ >= num_messages_to_send_) {
46       counter_promise_.set_value();
47     }
48   }
49 
callback()50   void callback() {
51     counter_promise_.set_value();
52   }
53 
54   int64_t num_messages_to_send_;
55   int64_t counter_;
56   std::promise<void> counter_promise_;
57 };
58 
59 class BM_ReactorThread : public BM_ThreadPerformance {
60  protected:
SetUp(State & st)61   void SetUp(State& st) override {
62     BM_ThreadPerformance::SetUp(st);
63     thread_ = std::make_unique<Thread>("BM_ReactorThread thread", Thread::Priority::NORMAL);
64     handler_ = std::make_unique<Handler>(thread_.get());
65   }
TearDown(State & st)66   void TearDown(State& st) override {
67     handler_ = nullptr;
68     thread_->Stop();
69     thread_ = nullptr;
70     BM_ThreadPerformance::TearDown(st);
71   }
72   std::unique_ptr<Thread> thread_;
73   std::unique_ptr<Handler> handler_;
74 };
75 
BENCHMARK_DEFINE_F(BM_ReactorThread,batch_enque_dequeue)76 BENCHMARK_DEFINE_F(BM_ReactorThread, batch_enque_dequeue)(State& state) {
77   for (auto _ : state) {
78     num_messages_to_send_ = state.range(0);
79     counter_ = 0;
80     counter_promise_ = std::promise<void>();
81     std::future<void> counter_future = counter_promise_.get_future();
82     for (int i = 0; i < num_messages_to_send_; i++) {
83       handler_->Post(BindOnce(
84           &BM_ReactorThread_batch_enque_dequeue_Benchmark::callback_batch, bluetooth::common::Unretained(this)));
85     }
86     counter_future.wait();
87   }
88 };
89 
90 BENCHMARK_REGISTER_F(BM_ReactorThread, batch_enque_dequeue)
91     ->Arg(10)
92     ->Arg(1000)
93     ->Arg(10000)
94     ->Arg(100000)
95     ->Iterations(1)
96     ->UseRealTime();
97 
BENCHMARK_DEFINE_F(BM_ReactorThread,sequential_execution)98 BENCHMARK_DEFINE_F(BM_ReactorThread, sequential_execution)(State& state) {
99   for (auto _ : state) {
100     num_messages_to_send_ = state.range(0);
101     for (int i = 0; i < num_messages_to_send_; i++) {
102       counter_promise_ = std::promise<void>();
103       std::future<void> counter_future = counter_promise_.get_future();
104       handler_->Post(
105           BindOnce(&BM_ReactorThread_sequential_execution_Benchmark::callback, bluetooth::common::Unretained(this)));
106       counter_future.wait();
107     }
108   }
109 };
110 
111 BENCHMARK_REGISTER_F(BM_ReactorThread, sequential_execution)
112     ->Arg(10)
113     ->Arg(1000)
114     ->Arg(10000)
115     ->Arg(100000)
116     ->Iterations(1)
117     ->UseRealTime();
118