Home | History | Annotate | Download | only in transport
      1 /*
      2  *
      3  * Copyright 2016 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 #ifndef GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
     20 #define GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H
     21 
     22 #include <grpc/support/port_platform.h>
     23 
     24 #include <inttypes.h>
     25 #include <stdbool.h>
     26 #include <stdint.h>
     27 
     28 #include <grpc/support/log.h>
     29 #include <grpc/support/time.h>
     30 
     31 #include "src/core/lib/debug/trace.h"
     32 #include "src/core/lib/iomgr/exec_ctx.h"
     33 
     34 extern grpc_core::TraceFlag grpc_bdp_estimator_trace;
     35 
     36 namespace grpc_core {
     37 
     38 class BdpEstimator {
     39  public:
     40   explicit BdpEstimator(const char* name);
     41   ~BdpEstimator() {}
     42 
     43   int64_t EstimateBdp() const { return estimate_; }
     44   double EstimateBandwidth() const { return bw_est_; }
     45 
     46   void AddIncomingBytes(int64_t num_bytes) { accumulator_ += num_bytes; }
     47 
     48   // Schedule a ping: call in response to receiving a true from
     49   // grpc_bdp_estimator_add_incoming_bytes once a ping has been scheduled by a
     50   // transport (but not necessarily started)
     51   void SchedulePing() {
     52     if (grpc_bdp_estimator_trace.enabled()) {
     53       gpr_log(GPR_INFO, "bdp[%s]:sched acc=%" PRId64 " est=%" PRId64, name_,
     54               accumulator_, estimate_);
     55     }
     56     GPR_ASSERT(ping_state_ == PingState::UNSCHEDULED);
     57     ping_state_ = PingState::SCHEDULED;
     58     accumulator_ = 0;
     59   }
     60 
     61   // Start a ping: call after calling grpc_bdp_estimator_schedule_ping and
     62   // once
     63   // the ping is on the wire
     64   void StartPing() {
     65     if (grpc_bdp_estimator_trace.enabled()) {
     66       gpr_log(GPR_INFO, "bdp[%s]:start acc=%" PRId64 " est=%" PRId64, name_,
     67               accumulator_, estimate_);
     68     }
     69     GPR_ASSERT(ping_state_ == PingState::SCHEDULED);
     70     ping_state_ = PingState::STARTED;
     71     accumulator_ = 0;
     72     ping_start_time_ = gpr_now(GPR_CLOCK_MONOTONIC);
     73   }
     74 
     75   // Completes a previously started ping, returns when to schedule the next one
     76   grpc_millis CompletePing();
     77 
     78  private:
     79   enum class PingState { UNSCHEDULED, SCHEDULED, STARTED };
     80 
     81   PingState ping_state_;
     82   int64_t accumulator_;
     83   int64_t estimate_;
     84   // when was the current ping started?
     85   gpr_timespec ping_start_time_;
     86   int inter_ping_delay_;
     87   int stable_estimate_count_;
     88   double bw_est_;
     89   const char* name_;
     90 };
     91 
     92 }  // namespace grpc_core
     93 
     94 #endif /* GRPC_CORE_LIB_TRANSPORT_BDP_ESTIMATOR_H */
     95