Home | History | Annotate | Download | only in congestion_control
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/quic/congestion_control/paced_sender.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "net/quic/quic_protocol.h"
     10 
     11 namespace net {
     12 
     13 // To prevent too aggressive pacing we allow the following packet burst size.
     14 const int64 kMinPacketBurstSize = 2;
     15 // Max estimated time between calls to TimeUntilSend and
     16 // AvailableCongestionWindow.
     17 const int64 kMaxSchedulingDelayUs = 2000;
     18 
     19 PacedSender::PacedSender(QuicBandwidth estimate, QuicByteCount max_segment_size)
     20     : leaky_bucket_(estimate),
     21       pace_(estimate),
     22       max_segment_size_(kDefaultMaxPacketSize) {
     23 }
     24 
     25 void PacedSender::set_max_segment_size(QuicByteCount max_segment_size) {
     26   max_segment_size_ = max_segment_size;
     27 }
     28 
     29 void PacedSender::UpdateBandwidthEstimate(QuicTime now,
     30                                           QuicBandwidth estimate) {
     31   leaky_bucket_.SetDrainingRate(now, estimate);
     32   pace_ = estimate;
     33 }
     34 
     35 void PacedSender::OnPacketSent(QuicTime now, QuicByteCount bytes) {
     36   leaky_bucket_.Add(now, bytes);
     37 }
     38 
     39 QuicTime::Delta PacedSender::TimeUntilSend(QuicTime now,
     40                                            QuicTime::Delta time_until_send) {
     41   if (time_until_send.ToMicroseconds() >= kMaxSchedulingDelayUs) {
     42     return time_until_send;
     43   }
     44   // Pace the data.
     45   QuicByteCount pacing_window = pace_.ToBytesPerPeriod(
     46       QuicTime::Delta::FromMicroseconds(kMaxSchedulingDelayUs));
     47   QuicByteCount min_window_size = kMinPacketBurstSize *  max_segment_size_;
     48   pacing_window = std::max(pacing_window, min_window_size);
     49 
     50   if (pacing_window > leaky_bucket_.BytesPending(now)) {
     51     // We have not filled our pacing window yet.
     52     return time_until_send;
     53   }
     54   return leaky_bucket_.TimeRemaining(now);
     55 }
     56 
     57 }  // namespace net
     58