Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / net / quic / congestion_control / pacing_sender.cc
blob21dd4f34c0b77ca3a0612493a42b0f68cd7af56b
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
3 // found in the LICENSE file.
5 #include "net/quic/congestion_control/pacing_sender.h"
7 using std::min;
9 namespace net {
11 PacingSender::PacingSender(SendAlgorithmInterface* sender,
12 QuicTime::Delta alarm_granularity,
13 uint32 initial_packet_burst)
14 : sender_(sender),
15 alarm_granularity_(alarm_granularity),
16 initial_packet_burst_(initial_packet_burst),
17 burst_tokens_(initial_packet_burst),
18 last_delayed_packet_sent_time_(QuicTime::Zero()),
19 ideal_next_packet_send_time_(QuicTime::Zero()),
20 was_last_send_delayed_(false) {
23 PacingSender::~PacingSender() {}
25 void PacingSender::SetFromConfig(const QuicConfig& config,
26 Perspective perspective) {
27 sender_->SetFromConfig(config, perspective);
30 void PacingSender::ResumeConnectionState(
31 const CachedNetworkParameters& cached_network_params,
32 bool max_bandwidth_resumption) {
33 sender_->ResumeConnectionState(cached_network_params,
34 max_bandwidth_resumption);
37 void PacingSender::SetNumEmulatedConnections(int num_connections) {
38 sender_->SetNumEmulatedConnections(num_connections);
41 void PacingSender::SetMaxCongestionWindow(QuicByteCount max_congestion_window) {
42 sender_->SetMaxCongestionWindow(max_congestion_window);
45 void PacingSender::OnCongestionEvent(bool rtt_updated,
46 QuicByteCount bytes_in_flight,
47 const CongestionVector& acked_packets,
48 const CongestionVector& lost_packets) {
49 sender_->OnCongestionEvent(
50 rtt_updated, bytes_in_flight, acked_packets, lost_packets);
53 bool PacingSender::OnPacketSent(
54 QuicTime sent_time,
55 QuicByteCount bytes_in_flight,
56 QuicPacketNumber packet_number,
57 QuicByteCount bytes,
58 HasRetransmittableData has_retransmittable_data) {
59 const bool in_flight =
60 sender_->OnPacketSent(sent_time, bytes_in_flight, packet_number, bytes,
61 has_retransmittable_data);
62 if (has_retransmittable_data != HAS_RETRANSMITTABLE_DATA) {
63 return in_flight;
65 if (bytes_in_flight == 0) {
66 // Add more burst tokens anytime the connection is leaving quiescence, but
67 // limit it to the equivalent of a single bulk write, not exceeding the
68 // current CWND in packets.
69 burst_tokens_ = min(
70 initial_packet_burst_,
71 static_cast<uint32>(sender_->GetCongestionWindow() / kDefaultTCPMSS));
73 if (burst_tokens_ > 0) {
74 --burst_tokens_;
75 was_last_send_delayed_ = false;
76 last_delayed_packet_sent_time_ = QuicTime::Zero();
77 ideal_next_packet_send_time_ = QuicTime::Zero();
78 return in_flight;
80 // The next packet should be sent as soon as the current packets has been
81 // transferred.
82 QuicTime::Delta delay = PacingRate().TransferTime(bytes);
83 // If the last send was delayed, and the alarm took a long time to get
84 // invoked, allow the connection to make up for lost time.
85 if (was_last_send_delayed_) {
86 ideal_next_packet_send_time_ = ideal_next_packet_send_time_.Add(delay);
87 // The send was application limited if it takes longer than the
88 // pacing delay between sent packets.
89 const bool application_limited =
90 last_delayed_packet_sent_time_.IsInitialized() &&
91 sent_time > last_delayed_packet_sent_time_.Add(delay);
92 const bool making_up_for_lost_time =
93 ideal_next_packet_send_time_ <= sent_time;
94 // As long as we're making up time and not application limited,
95 // continue to consider the packets delayed, allowing the packets to be
96 // sent immediately.
97 if (making_up_for_lost_time && !application_limited) {
98 last_delayed_packet_sent_time_ = sent_time;
99 } else {
100 was_last_send_delayed_ = false;
101 last_delayed_packet_sent_time_ = QuicTime::Zero();
103 } else {
104 ideal_next_packet_send_time_ = QuicTime::Max(
105 ideal_next_packet_send_time_.Add(delay), sent_time.Add(delay));
107 return in_flight;
110 void PacingSender::OnRetransmissionTimeout(bool packets_retransmitted) {
111 sender_->OnRetransmissionTimeout(packets_retransmitted);
114 QuicTime::Delta PacingSender::TimeUntilSend(
115 QuicTime now,
116 QuicByteCount bytes_in_flight,
117 HasRetransmittableData has_retransmittable_data) const {
118 QuicTime::Delta time_until_send =
119 sender_->TimeUntilSend(now, bytes_in_flight, has_retransmittable_data);
120 if (burst_tokens_ > 0 || bytes_in_flight == 0) {
121 // Don't pace if we have burst tokens available or leaving quiescence.
122 return time_until_send;
125 if (!time_until_send.IsZero()) {
126 DCHECK(time_until_send.IsInfinite());
127 // The underlying sender prevents sending.
128 return time_until_send;
131 if (has_retransmittable_data == NO_RETRANSMITTABLE_DATA) {
132 // Don't pace ACK packets, since they do not count against CWND and do not
133 // cause CWND to grow.
134 return QuicTime::Delta::Zero();
137 // If the next send time is within the alarm granularity, send immediately.
138 if (ideal_next_packet_send_time_ > now.Add(alarm_granularity_)) {
139 DVLOG(1) << "Delaying packet: "
140 << ideal_next_packet_send_time_.Subtract(now).ToMicroseconds();
141 was_last_send_delayed_ = true;
142 return ideal_next_packet_send_time_.Subtract(now);
145 DVLOG(1) << "Sending packet now";
146 return QuicTime::Delta::Zero();
149 QuicBandwidth PacingSender::PacingRate() const {
150 return sender_->PacingRate();
153 QuicBandwidth PacingSender::BandwidthEstimate() const {
154 return sender_->BandwidthEstimate();
157 QuicTime::Delta PacingSender::RetransmissionDelay() const {
158 return sender_->RetransmissionDelay();
161 QuicByteCount PacingSender::GetCongestionWindow() const {
162 return sender_->GetCongestionWindow();
165 bool PacingSender::InSlowStart() const {
166 return sender_->InSlowStart();
169 bool PacingSender::InRecovery() const {
170 return sender_->InRecovery();
173 QuicByteCount PacingSender::GetSlowStartThreshold() const {
174 return sender_->GetSlowStartThreshold();
177 CongestionControlType PacingSender::GetCongestionControlType() const {
178 return sender_->GetCongestionControlType();
181 } // namespace net