| OLD | NEW |
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/congestion_control/pacing_sender.h" | 5 #include "net/quic/congestion_control/pacing_sender.h" |
| 6 | 6 |
| 7 namespace net { | 7 namespace net { |
| 8 | 8 |
| 9 PacingSender::PacingSender(SendAlgorithmInterface* sender, | 9 PacingSender::PacingSender(SendAlgorithmInterface* sender, |
| 10 QuicTime::Delta alarm_granularity) | 10 QuicTime::Delta alarm_granularity) |
| 11 : sender_(sender), | 11 : sender_(sender), |
| 12 alarm_granularity_(alarm_granularity), | 12 alarm_granularity_(alarm_granularity), |
| 13 last_delayed_packet_sent_time_(QuicTime::Zero()), |
| 13 next_packet_send_time_(QuicTime::Zero()), | 14 next_packet_send_time_(QuicTime::Zero()), |
| 14 was_last_send_delayed_(false), | 15 was_last_send_delayed_(false), |
| 15 has_valid_rtt_(false) { | 16 has_valid_rtt_(false) { |
| 16 } | 17 } |
| 17 | 18 |
| 18 PacingSender::~PacingSender() {} | 19 PacingSender::~PacingSender() {} |
| 19 | 20 |
| 20 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { | 21 void PacingSender::SetFromConfig(const QuicConfig& config, bool is_server) { |
| 21 sender_->SetFromConfig(config, is_server); | 22 sender_->SetFromConfig(config, is_server); |
| 22 } | 23 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 47 HasRetransmittableData has_retransmittable_data) { | 48 HasRetransmittableData has_retransmittable_data) { |
| 48 // Only pace data packets once we have an updated RTT. | 49 // Only pace data packets once we have an updated RTT. |
| 49 if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) { | 50 if (has_retransmittable_data == HAS_RETRANSMITTABLE_DATA && has_valid_rtt_) { |
| 50 // The next packet should be sent as soon as the current packets has | 51 // The next packet should be sent as soon as the current packets has |
| 51 // been transferred. We pace at twice the rate of the underlying | 52 // been transferred. We pace at twice the rate of the underlying |
| 52 // sender's bandwidth estimate to help ensure that pacing doesn't become | 53 // sender's bandwidth estimate to help ensure that pacing doesn't become |
| 53 // a bottleneck. | 54 // a bottleneck. |
| 54 const float kPacingAggression = 2; | 55 const float kPacingAggression = 2; |
| 55 QuicTime::Delta delay = | 56 QuicTime::Delta delay = |
| 56 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); | 57 BandwidthEstimate().Scale(kPacingAggression).TransferTime(bytes); |
| 57 next_packet_send_time_ = next_packet_send_time_.Add(delay); | 58 // If the last send was delayed, and the alarm took a long time to get |
| 59 // invoked, allow the connection to make up for lost time. |
| 60 if (was_last_send_delayed_) { |
| 61 next_packet_send_time_ = next_packet_send_time_.Add(delay); |
| 62 // As long as we're making up time and not application limited, |
| 63 // continue to consider the packets delayed. |
| 64 // The send was application limited if it takes longer than the |
| 65 // pacing delay between sent packets. |
| 66 const bool application_limited = |
| 67 last_delayed_packet_sent_time_.IsInitialized() && |
| 68 sent_time > last_delayed_packet_sent_time_.Add(delay); |
| 69 const bool making_up_for_lost_time = next_packet_send_time_ > sent_time; |
| 70 if (making_up_for_lost_time || application_limited) { |
| 71 was_last_send_delayed_ = false; |
| 72 last_delayed_packet_sent_time_ = QuicTime::Zero(); |
| 73 } else { |
| 74 last_delayed_packet_sent_time_ = sent_time; |
| 75 } |
| 76 } else { |
| 77 next_packet_send_time_ = |
| 78 QuicTime::Max(next_packet_send_time_.Add(delay), |
| 79 sent_time.Add(delay).Subtract(alarm_granularity_)); |
| 80 } |
| 58 } | 81 } |
| 59 return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, | 82 return sender_->OnPacketSent(sent_time, bytes_in_flight, sequence_number, |
| 60 bytes, has_retransmittable_data); | 83 bytes, has_retransmittable_data); |
| 61 } | 84 } |
| 62 | 85 |
| 63 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { | 86 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) { |
| 64 sender_->OnRetransmissionTimeout(packets_retransmitted); | 87 sender_->OnRetransmissionTimeout(packets_retransmitted); |
| 65 } | 88 } |
| 66 | 89 |
| 67 QuicTime::Delta PacingSender::TimeUntilSend( | 90 QuicTime::Delta PacingSender::TimeUntilSend( |
| (...skipping 12 matching lines...) Expand all Loading... |
| 80 // The underlying sender prevents sending. | 103 // The underlying sender prevents sending. |
| 81 return time_until_send; | 104 return time_until_send; |
| 82 } | 105 } |
| 83 | 106 |
| 84 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { | 107 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) { |
| 85 // Don't pace ACK packets, since they do not count against CWND and do not | 108 // Don't pace ACK packets, since they do not count against CWND and do not |
| 86 // cause CWND to grow. | 109 // cause CWND to grow. |
| 87 return QuicTime::Delta::Zero(); | 110 return QuicTime::Delta::Zero(); |
| 88 } | 111 } |
| 89 | 112 |
| 90 if (!was_last_send_delayed_ && | 113 // If the next send time is within the alarm granularity, send immediately. |
| 91 (!next_packet_send_time_.IsInitialized() || | |
| 92 now > next_packet_send_time_.Add(alarm_granularity_))) { | |
| 93 // An alarm did not go off late, instead the application is "slow" | |
| 94 // delivering data. In this case, we restrict the amount of lost time | |
| 95 // that we can make up for. | |
| 96 next_packet_send_time_ = now.Subtract(alarm_granularity_); | |
| 97 } | |
| 98 | |
| 99 // If the end of the epoch is far enough in the future, delay the send. | |
| 100 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { | 114 if (next_packet_send_time_ > now.Add(alarm_granularity_)) { |
| 101 was_last_send_delayed_ = true; | |
| 102 DVLOG(1) << "Delaying packet: " | 115 DVLOG(1) << "Delaying packet: " |
| 103 << next_packet_send_time_.Subtract(now).ToMicroseconds(); | 116 << next_packet_send_time_.Subtract(now).ToMicroseconds(); |
| 117 was_last_send_delayed_ = true; |
| 104 return next_packet_send_time_.Subtract(now); | 118 return next_packet_send_time_.Subtract(now); |
| 105 } | 119 } |
| 106 | 120 |
| 107 // Sent it immediately. The epoch end will be adjusted in OnPacketSent. | |
| 108 was_last_send_delayed_ = false; | |
| 109 DVLOG(1) << "Sending packet now"; | 121 DVLOG(1) << "Sending packet now"; |
| 110 return QuicTime::Delta::Zero(); | 122 return QuicTime::Delta::Zero(); |
| 111 } | 123 } |
| 112 | 124 |
| 113 QuicBandwidth PacingSender::BandwidthEstimate() const { | 125 QuicBandwidth PacingSender::BandwidthEstimate() const { |
| 114 return sender_->BandwidthEstimate(); | 126 return sender_->BandwidthEstimate(); |
| 115 } | 127 } |
| 116 | 128 |
| 117 QuicTime::Delta PacingSender::RetransmissionDelay() const { | 129 QuicTime::Delta PacingSender::RetransmissionDelay() const { |
| 118 return sender_->RetransmissionDelay(); | 130 return sender_->RetransmissionDelay(); |
| 119 } | 131 } |
| 120 | 132 |
| 121 QuicByteCount PacingSender::GetCongestionWindow() const { | 133 QuicByteCount PacingSender::GetCongestionWindow() const { |
| 122 return sender_->GetCongestionWindow(); | 134 return sender_->GetCongestionWindow(); |
| 123 } | 135 } |
| 124 | 136 |
| 125 } // namespace net | 137 } // namespace net |
| OLD | NEW |