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 { benchmark::Fixture::TearDown(st); }
callback_batch()41   void callback_batch() {
42     counter_++;
43     if (counter_ >= num_messages_to_send_) {
44       counter_promise_.set_value();
45     }
46   }
47 
callback()48   void callback() { counter_promise_.set_value(); }
49 
50   int64_t num_messages_to_send_;
51   int64_t counter_;
52   std::promise<void> counter_promise_;
53 };
54 
55 class BM_ReactorThread : public BM_ThreadPerformance {
56 protected:
SetUp(State & st)57   void SetUp(State& st) override {
58     BM_ThreadPerformance::SetUp(st);
59     thread_ = std::make_unique<Thread>("BM_ReactorThread thread", Thread::Priority::NORMAL);
60     handler_ = std::make_unique<Handler>(thread_.get());
61   }
TearDown(State & st)62   void TearDown(State& st) override {
63     handler_ = nullptr;
64     thread_->Stop();
65     thread_ = nullptr;
66     BM_ThreadPerformance::TearDown(st);
67   }
68   std::unique_ptr<Thread> thread_;
69   std::unique_ptr<Handler> handler_;
70 };
71 
BENCHMARK_DEFINE_F(BM_ReactorThread,batch_enque_dequeue)72 BENCHMARK_DEFINE_F(BM_ReactorThread, batch_enque_dequeue)(State& state) {
73   for (auto _ : state) {
74     num_messages_to_send_ = state.range(0);
75     counter_ = 0;
76     counter_promise_ = std::promise<void>();
77     std::future<void> counter_future = counter_promise_.get_future();
78     for (int i = 0; i < num_messages_to_send_; i++) {
79       handler_->Post(BindOnce(&BM_ReactorThread_batch_enque_dequeue_Benchmark::callback_batch,
80                               bluetooth::common::Unretained(this)));
81     }
82     counter_future.wait();
83   }
84 }
85 
86 BENCHMARK_REGISTER_F(BM_ReactorThread, batch_enque_dequeue)
87         ->Arg(10)
88         ->Arg(1000)
89         ->Arg(10000)
90         ->Arg(100000)
91         ->Iterations(1)
92         ->UseRealTime();
93 
BENCHMARK_DEFINE_F(BM_ReactorThread,sequential_execution)94 BENCHMARK_DEFINE_F(BM_ReactorThread, sequential_execution)(State& state) {
95   for (auto _ : state) {
96     num_messages_to_send_ = state.range(0);
97     for (int i = 0; i < num_messages_to_send_; i++) {
98       counter_promise_ = std::promise<void>();
99       std::future<void> counter_future = counter_promise_.get_future();
100       handler_->Post(BindOnce(&BM_ReactorThread_sequential_execution_Benchmark::callback,
101                               bluetooth::common::Unretained(this)));
102       counter_future.wait();
103     }
104   }
105 }
106 
107 BENCHMARK_REGISTER_F(BM_ReactorThread, sequential_execution)
108         ->Arg(10)
109         ->Arg(1000)
110         ->Arg(10000)
111         ->Arg(100000)
112         ->Iterations(1)
113         ->UseRealTime();
114