9 #include "benchmark/benchmark.h"
11 // Test that Setup() and Teardown() are called exactly once
12 // for each benchmark run (single-threaded).
14 static int setup_call
= 0;
15 static int teardown_call
= 0;
17 static void DoSetup1(const benchmark::State
& state
) {
20 // Setup/Teardown should never be called with any thread_idx != 0.
21 assert(state
.thread_index() == 0);
24 static void DoTeardown1(const benchmark::State
& state
) {
25 ++single::teardown_call
;
26 assert(state
.thread_index() == 0);
29 static void BM_with_setup(benchmark::State
& state
) {
30 for (auto s
: state
) {
33 BENCHMARK(BM_with_setup
)
40 ->Teardown(DoTeardown1
);
42 // Test that Setup() and Teardown() are called once for each group of threads.
43 namespace concurrent
{
44 static std::atomic
<int> setup_call(0);
45 static std::atomic
<int> teardown_call(0);
46 static std::atomic
<int> func_call(0);
47 } // namespace concurrent
49 static void DoSetup2(const benchmark::State
& state
) {
50 concurrent::setup_call
.fetch_add(1, std::memory_order_acquire
);
51 assert(state
.thread_index() == 0);
54 static void DoTeardown2(const benchmark::State
& state
) {
55 concurrent::teardown_call
.fetch_add(1, std::memory_order_acquire
);
56 assert(state
.thread_index() == 0);
59 static void BM_concurrent(benchmark::State
& state
) {
60 for (auto s
: state
) {
62 concurrent::func_call
.fetch_add(1, std::memory_order_acquire
);
65 BENCHMARK(BM_concurrent
)
67 ->Teardown(DoTeardown2
)
73 // Testing interaction with Fixture::Setup/Teardown
74 namespace fixture_interaction
{
76 int fixture_setup
= 0;
77 } // namespace fixture_interaction
79 #define FIXTURE_BECHMARK_NAME MyFixture
81 class FIXTURE_BECHMARK_NAME
: public ::benchmark::Fixture
{
83 void SetUp(const ::benchmark::State
&) BENCHMARK_OVERRIDE
{
84 fixture_interaction::fixture_setup
++;
87 ~FIXTURE_BECHMARK_NAME() {}
90 BENCHMARK_F(FIXTURE_BECHMARK_NAME
, BM_WithFixture
)(benchmark::State
& st
) {
95 static void DoSetupWithFixture(const benchmark::State
&) {
96 fixture_interaction::setup
++;
99 BENCHMARK_REGISTER_F(FIXTURE_BECHMARK_NAME
, BM_WithFixture
)
104 ->Setup(DoSetupWithFixture
)
108 // Testing repetitions.
109 namespace repetitions
{
113 static void DoSetupWithRepetitions(const benchmark::State
&) {
114 repetitions::setup
++;
116 static void BM_WithRep(benchmark::State
& state
) {
117 for (auto _
: state
) {
121 BENCHMARK(BM_WithRep
)
126 ->Setup(DoSetupWithRepetitions
)
130 int main(int argc
, char** argv
) {
131 benchmark::Initialize(&argc
, argv
);
133 size_t ret
= benchmark::RunSpecifiedBenchmarks(".");
136 // Setup/Teardown is called once for each arg group (1,3,5,7).
137 assert(single::setup_call
== 4);
138 assert(single::teardown_call
== 4);
140 // 3 group of threads calling this function (3,5,10).
141 assert(concurrent::setup_call
.load(std::memory_order_relaxed
) == 3);
142 assert(concurrent::teardown_call
.load(std::memory_order_relaxed
) == 3);
143 assert((5 + 10 + 15) ==
144 concurrent::func_call
.load(std::memory_order_relaxed
));
146 // Setup is called 4 times, once for each arg group (1,3,5,7)
147 assert(fixture_interaction::setup
== 4);
148 // Fixture::Setup is called everytime the bm routine is run.
149 // The exact number is indeterministic, so we just assert that
150 // it's more than setup.
151 assert(fixture_interaction::fixture_setup
> fixture_interaction::setup
);
153 // Setup is call once for each repetition * num_arg = 4 * 4 = 16.
154 assert(repetitions::setup
== 16);