1 /*
2 *
3 * Copyright 2019 gRPC authors.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 */
18
19 /* Benchmark gRPC end2end in various configurations */
20
21 #ifndef TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H
22 #define TEST_CPP_MICROBENCHMARKS_CALLBACK_UNARY_PING_PONG_H
23
24 #include <benchmark/benchmark.h>
25 #include <sstream>
26 #include "src/core/lib/profiling/timers.h"
27 #include "src/proto/grpc/testing/echo.grpc.pb.h"
28 #include "test/cpp/microbenchmarks/callback_test_service.h"
29 #include "test/cpp/microbenchmarks/fullstack_context_mutators.h"
30 #include "test/cpp/microbenchmarks/fullstack_fixtures.h"
31
32 namespace grpc {
33 namespace testing {
34
35 /*******************************************************************************
36 * BENCHMARKING KERNELS
37 */
38
SendCallbackUnaryPingPong(benchmark::State * state,ClientContext * cli_ctx,EchoRequest * request,EchoResponse * response,EchoTestService::Stub * stub_,bool * done,std::mutex * mu,std::condition_variable * cv)39 void SendCallbackUnaryPingPong(benchmark::State* state, ClientContext* cli_ctx,
40 EchoRequest* request, EchoResponse* response,
41 EchoTestService::Stub* stub_, bool* done,
42 std::mutex* mu, std::condition_variable* cv) {
43 int response_msgs_size = state->range(1);
44 cli_ctx->AddMetadata(kServerMessageSize, grpc::to_string(response_msgs_size));
45 stub_->experimental_async()->Echo(
46 cli_ctx, request, response,
47 [state, cli_ctx, request, response, stub_, done, mu, cv](Status s) {
48 GPR_ASSERT(s.ok());
49 if (state->KeepRunning()) {
50 cli_ctx->~ClientContext();
51 new (cli_ctx) ClientContext();
52 SendCallbackUnaryPingPong(state, cli_ctx, request, response, stub_,
53 done, mu, cv);
54 } else {
55 std::lock_guard<std::mutex> l(*mu);
56 *done = true;
57 cv->notify_one();
58 }
59 });
60 };
61
62 template <class Fixture, class ClientContextMutator, class ServerContextMutator>
BM_CallbackUnaryPingPong(benchmark::State & state)63 static void BM_CallbackUnaryPingPong(benchmark::State& state) {
64 int request_msgs_size = state.range(0);
65 int response_msgs_size = state.range(1);
66 CallbackStreamingTestService service;
67 std::unique_ptr<Fixture> fixture(new Fixture(&service));
68 std::unique_ptr<EchoTestService::Stub> stub_(
69 EchoTestService::NewStub(fixture->channel()));
70 EchoRequest request;
71 EchoResponse response;
72 ClientContext cli_ctx;
73
74 if (request_msgs_size > 0) {
75 request.set_message(std::string(request_msgs_size, 'a'));
76 } else {
77 request.set_message("");
78 }
79
80 std::mutex mu;
81 std::condition_variable cv;
82 bool done = false;
83 if (state.KeepRunning()) {
84 GPR_TIMER_SCOPE("BenchmarkCycle", 0);
85 SendCallbackUnaryPingPong(&state, &cli_ctx, &request, &response,
86 stub_.get(), &done, &mu, &cv);
87 }
88 std::unique_lock<std::mutex> l(mu);
89 while (!done) {
90 cv.wait(l);
91 }
92 fixture->Finish(state);
93 fixture.reset();
94 state.SetBytesProcessed(request_msgs_size * state.iterations() +
95 response_msgs_size * state.iterations());
96 }
97
98 } // namespace testing
99 } // namespace grpc
100
101 #endif // TEST_CPP_MICROBENCHMARKS_FULLSTACK_UNARY_PING_PONG_H
102