blob: 60b9fba0838b97aa2806fadbb7794c387c707928 [file] [log] [blame]
Craig Tiller064db442016-10-20 09:34:58 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2016 gRPC authors.
Craig Tiller064db442016-10-20 09:34:58 -07004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
Craig Tiller064db442016-10-20 09:34:58 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Craig Tiller064db442016-10-20 09:34:58 -070010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
Craig Tiller064db442016-10-20 09:34:58 -070016 *
17 */
18
19#ifndef GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
20#define GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
21
Craig Tiller9fc49c92017-10-12 15:53:36 -070022#include <inttypes.h>
Craig Tiller064db442016-10-20 09:34:58 -070023#include <stdbool.h>
24#include <stdint.h>
Craig Tiller92226062017-10-08 21:16:12 -070025
26#include <grpc/support/log.h>
27#include <grpc/support/time.h>
28
Craig Tiller84f75d42017-05-03 13:06:35 -070029#include "src/core/lib/debug/trace.h"
Craig Tiller43c1b5f2017-10-02 14:42:49 -070030#include "src/core/lib/iomgr/exec_ctx.h"
Craig Tiller064db442016-10-20 09:34:58 -070031
Craig Tiller84f75d42017-05-03 13:06:35 -070032extern grpc_tracer_flag grpc_bdp_estimator_trace;
Craig Tillerefbd7c22017-01-27 14:07:44 -080033
Craig Tiller92226062017-10-08 21:16:12 -070034namespace grpc_core {
Craig Tillerc0118b42016-12-29 12:17:57 -080035
Craig Tiller92226062017-10-08 21:16:12 -070036class BdpEstimator {
37 public:
38 explicit BdpEstimator(const char *name);
Craig Tiller3be5e1e2017-10-08 21:48:13 -070039 ~BdpEstimator() {}
Craig Tiller92226062017-10-08 21:16:12 -070040
41 // Returns true if a reasonable estimate could be obtained
Craig Tiller0cdfb872017-10-08 21:19:38 -070042 bool EstimateBdp(int64_t *estimate_out) const {
Craig Tiller92226062017-10-08 21:16:12 -070043 *estimate_out = estimate_;
44 return true;
45 }
Craig Tiller0cdfb872017-10-08 21:19:38 -070046 bool EstimateBandwidth(double *bw_out) const {
Craig Tiller92226062017-10-08 21:16:12 -070047 *bw_out = bw_est_;
48 return true;
49 }
50
51 void AddIncomingBytes(int64_t num_bytes) { accumulator_ += num_bytes; }
52
53 // Returns true if the user should schedule a ping
Craig Tiller0cdfb872017-10-08 21:19:38 -070054 bool NeedPing(grpc_exec_ctx *exec_ctx) const {
Craig Tiller92226062017-10-08 21:16:12 -070055 switch (ping_state_) {
56 case PingState::UNSCHEDULED:
57 return grpc_exec_ctx_now(exec_ctx) >= next_ping_scheduled_;
58 case PingState::SCHEDULED:
59 case PingState::STARTED:
60 return false;
61 }
62 GPR_UNREACHABLE_CODE(return false);
63 }
64
65 // Schedule a ping: call in response to receiving a true from
66 // grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a
67 // transport (but not necessarily started)
68 void SchedulePing() {
69 if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
70 gpr_log(GPR_DEBUG, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_,
71 accumulator_, estimate_);
72 }
73 GPR_ASSERT(ping_state_ == PingState::UNSCHEDULED);
74 ping_state_ = PingState::SCHEDULED;
75 accumulator_ = 0;
76 }
77
78 // Start a ping: call after calling grpc_bdp_estimator_schedule_ping and
79 // once
80 // the ping is on the wire
81 void StartPing() {
82 if (GRPC_TRACER_ON(grpc_bdp_estimator_trace)) {
83 gpr_log(GPR_DEBUG, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_,
84 accumulator_, estimate_);
85 }
86 GPR_ASSERT(ping_state_ == PingState::SCHEDULED);
87 ping_state_ = PingState::STARTED;
88 accumulator_ = 0;
89 ping_start_time_ = gpr_now(GPR_CLOCK_MONOTONIC);
90 }
91
92 // Completes a previously started ping
93 void CompletePing(grpc_exec_ctx *exec_ctx);
94
95 private:
96 enum class PingState { UNSCHEDULED, SCHEDULED, STARTED };
97
98 PingState ping_state_;
99 int64_t accumulator_;
100 int64_t estimate_;
Craig Tiller43c1b5f2017-10-02 14:42:49 -0700101 // when was the current ping started?
Craig Tiller92226062017-10-08 21:16:12 -0700102 gpr_timespec ping_start_time_;
Craig Tiller43c1b5f2017-10-02 14:42:49 -0700103 // when should the next ping start?
Craig Tiller92226062017-10-08 21:16:12 -0700104 grpc_millis next_ping_scheduled_;
105 int inter_ping_delay_;
106 int stable_estimate_count_;
107 double bw_est_;
108 const char *name_;
109};
Craig Tiller064db442016-10-20 09:34:58 -0700110
Craig Tiller92226062017-10-08 21:16:12 -0700111} // namespace grpc_core
Craig Tiller064db442016-10-20 09:34:58 -0700112
Craig Tiller92226062017-10-08 21:16:12 -0700113#endif /* GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H */