xref: /aosp_15_r20/external/grpc-grpc/test/cpp/microbenchmarks/bm_closure.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2017 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker // Test various closure related operations
20*cc02d7e2SAndroid Build Coastguard Worker 
21*cc02d7e2SAndroid Build Coastguard Worker #include <sstream>
22*cc02d7e2SAndroid Build Coastguard Worker 
23*cc02d7e2SAndroid Build Coastguard Worker #include <benchmark/benchmark.h>
24*cc02d7e2SAndroid Build Coastguard Worker 
25*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/grpc.h>
26*cc02d7e2SAndroid Build Coastguard Worker 
27*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gpr/spinlock.h"
28*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/iomgr/closure.h"
29*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/iomgr/combiner.h"
30*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/iomgr/exec_ctx.h"
31*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/test_config.h"
32*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/microbenchmarks/helpers.h"
33*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/util/test_config.h"
34*cc02d7e2SAndroid Build Coastguard Worker 
BM_NoOpExecCtx(benchmark::State & state)35*cc02d7e2SAndroid Build Coastguard Worker static void BM_NoOpExecCtx(benchmark::State& state) {
36*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
37*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx exec_ctx;
38*cc02d7e2SAndroid Build Coastguard Worker   }
39*cc02d7e2SAndroid Build Coastguard Worker }
40*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_NoOpExecCtx);
41*cc02d7e2SAndroid Build Coastguard Worker 
BM_WellFlushed(benchmark::State & state)42*cc02d7e2SAndroid Build Coastguard Worker static void BM_WellFlushed(benchmark::State& state) {
43*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
44*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
45*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
46*cc02d7e2SAndroid Build Coastguard Worker   }
47*cc02d7e2SAndroid Build Coastguard Worker }
48*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_WellFlushed);
49*cc02d7e2SAndroid Build Coastguard Worker 
DoNothing(void *,grpc_error_handle)50*cc02d7e2SAndroid Build Coastguard Worker static void DoNothing(void* /*arg*/, grpc_error_handle /*error*/) {}
51*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureInitAgainstExecCtx(benchmark::State & state)52*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureInitAgainstExecCtx(benchmark::State& state) {
53*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
54*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
55*cc02d7e2SAndroid Build Coastguard Worker     benchmark::DoNotOptimize(
56*cc02d7e2SAndroid Build Coastguard Worker         GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx));
57*cc02d7e2SAndroid Build Coastguard Worker   }
58*cc02d7e2SAndroid Build Coastguard Worker }
59*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureInitAgainstExecCtx);
60*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureInitAgainstCombiner(benchmark::State & state)61*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureInitAgainstCombiner(benchmark::State& state) {
62*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner = grpc_combiner_create(
63*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine());
64*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
65*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
66*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
67*cc02d7e2SAndroid Build Coastguard Worker     benchmark::DoNotOptimize(
68*cc02d7e2SAndroid Build Coastguard Worker         GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, nullptr));
69*cc02d7e2SAndroid Build Coastguard Worker   }
70*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner, "finished");
71*cc02d7e2SAndroid Build Coastguard Worker }
72*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureInitAgainstCombiner);
73*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureRun(benchmark::State & state)74*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureRun(benchmark::State& state) {
75*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
76*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
77*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
78*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
79*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::Closure::Run(DEBUG_LOCATION, &c, absl::OkStatus());
80*cc02d7e2SAndroid Build Coastguard Worker   }
81*cc02d7e2SAndroid Build Coastguard Worker }
82*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureRun);
83*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureCreateAndRun(benchmark::State & state)84*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureCreateAndRun(benchmark::State& state) {
85*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
86*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
87*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::Closure::Run(
88*cc02d7e2SAndroid Build Coastguard Worker         DEBUG_LOCATION,
89*cc02d7e2SAndroid Build Coastguard Worker         GRPC_CLOSURE_CREATE(DoNothing, nullptr, grpc_schedule_on_exec_ctx),
90*cc02d7e2SAndroid Build Coastguard Worker         absl::OkStatus());
91*cc02d7e2SAndroid Build Coastguard Worker   }
92*cc02d7e2SAndroid Build Coastguard Worker }
93*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureCreateAndRun);
94*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureInitAndRun(benchmark::State & state)95*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureInitAndRun(benchmark::State& state) {
96*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
97*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
98*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
99*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::Closure::Run(
100*cc02d7e2SAndroid Build Coastguard Worker         DEBUG_LOCATION,
101*cc02d7e2SAndroid Build Coastguard Worker         GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx),
102*cc02d7e2SAndroid Build Coastguard Worker         absl::OkStatus());
103*cc02d7e2SAndroid Build Coastguard Worker   }
104*cc02d7e2SAndroid Build Coastguard Worker }
105*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureInitAndRun);
106*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSchedOnExecCtx(benchmark::State & state)107*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSchedOnExecCtx(benchmark::State& state) {
108*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
109*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
110*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
111*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
112*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c, absl::OkStatus());
113*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
114*cc02d7e2SAndroid Build Coastguard Worker   }
115*cc02d7e2SAndroid Build Coastguard Worker }
116*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSchedOnExecCtx);
117*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched2OnExecCtx(benchmark::State & state)118*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched2OnExecCtx(benchmark::State& state) {
119*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
120*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
121*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
122*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
123*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
124*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
125*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c1, absl::OkStatus());
126*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c2, absl::OkStatus());
127*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
128*cc02d7e2SAndroid Build Coastguard Worker   }
129*cc02d7e2SAndroid Build Coastguard Worker }
130*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched2OnExecCtx);
131*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched3OnExecCtx(benchmark::State & state)132*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched3OnExecCtx(benchmark::State& state) {
133*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
134*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
135*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c3;
136*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
137*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
138*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, grpc_schedule_on_exec_ctx);
139*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
140*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
141*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c1, absl::OkStatus());
142*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c2, absl::OkStatus());
143*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &c3, absl::OkStatus());
144*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
145*cc02d7e2SAndroid Build Coastguard Worker   }
146*cc02d7e2SAndroid Build Coastguard Worker }
147*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched3OnExecCtx);
148*cc02d7e2SAndroid Build Coastguard Worker 
BM_AcquireMutex(benchmark::State & state)149*cc02d7e2SAndroid Build Coastguard Worker static void BM_AcquireMutex(benchmark::State& state) {
150*cc02d7e2SAndroid Build Coastguard Worker   // for comparison with the combiner stuff below
151*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu mu;
152*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu_init(&mu);
153*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
154*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
155*cc02d7e2SAndroid Build Coastguard Worker     gpr_mu_lock(&mu);
156*cc02d7e2SAndroid Build Coastguard Worker     DoNothing(nullptr, absl::OkStatus());
157*cc02d7e2SAndroid Build Coastguard Worker     gpr_mu_unlock(&mu);
158*cc02d7e2SAndroid Build Coastguard Worker   }
159*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu_destroy(&mu);
160*cc02d7e2SAndroid Build Coastguard Worker }
161*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_AcquireMutex);
162*cc02d7e2SAndroid Build Coastguard Worker 
BM_TryAcquireMutex(benchmark::State & state)163*cc02d7e2SAndroid Build Coastguard Worker static void BM_TryAcquireMutex(benchmark::State& state) {
164*cc02d7e2SAndroid Build Coastguard Worker   // for comparison with the combiner stuff below
165*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu mu;
166*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu_init(&mu);
167*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
168*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
169*cc02d7e2SAndroid Build Coastguard Worker     if (gpr_mu_trylock(&mu)) {
170*cc02d7e2SAndroid Build Coastguard Worker       DoNothing(nullptr, absl::OkStatus());
171*cc02d7e2SAndroid Build Coastguard Worker       gpr_mu_unlock(&mu);
172*cc02d7e2SAndroid Build Coastguard Worker     } else {
173*cc02d7e2SAndroid Build Coastguard Worker       abort();
174*cc02d7e2SAndroid Build Coastguard Worker     }
175*cc02d7e2SAndroid Build Coastguard Worker   }
176*cc02d7e2SAndroid Build Coastguard Worker   gpr_mu_destroy(&mu);
177*cc02d7e2SAndroid Build Coastguard Worker }
178*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_TryAcquireMutex);
179*cc02d7e2SAndroid Build Coastguard Worker 
BM_AcquireSpinlock(benchmark::State & state)180*cc02d7e2SAndroid Build Coastguard Worker static void BM_AcquireSpinlock(benchmark::State& state) {
181*cc02d7e2SAndroid Build Coastguard Worker   // for comparison with the combiner stuff below
182*cc02d7e2SAndroid Build Coastguard Worker   gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
183*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
184*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
185*cc02d7e2SAndroid Build Coastguard Worker     gpr_spinlock_lock(&mu);
186*cc02d7e2SAndroid Build Coastguard Worker     DoNothing(nullptr, absl::OkStatus());
187*cc02d7e2SAndroid Build Coastguard Worker     gpr_spinlock_unlock(&mu);
188*cc02d7e2SAndroid Build Coastguard Worker   }
189*cc02d7e2SAndroid Build Coastguard Worker }
190*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_AcquireSpinlock);
191*cc02d7e2SAndroid Build Coastguard Worker 
BM_TryAcquireSpinlock(benchmark::State & state)192*cc02d7e2SAndroid Build Coastguard Worker static void BM_TryAcquireSpinlock(benchmark::State& state) {
193*cc02d7e2SAndroid Build Coastguard Worker   // for comparison with the combiner stuff below
194*cc02d7e2SAndroid Build Coastguard Worker   gpr_spinlock mu = GPR_SPINLOCK_INITIALIZER;
195*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
196*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
197*cc02d7e2SAndroid Build Coastguard Worker     if (gpr_spinlock_trylock(&mu)) {
198*cc02d7e2SAndroid Build Coastguard Worker       DoNothing(nullptr, absl::OkStatus());
199*cc02d7e2SAndroid Build Coastguard Worker       gpr_spinlock_unlock(&mu);
200*cc02d7e2SAndroid Build Coastguard Worker     } else {
201*cc02d7e2SAndroid Build Coastguard Worker       abort();
202*cc02d7e2SAndroid Build Coastguard Worker     }
203*cc02d7e2SAndroid Build Coastguard Worker   }
204*cc02d7e2SAndroid Build Coastguard Worker }
205*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_TryAcquireSpinlock);
206*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSchedOnCombiner(benchmark::State & state)207*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSchedOnCombiner(benchmark::State& state) {
208*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner = grpc_combiner_create(
209*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine());
210*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c;
211*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c, DoNothing, nullptr, nullptr);
212*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
213*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
214*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c, absl::OkStatus());
215*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
216*cc02d7e2SAndroid Build Coastguard Worker   }
217*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner, "finished");
218*cc02d7e2SAndroid Build Coastguard Worker }
219*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSchedOnCombiner);
220*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched2OnCombiner(benchmark::State & state)221*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched2OnCombiner(benchmark::State& state) {
222*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner = grpc_combiner_create(
223*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine());
224*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
225*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
226*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
227*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
228*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
229*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
230*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c1, absl::OkStatus());
231*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c2, absl::OkStatus());
232*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
233*cc02d7e2SAndroid Build Coastguard Worker   }
234*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner, "finished");
235*cc02d7e2SAndroid Build Coastguard Worker }
236*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched2OnCombiner);
237*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched3OnCombiner(benchmark::State & state)238*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched3OnCombiner(benchmark::State& state) {
239*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner = grpc_combiner_create(
240*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine());
241*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
242*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
243*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c3;
244*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
245*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
246*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, nullptr);
247*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
248*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
249*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c1, absl::OkStatus());
250*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c2, absl::OkStatus());
251*cc02d7e2SAndroid Build Coastguard Worker     combiner->Run(&c3, absl::OkStatus());
252*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
253*cc02d7e2SAndroid Build Coastguard Worker   }
254*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner, "finished");
255*cc02d7e2SAndroid Build Coastguard Worker }
256*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched3OnCombiner);
257*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched2OnTwoCombiners(benchmark::State & state)258*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched2OnTwoCombiners(benchmark::State& state) {
259*cc02d7e2SAndroid Build Coastguard Worker   std::shared_ptr<grpc_event_engine::experimental::EventEngine> engine =
260*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine();
261*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner1 = grpc_combiner_create(engine);
262*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner2 = grpc_combiner_create(engine);
263*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
264*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
265*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
266*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
267*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
268*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
269*cc02d7e2SAndroid Build Coastguard Worker     combiner1->Run(&c1, absl::OkStatus());
270*cc02d7e2SAndroid Build Coastguard Worker     combiner2->Run(&c2, absl::OkStatus());
271*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
272*cc02d7e2SAndroid Build Coastguard Worker   }
273*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner1, "finished");
274*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner2, "finished");
275*cc02d7e2SAndroid Build Coastguard Worker }
276*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched2OnTwoCombiners);
277*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureSched4OnTwoCombiners(benchmark::State & state)278*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureSched4OnTwoCombiners(benchmark::State& state) {
279*cc02d7e2SAndroid Build Coastguard Worker   std::shared_ptr<grpc_event_engine::experimental::EventEngine> engine =
280*cc02d7e2SAndroid Build Coastguard Worker       grpc_event_engine::experimental::CreateEventEngine();
281*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner1 = grpc_combiner_create(engine);
282*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::Combiner* combiner2 = grpc_combiner_create(engine);
283*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c1;
284*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c2;
285*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c3;
286*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure c4;
287*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c1, DoNothing, nullptr, nullptr);
288*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c2, DoNothing, nullptr, nullptr);
289*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c3, DoNothing, nullptr, nullptr);
290*cc02d7e2SAndroid Build Coastguard Worker   GRPC_CLOSURE_INIT(&c4, DoNothing, nullptr, nullptr);
291*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
292*cc02d7e2SAndroid Build Coastguard Worker   for (auto _ : state) {
293*cc02d7e2SAndroid Build Coastguard Worker     combiner1->Run(&c1, absl::OkStatus());
294*cc02d7e2SAndroid Build Coastguard Worker     combiner2->Run(&c2, absl::OkStatus());
295*cc02d7e2SAndroid Build Coastguard Worker     combiner1->Run(&c3, absl::OkStatus());
296*cc02d7e2SAndroid Build Coastguard Worker     combiner2->Run(&c4, absl::OkStatus());
297*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Get()->Flush();
298*cc02d7e2SAndroid Build Coastguard Worker   }
299*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner1, "finished");
300*cc02d7e2SAndroid Build Coastguard Worker   GRPC_COMBINER_UNREF(combiner2, "finished");
301*cc02d7e2SAndroid Build Coastguard Worker }
302*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureSched4OnTwoCombiners);
303*cc02d7e2SAndroid Build Coastguard Worker 
304*cc02d7e2SAndroid Build Coastguard Worker // Helper that continuously reschedules the same closure against something until
305*cc02d7e2SAndroid Build Coastguard Worker // the benchmark is complete
306*cc02d7e2SAndroid Build Coastguard Worker class Rescheduler {
307*cc02d7e2SAndroid Build Coastguard Worker  public:
Rescheduler(benchmark::State & state)308*cc02d7e2SAndroid Build Coastguard Worker   explicit Rescheduler(benchmark::State& state) : state_(state) {
309*cc02d7e2SAndroid Build Coastguard Worker     GRPC_CLOSURE_INIT(&closure_, Step, this, nullptr);
310*cc02d7e2SAndroid Build Coastguard Worker   }
311*cc02d7e2SAndroid Build Coastguard Worker 
ScheduleFirst()312*cc02d7e2SAndroid Build Coastguard Worker   void ScheduleFirst() {
313*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION, &closure_, absl::OkStatus());
314*cc02d7e2SAndroid Build Coastguard Worker   }
315*cc02d7e2SAndroid Build Coastguard Worker 
ScheduleFirstAgainstDifferentScheduler()316*cc02d7e2SAndroid Build Coastguard Worker   void ScheduleFirstAgainstDifferentScheduler() {
317*cc02d7e2SAndroid Build Coastguard Worker     grpc_core::ExecCtx::Run(DEBUG_LOCATION,
318*cc02d7e2SAndroid Build Coastguard Worker                             GRPC_CLOSURE_CREATE(Step, this, nullptr),
319*cc02d7e2SAndroid Build Coastguard Worker                             absl::OkStatus());
320*cc02d7e2SAndroid Build Coastguard Worker   }
321*cc02d7e2SAndroid Build Coastguard Worker 
322*cc02d7e2SAndroid Build Coastguard Worker  private:
323*cc02d7e2SAndroid Build Coastguard Worker   benchmark::State& state_;
324*cc02d7e2SAndroid Build Coastguard Worker   grpc_closure closure_;
325*cc02d7e2SAndroid Build Coastguard Worker 
Step(void * arg,grpc_error_handle)326*cc02d7e2SAndroid Build Coastguard Worker   static void Step(void* arg, grpc_error_handle /*error*/) {
327*cc02d7e2SAndroid Build Coastguard Worker     Rescheduler* self = static_cast<Rescheduler*>(arg);
328*cc02d7e2SAndroid Build Coastguard Worker     if (self->state_.KeepRunning()) {
329*cc02d7e2SAndroid Build Coastguard Worker       grpc_core::ExecCtx::Run(DEBUG_LOCATION, &self->closure_,
330*cc02d7e2SAndroid Build Coastguard Worker                               absl::OkStatus());
331*cc02d7e2SAndroid Build Coastguard Worker     }
332*cc02d7e2SAndroid Build Coastguard Worker   }
333*cc02d7e2SAndroid Build Coastguard Worker };
334*cc02d7e2SAndroid Build Coastguard Worker 
BM_ClosureReschedOnExecCtx(benchmark::State & state)335*cc02d7e2SAndroid Build Coastguard Worker static void BM_ClosureReschedOnExecCtx(benchmark::State& state) {
336*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx exec_ctx;
337*cc02d7e2SAndroid Build Coastguard Worker   Rescheduler r(state);
338*cc02d7e2SAndroid Build Coastguard Worker   r.ScheduleFirst();
339*cc02d7e2SAndroid Build Coastguard Worker   grpc_core::ExecCtx::Get()->Flush();
340*cc02d7e2SAndroid Build Coastguard Worker }
341*cc02d7e2SAndroid Build Coastguard Worker BENCHMARK(BM_ClosureReschedOnExecCtx);
342*cc02d7e2SAndroid Build Coastguard Worker 
343*cc02d7e2SAndroid Build Coastguard Worker // Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
344*cc02d7e2SAndroid Build Coastguard Worker // and others do not. This allows us to support both modes.
345*cc02d7e2SAndroid Build Coastguard Worker namespace benchmark {
RunTheBenchmarksNamespaced()346*cc02d7e2SAndroid Build Coastguard Worker void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
347*cc02d7e2SAndroid Build Coastguard Worker }  // namespace benchmark
348*cc02d7e2SAndroid Build Coastguard Worker 
main(int argc,char ** argv)349*cc02d7e2SAndroid Build Coastguard Worker int main(int argc, char** argv) {
350*cc02d7e2SAndroid Build Coastguard Worker   grpc::testing::TestEnvironment env(&argc, argv);
351*cc02d7e2SAndroid Build Coastguard Worker   LibraryInitializer libInit;
352*cc02d7e2SAndroid Build Coastguard Worker   ::benchmark::Initialize(&argc, argv);
353*cc02d7e2SAndroid Build Coastguard Worker   grpc::testing::InitTest(&argc, &argv, false);
354*cc02d7e2SAndroid Build Coastguard Worker   benchmark::RunTheBenchmarksNamespaced();
355*cc02d7e2SAndroid Build Coastguard Worker   return 0;
356*cc02d7e2SAndroid Build Coastguard Worker }
357