aboutsummaryrefslogtreecommitdiff
path: root/gd/os/thread_benchmark.cc
blob: 7a0e1407b55926159938d5d679a9c670673616c3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
 * Copyright 2019 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <future>
#include <memory>
#include <thread>

#include "benchmark/benchmark.h"
#include "common/bind.h"
#include "os/handler.h"
#include "os/thread.h"

using ::benchmark::State;
using ::bluetooth::common::BindOnce;
using ::bluetooth::os::Handler;
using ::bluetooth::os::Thread;

#define NUM_MESSAGES_TO_SEND 100000

class BM_ThreadPerformance : public ::benchmark::Fixture {
 protected:
  void SetUp(State& st) override {
    benchmark::Fixture::SetUp(st);
    counter_promise_ = std::promise<void>();
    counter_ = 0;
  }
  void TearDown(State& st) override {
    benchmark::Fixture::TearDown(st);
  }
  void callback_batch() {
    counter_++;
    if (counter_ >= num_messages_to_send_) {
      counter_promise_.set_value();
    }
  }

  void callback() {
    counter_promise_.set_value();
  }

  int64_t num_messages_to_send_;
  int64_t counter_;
  std::promise<void> counter_promise_;
};

class BM_ReactorThread : public BM_ThreadPerformance {
 protected:
  void SetUp(State& st) override {
    BM_ThreadPerformance::SetUp(st);
    thread_ = std::make_unique<Thread>("BM_ReactorThread thread", Thread::Priority::NORMAL);
    handler_ = std::make_unique<Handler>(thread_.get());
  }
  void TearDown(State& st) override {
    handler_ = nullptr;
    thread_->Stop();
    thread_ = nullptr;
    BM_ThreadPerformance::TearDown(st);
  }
  std::unique_ptr<Thread> thread_;
  std::unique_ptr<Handler> handler_;
};

BENCHMARK_DEFINE_F(BM_ReactorThread, batch_enque_dequeue)(State& state) {
  for (auto _ : state) {
    num_messages_to_send_ = state.range(0);
    counter_ = 0;
    counter_promise_ = std::promise<void>();
    std::future<void> counter_future = counter_promise_.get_future();
    for (int i = 0; i < num_messages_to_send_; i++) {
      handler_->Post(BindOnce(
          &BM_ReactorThread_batch_enque_dequeue_Benchmark::callback_batch, bluetooth::common::Unretained(this)));
    }
    counter_future.wait();
  }
};

BENCHMARK_REGISTER_F(BM_ReactorThread, batch_enque_dequeue)
    ->Arg(10)
    ->Arg(1000)
    ->Arg(10000)
    ->Arg(100000)
    ->Iterations(1)
    ->UseRealTime();

BENCHMARK_DEFINE_F(BM_ReactorThread, sequential_execution)(State& state) {
  for (auto _ : state) {
    num_messages_to_send_ = state.range(0);
    for (int i = 0; i < num_messages_to_send_; i++) {
      counter_promise_ = std::promise<void>();
      std::future<void> counter_future = counter_promise_.get_future();
      handler_->Post(
          BindOnce(&BM_ReactorThread_sequential_execution_Benchmark::callback, bluetooth::common::Unretained(this)));
      counter_future.wait();
    }
  }
};

BENCHMARK_REGISTER_F(BM_ReactorThread, sequential_execution)
    ->Arg(10)
    ->Arg(1000)
    ->Arg(10000)
    ->Arg(100000)
    ->Iterations(1)
    ->UseRealTime();