OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/send_algorithm_simulator.h" | 5 #include "net/quic/congestion_control/send_algorithm_simulator.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
99 DVLOG(1) << "Sending, advancing time:" | 99 DVLOG(1) << "Sending, advancing time:" |
100 << send_event.time_delta.ToMicroseconds() << "us"; | 100 << send_event.time_delta.ToMicroseconds() << "us"; |
101 clock_->AdvanceTime(send_event.time_delta); | 101 clock_->AdvanceTime(send_event.time_delta); |
102 SendDataNow(send_event.transfer); | 102 SendDataNow(send_event.transfer); |
103 bytes_sent += kPacketSize; | 103 bytes_sent += kPacketSize; |
104 } | 104 } |
105 } | 105 } |
106 } | 106 } |
107 | 107 |
108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { | 108 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() { |
109 QuicTime::Delta send_time = QuicTime::Delta::Infinite(); | 109 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite(); |
110 Transfer* transfer = NULL; | 110 Transfer* transfer = NULL; |
111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); | 111 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
112 it != pending_transfers_.end(); ++it) { | 112 it != pending_transfers_.end(); ++it) { |
113 // If the flow hasn't started, return the start time. | |
114 if (clock_->Now() < it->start_time) { | |
115 send_time = it->start_time.Subtract(clock_->Now()); | |
116 transfer = &(*it); | |
117 continue; | |
118 } | |
119 // If we've already sent enough bytes, wait for them to be acked. | 113 // If we've already sent enough bytes, wait for them to be acked. |
120 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { | 114 if (it->bytes_acked + it->bytes_in_flight >= it->num_bytes) { |
121 continue; | 115 continue; |
122 } | 116 } |
123 QuicTime::Delta transfer_send_time = | 117 // If the flow hasn't started, use the start time. |
124 it->sender->send_algorithm->TimeUntilSend( | 118 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now()); |
125 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); | 119 if (clock_->Now() >= it->start_time) { |
126 if (transfer_send_time < send_time) { | 120 transfer_send_time = |
127 send_time = transfer_send_time; | 121 it->sender->send_algorithm->TimeUntilSend( |
| 122 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA); |
| 123 } |
| 124 if (transfer_send_time < next_send_time) { |
| 125 next_send_time = transfer_send_time; |
128 transfer = &(*it); | 126 transfer = &(*it); |
129 } | 127 } |
130 } | 128 } |
131 DVLOG(1) << "NextSendTime returning delta(ms):" << send_time.ToMilliseconds(); | 129 DVLOG(1) << "NextSendTime returning delta(ms):" |
132 return PacketEvent(send_time, transfer); | 130 << next_send_time.ToMilliseconds(); |
| 131 return PacketEvent(next_send_time, transfer); |
133 } | 132 } |
134 | 133 |
135 // NextAck takes into account packet loss in both forward and reverse | 134 // NextAck takes into account packet loss in both forward and reverse |
136 // direction, as well as correlated losses. And it assumes the receiver acks | 135 // direction, as well as correlated losses. And it assumes the receiver acks |
137 // every other packet when there is no loss. | 136 // every other packet when there is no loss. |
138 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { | 137 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() { |
139 if (sent_packets_.empty()) { | 138 if (sent_packets_.empty()) { |
140 DVLOG(1) << "No outstanding packets to ack for any transfer."; | 139 DVLOG(1) << "No outstanding packets to ack for any transfer."; |
141 return PacketEvent(QuicTime::Delta::Infinite(), NULL); | 140 return PacketEvent(QuicTime::Delta::Infinite(), NULL); |
142 } | 141 } |
143 | 142 |
144 // For each connection, find the next acked packet. | 143 // For each connection, find the next acked packet. |
145 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); | 144 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
146 Transfer* transfer = NULL; | 145 Transfer* transfer = NULL; |
147 for (vector<Transfer>::iterator it = pending_transfers_.begin(); | 146 for (vector<Transfer>::iterator it = pending_transfers_.begin(); |
148 it != pending_transfers_.end(); ++it) { | 147 it != pending_transfers_.end(); ++it) { |
149 // If necessary, determine next_acked_. | |
150 // This is only done once to ensure multiple calls return the same time. | |
151 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); | 148 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it)); |
152 if (transfer_ack_time < ack_time) { | 149 if (transfer_ack_time < ack_time) { |
153 ack_time = transfer_ack_time; | 150 ack_time = transfer_ack_time; |
154 transfer = &(*it); | 151 transfer = &(*it); |
155 } | 152 } |
156 } | 153 } |
157 | 154 |
158 return PacketEvent(ack_time, transfer); | 155 return PacketEvent(ack_time, transfer); |
159 } | 156 } |
160 | 157 |
161 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { | 158 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) { |
162 Sender* sender = transfer->sender; | 159 Sender* sender = transfer->sender; |
163 if (sender->next_acked == sender->last_acked) { | 160 if (sender->next_acked == sender->last_acked) { |
164 // Determine if the next ack is lost only once, to ensure determinism. | 161 // Determine if the next ack is lost only once, to ensure determinism. |
165 lose_next_ack_ = | 162 lose_next_ack_ = |
166 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); | 163 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64(); |
167 } | 164 } |
168 bool two_acks_remaining = lose_next_ack_; | 165 bool two_acks_remaining = lose_next_ack_; |
169 sender->next_acked = sender->last_acked; | 166 sender->next_acked = sender->last_acked; |
170 bool packets_lost = false; | 167 bool packets_lost = false; |
171 // Remove any packets that are simulated as lost. | 168 // Remove any packets that are simulated as lost. |
172 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 169 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
173 it != sent_packets_.end(); ++it) { | 170 it != sent_packets_.end(); ++it) { |
174 if (transfer != it->transfer) { | 171 if (transfer != it->transfer) { |
175 continue; | 172 continue; |
176 } | 173 } |
177 | 174 |
178 // Lost packets don't trigger an ack. | 175 // Lost packets don't trigger an ack. |
179 if (it->ack_time == QuicTime::Zero()) { | 176 if (it->ack_time == QuicTime::Zero()) { |
180 packets_lost = true; | 177 packets_lost = true; |
181 continue; | 178 continue; |
182 } | 179 } |
183 // Buffer dropped packets are skipped automatically, but still end up | 180 // Buffer dropped packets are skipped automatically, but still end up |
184 // being lost and cause acks to be sent immediately. | 181 // being lost and cause acks to be sent immediately. |
185 if (sender->next_acked < it->sequence_number - 1) { | 182 if (sender->next_acked < it->sequence_number - 1) { |
186 packets_lost = true; | 183 packets_lost = true; |
187 } | 184 } |
| 185 DCHECK_LT(sender->next_acked, it->sequence_number); |
188 sender->next_acked = it->sequence_number; | 186 sender->next_acked = it->sequence_number; |
189 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { | 187 if (packets_lost || (sender->next_acked - sender->last_acked) % 2 == 0) { |
190 if (two_acks_remaining) { | 188 if (two_acks_remaining) { |
191 two_acks_remaining = false; | 189 two_acks_remaining = false; |
192 } else { | 190 } else { |
193 break; | 191 break; |
194 } | 192 } |
195 } | 193 } |
196 } | 194 } |
| 195 // If the connection has no packets to be acked, return Infinite. |
| 196 if (sender->next_acked == sender->last_acked) { |
| 197 return QuicTime::Delta::Infinite(); |
| 198 } |
197 | 199 |
198 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); | 200 QuicTime::Delta ack_time = QuicTime::Delta::Infinite(); |
199 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); | 201 for (list<SentPacket>::const_iterator it = sent_packets_.begin(); |
200 it != sent_packets_.end(); ++it) { | 202 it != sent_packets_.end(); ++it) { |
201 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { | 203 if (transfer == it->transfer && sender->next_acked == it->sequence_number) { |
202 ack_time = it->ack_time.Subtract(clock_->Now()); | 204 ack_time = it->ack_time.Subtract(clock_->Now()); |
203 } | 205 } |
204 } | 206 } |
205 // If only one packet is acked, simulate a delayed ack. | 207 // If only one packet is acked, simulate a delayed ack. |
206 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { | 208 if (!ack_time.IsInfinite() && transfer->bytes_in_flight == kPacketSize) { |
207 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); | 209 ack_time = ack_time.Add(QuicTime::Delta::FromMilliseconds(100)); |
208 } | 210 } |
209 DVLOG(1) << "FindNextAcked found next_acked_:" | 211 DVLOG(1) << "FindNextAcked found next_acked_:" |
210 << transfer->sender->next_acked | 212 << transfer->sender->next_acked |
211 << " last_acked:" << transfer->sender->last_acked | 213 << " last_acked:" << transfer->sender->last_acked |
212 << " ack_time(ms):" << ack_time.ToMilliseconds(); | 214 << " ack_time(ms):" << ack_time.ToMilliseconds(); |
213 return ack_time; | 215 return ack_time; |
214 } | 216 } |
215 | 217 |
216 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { | 218 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) { |
217 Sender* sender = transfer->sender; | 219 Sender* sender = transfer->sender; |
218 DCHECK_LT(sender->last_acked, sender->next_acked); | 220 DCHECK_LT(sender->last_acked, sender->next_acked); |
219 SendAlgorithmInterface::CongestionMap acked_packets; | 221 SendAlgorithmInterface::CongestionMap acked_packets; |
220 SendAlgorithmInterface::CongestionMap lost_packets; | 222 SendAlgorithmInterface::CongestionMap lost_packets; |
221 // Some entries may be missing from the sent_packets_ array, if they were | 223 // Some entries may be missing from the sent_packets_ array, if they were |
222 // dropped due to buffer overruns. | 224 // dropped due to buffer overruns. |
223 SentPacket largest_observed = sent_packets_.front(); | 225 SentPacket largest_observed(0, QuicTime::Zero(), QuicTime::Zero(), NULL); |
| 226 list<SentPacket>::iterator it = sent_packets_.begin(); |
224 while (sender->last_acked < sender->next_acked) { | 227 while (sender->last_acked < sender->next_acked) { |
225 ++sender->last_acked; | 228 ++sender->last_acked; |
226 TransmissionInfo info = TransmissionInfo(); | 229 TransmissionInfo info = TransmissionInfo(); |
227 info.bytes_sent = kPacketSize; | 230 info.bytes_sent = kPacketSize; |
228 info.in_flight = true; | 231 info.in_flight = true; |
| 232 // Find the next SentPacket for this transfer. |
| 233 while (it->transfer != transfer) { |
| 234 DCHECK(it != sent_packets_.end()); |
| 235 ++it; |
| 236 } |
229 // If it's missing from the array, it's a loss. | 237 // If it's missing from the array, it's a loss. |
230 if (sent_packets_.front().sequence_number > sender->last_acked) { | 238 if (it->sequence_number > sender->last_acked) { |
231 DVLOG(1) << "Lost packet:" << sender->last_acked | 239 DVLOG(1) << "Lost packet:" << sender->last_acked |
232 << " dropped by buffer overflow."; | 240 << " dropped by buffer overflow."; |
233 lost_packets[sender->last_acked] = info; | 241 lost_packets[sender->last_acked] = info; |
234 continue; | 242 continue; |
235 } | 243 } |
236 if (sent_packets_.front().ack_time.IsInitialized()) { | 244 if (it->ack_time.IsInitialized()) { |
237 acked_packets[sender->last_acked] = info; | 245 acked_packets[sender->last_acked] = info; |
238 } else { | 246 } else { |
239 lost_packets[sender->last_acked] = info; | 247 lost_packets[sender->last_acked] = info; |
240 } | 248 } |
241 // Remove all packets from the front to next_acked_. | 249 // This packet has been acked or lost, remove it from sent_packets_. |
242 largest_observed = sent_packets_.front(); | 250 largest_observed = *it; |
243 sent_packets_.pop_front(); | 251 sent_packets_.erase(it++); |
244 } | 252 } |
245 | 253 |
246 DCHECK(largest_observed.ack_time.IsInitialized()); | 254 DCHECK(largest_observed.ack_time.IsInitialized()); |
| 255 DVLOG(1) << "Updating RTT from send_time:" |
| 256 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:" |
| 257 << largest_observed.ack_time.ToDebuggingValue(); |
247 sender->rtt_stats->UpdateRtt( | 258 sender->rtt_stats->UpdateRtt( |
248 largest_observed.ack_time.Subtract(largest_observed.send_time), | 259 largest_observed.ack_time.Subtract(largest_observed.send_time), |
249 QuicTime::Delta::Zero(), | 260 QuicTime::Delta::Zero(), |
250 clock_->Now()); | 261 clock_->Now()); |
251 sender->send_algorithm->OnCongestionEvent( | 262 sender->send_algorithm->OnCongestionEvent( |
252 true, transfer->bytes_in_flight, acked_packets, lost_packets); | 263 true, transfer->bytes_in_flight, acked_packets, lost_packets); |
253 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), | 264 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()), |
254 transfer->bytes_in_flight); | 265 transfer->bytes_in_flight); |
255 transfer->bytes_in_flight -= | 266 transfer->bytes_in_flight -= |
256 kPacketSize * (acked_packets.size() + lost_packets.size()); | 267 kPacketSize * (acked_packets.size() + lost_packets.size()); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
297 DVLOG(1) << "losing packet:" << sender->last_sent | 308 DVLOG(1) << "losing packet:" << sender->last_sent |
298 << " due to random loss."; | 309 << " due to random loss."; |
299 | 310 |
300 QuicTime ack_time = clock_->Now().Add(rtt_); | 311 QuicTime ack_time = clock_->Now().Add(rtt_); |
301 // If the number of bytes in flight are less than the bdp, there's | 312 // If the number of bytes in flight are less than the bdp, there's |
302 // no buffering delay. Bytes lost from the buffer are not counted. | 313 // no buffering delay. Bytes lost from the buffer are not counted. |
303 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); | 314 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_); |
304 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { | 315 if ((sent_packets_.size() + 1) * kPacketSize > bdp) { |
305 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; | 316 QuicByteCount qsize = (sent_packets_.size() + 1) * kPacketSize - bdp; |
306 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); | 317 ack_time = ack_time.Add(bandwidth_.TransferTime(qsize)); |
| 318 DVLOG(1) << "Increasing transfer time:" |
| 319 << bandwidth_.TransferTime(qsize).ToMilliseconds() |
| 320 << "ms due to qsize:" << qsize; |
307 } | 321 } |
308 // If the packet is lost, give it an ack time of Zero. | 322 // If the packet is lost, give it an ack time of Zero. |
309 sent_packets_.push_back(SentPacket( | 323 sent_packets_.push_back(SentPacket( |
310 sender->last_sent, clock_->Now(), | 324 sender->last_sent, clock_->Now(), |
311 packet_lost ? QuicTime::Zero() : ack_time, transfer)); | 325 packet_lost ? QuicTime::Zero() : ack_time, transfer)); |
312 } else { | 326 } else { |
313 DVLOG(1) << "losing packet:" << sender->last_sent | 327 DVLOG(1) << "losing packet:" << sender->last_sent |
314 << " because the buffer was full."; | 328 << " because the buffer was full."; |
315 } | 329 } |
316 transfer->bytes_in_flight += kPacketSize; | 330 transfer->bytes_in_flight += kPacketSize; |
317 } | 331 } |
318 | 332 |
319 // Advance the time by |delta| without sending anything. | 333 // Advance the time by |delta| without sending anything. |
320 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { | 334 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) { |
321 clock_->AdvanceTime(delta); | 335 clock_->AdvanceTime(delta); |
322 } | 336 } |
323 | 337 |
324 } // namespace net | 338 } // namespace net |
OLD | NEW |