MacViews: Get c/b/ui/views/tabs to build on Mac
[chromium-blink-merge.git] / net / quic / congestion_control / send_algorithm_simulator.cc
blobf08acffce663d4fbc59e88c36b0bc8715ccabc4b
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
3 // found in the LICENSE file.
5 #include "net/quic/congestion_control/send_algorithm_simulator.h"
7 #include <limits>
9 #include "base/logging.h"
10 #include "base/rand_util.h"
11 #include "net/quic/crypto/quic_random.h"
13 using std::list;
14 using std::make_pair;
15 using std::max;
16 using std::min;
17 using std::vector;
19 namespace net {
21 namespace {
23 const QuicByteCount kPacketSize = 1200;
25 } // namespace
27 SendAlgorithmSimulator::Sender::Sender(SendAlgorithmInterface* send_algorithm,
28 RttStats* rtt_stats)
29 : send_algorithm(send_algorithm),
30 rtt_stats(rtt_stats),
31 last_sent(0),
32 last_acked(0),
33 next_acked(1),
34 max_cwnd(0),
35 min_cwnd(100000),
36 max_cwnd_drop(0),
37 last_cwnd(0),
38 last_transfer_bandwidth(QuicBandwidth::Zero()),
39 last_transfer_loss_rate(0) {}
41 SendAlgorithmSimulator::SendAlgorithmSimulator(
42 MockClock* clock,
43 QuicBandwidth bandwidth,
44 QuicTime::Delta rtt)
45 : clock_(clock),
46 lose_next_ack_(false),
47 forward_loss_rate_(0),
48 reverse_loss_rate_(0),
49 loss_correlation_(0),
50 bandwidth_(bandwidth),
51 rtt_(rtt),
52 buffer_size_(1000000),
53 delayed_ack_timer_(QuicTime::Delta::FromMilliseconds(100)) {
54 uint32 seed = base::RandInt(0, std::numeric_limits<int32>::max());
55 DVLOG(1) << "Seeding SendAlgorithmSimulator with " << seed;
56 simple_random_.set_seed(seed);
59 SendAlgorithmSimulator::~SendAlgorithmSimulator() {}
61 void SendAlgorithmSimulator::AddTransfer(Sender* sender, size_t num_bytes) {
62 AddTransfer(sender, num_bytes, clock_->Now());
65 void SendAlgorithmSimulator::AddTransfer(
66 Sender* sender, size_t num_bytes, QuicTime start_time) {
67 pending_transfers_.push_back(Transfer(sender, num_bytes, start_time));
68 // Record initial stats from when the transfer begins.
69 pending_transfers_.back().sender->RecordStats();
72 void SendAlgorithmSimulator::TransferBytes() {
73 TransferBytes(kuint64max, QuicTime::Delta::Infinite());
76 void SendAlgorithmSimulator::TransferBytes(QuicByteCount max_bytes,
77 QuicTime::Delta max_time) {
78 const QuicTime end_time = max_time.IsInfinite() ?
79 QuicTime::Zero().Add(QuicTime::Delta::Infinite()) :
80 clock_->Now().Add(max_time);
81 QuicByteCount bytes_sent = 0;
82 while (!pending_transfers_.empty() &&
83 clock_->Now() < end_time &&
84 bytes_sent < max_bytes) {
85 // Determine the times of next send and of the next ack arrival.
86 PacketEvent send_event = NextSendEvent();
87 PacketEvent ack_event = NextAckEvent();
88 // If both times are infinite, fire a TLP.
89 if (ack_event.time_delta.IsInfinite() &&
90 send_event.time_delta.IsInfinite()) {
91 DVLOG(1) << "Both times are infinite, simulating a TLP.";
92 // TODO(ianswett): Use a more sophisticated TLP timer or never lose
93 // the last ack?
94 clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(100));
95 SendDataNow(&pending_transfers_.front());
96 } else if (ack_event.time_delta < send_event.time_delta) {
97 DVLOG(1) << "Handling ack of largest observed:"
98 << ack_event.transfer->sender->next_acked << ", advancing time:"
99 << ack_event.time_delta.ToMicroseconds() << "us";
100 // Ack data all the data up to ack time and lose any missing sequence
101 // numbers.
102 clock_->AdvanceTime(ack_event.time_delta);
103 HandlePendingAck(ack_event.transfer);
104 } else {
105 DVLOG(1) << "Sending, advancing time:"
106 << send_event.time_delta.ToMicroseconds() << "us";
107 clock_->AdvanceTime(send_event.time_delta);
108 SendDataNow(send_event.transfer);
109 bytes_sent += kPacketSize;
114 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextSendEvent() {
115 QuicTime::Delta next_send_time = QuicTime::Delta::Infinite();
116 Transfer* transfer = nullptr;
117 for (vector<Transfer>::iterator it = pending_transfers_.begin();
118 it != pending_transfers_.end(); ++it) {
119 // 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) {
121 continue;
123 // If the flow hasn't started, use the start time.
124 QuicTime::Delta transfer_send_time = it->start_time.Subtract(clock_->Now());
125 if (clock_->Now() >= it->start_time) {
126 transfer_send_time =
127 it->sender->send_algorithm->TimeUntilSend(
128 clock_->Now(), it->bytes_in_flight, HAS_RETRANSMITTABLE_DATA);
130 if (transfer_send_time < next_send_time) {
131 next_send_time = transfer_send_time;
132 transfer = &(*it);
135 DVLOG(1) << "NextSendTime returning delta(ms):"
136 << next_send_time.ToMilliseconds();
137 return PacketEvent(next_send_time, transfer);
140 // NextAck takes into account packet loss in both forward and reverse
141 // direction, as well as correlated losses. And it assumes the receiver acks
142 // every other packet when there is no loss.
143 SendAlgorithmSimulator::PacketEvent SendAlgorithmSimulator::NextAckEvent() {
144 if (sent_packets_.empty()) {
145 DVLOG(1) << "No outstanding packets to ack for any transfer.";
146 return PacketEvent(QuicTime::Delta::Infinite(), nullptr);
149 // For each connection, find the next acked packet.
150 QuicTime::Delta ack_time = QuicTime::Delta::Infinite();
151 Transfer* transfer = nullptr;
152 for (vector<Transfer>::iterator it = pending_transfers_.begin();
153 it != pending_transfers_.end(); ++it) {
154 QuicTime::Delta transfer_ack_time = FindNextAcked(&(*it));
155 if (transfer_ack_time < ack_time) {
156 ack_time = transfer_ack_time;
157 transfer = &(*it);
161 return PacketEvent(ack_time, transfer);
164 QuicTime::Delta SendAlgorithmSimulator::FindNextAcked(Transfer* transfer) {
165 Sender* sender = transfer->sender;
166 if (sender->next_acked == sender->last_acked) {
167 // Determine if the next ack is lost only once, to ensure determinism.
168 lose_next_ack_ =
169 reverse_loss_rate_ * kuint64max > simple_random_.RandUint64();
172 QuicPacketSequenceNumber next_acked = sender->last_acked;
173 QuicTime::Delta next_ack_delay =
174 FindNextAck(transfer, sender->last_acked, &next_acked);
175 if (lose_next_ack_) {
176 next_ack_delay = FindNextAck(transfer, next_acked, &next_acked);
178 sender->next_acked = next_acked;
179 return next_ack_delay;
182 QuicTime::Delta SendAlgorithmSimulator::FindNextAck(
183 const Transfer* transfer,
184 QuicPacketSequenceNumber last_acked,
185 QuicPacketSequenceNumber* next_acked) const {
186 *next_acked = last_acked;
187 QuicTime::Delta ack_delay = QuicTime::Delta::Infinite();
188 // Remove any packets that are simulated as lost.
189 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
190 it != sent_packets_.end(); ++it) {
191 if (transfer != it->transfer) {
192 continue;
194 // Skip over any packets less than or equal to last_acked.
195 if (it->sequence_number <= last_acked) {
196 continue;
198 // Lost packets don't trigger an ack.
199 if (it->lost) {
200 continue;
202 DCHECK_LT(*next_acked, it->sequence_number);
203 // Consider a delayed ack for the current next_acked.
204 if (ack_delay < it->ack_time.Subtract(clock_->Now())) {
205 break;
207 *next_acked = it->sequence_number;
208 ack_delay = it->ack_time.Subtract(clock_->Now());
209 if (HasRecentLostPackets(transfer, *next_acked) ||
210 (*next_acked - last_acked) >= 2) {
211 break;
213 ack_delay = ack_delay.Add(delayed_ack_timer_);
216 DVLOG(1) << "FindNextAcked found next_acked_:"
217 << transfer->sender->next_acked
218 << " last_acked:" << transfer->sender->last_acked
219 << " ack_delay(ms):" << ack_delay.ToMilliseconds();
220 return ack_delay;
223 bool SendAlgorithmSimulator::HasRecentLostPackets(
224 const Transfer* transfer, QuicPacketSequenceNumber next_acked) const {
225 QuicPacketSequenceNumber last_packet = transfer->sender->last_acked;
226 for (list<SentPacket>::const_iterator it = sent_packets_.begin();
227 it != sent_packets_.end() && it->sequence_number < next_acked; ++it) {
228 if (transfer != it->transfer) {
229 continue;
231 // Lost packets don't trigger an ack.
232 if (it->lost) {
233 return true;
235 // Buffer dropped packets are skipped automatically, but still end up
236 // being lost and cause acks to be sent immediately.
237 if (it->sequence_number > last_packet + 1) {
238 return true;
240 last_packet = it->sequence_number;
242 return false;
245 void SendAlgorithmSimulator::HandlePendingAck(Transfer* transfer) {
246 Sender* sender = transfer->sender;
247 DCHECK_LT(sender->last_acked, sender->next_acked);
248 SendAlgorithmInterface::CongestionVector acked_packets;
249 SendAlgorithmInterface::CongestionVector lost_packets;
250 DVLOG(1) << "Acking packets from:" << sender->last_acked
251 << " to " << sender->next_acked
252 << " bytes_in_flight:" << transfer->bytes_in_flight
253 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
254 // Some entries may be missing from the sent_packets_ array, if they were
255 // dropped due to buffer overruns.
256 SentPacket largest_observed;
257 list<SentPacket>::iterator it = sent_packets_.begin();
258 while (sender->last_acked < sender->next_acked) {
259 ++sender->last_acked;
260 TransmissionInfo info = TransmissionInfo();
261 info.bytes_sent = kPacketSize;
262 info.in_flight = true;
263 // Find the next SentPacket for this transfer.
264 while (it->transfer != transfer) {
265 DCHECK(it != sent_packets_.end());
266 ++it;
268 // If it's missing from the array, it's a loss.
269 if (it->sequence_number > sender->last_acked) {
270 DVLOG(1) << "Lost packet:" << sender->last_acked
271 << " dropped by buffer overflow.";
272 lost_packets.push_back(make_pair(sender->last_acked, info));
273 continue;
275 if (it->lost) {
276 lost_packets.push_back(make_pair(sender->last_acked, info));
277 } else {
278 acked_packets.push_back(make_pair(sender->last_acked, info));
280 // This packet has been acked or lost, remove it from sent_packets_.
281 largest_observed = *it;
282 sent_packets_.erase(it++);
285 DCHECK(largest_observed.ack_time.IsInitialized());
286 DVLOG(1) << "Updating RTT from send_time:"
287 << largest_observed.send_time.ToDebuggingValue() << " to ack_time:"
288 << largest_observed.ack_time.ToDebuggingValue();
289 QuicTime::Delta measured_rtt =
290 largest_observed.ack_time.Subtract(largest_observed.send_time);
291 DCHECK_GE(measured_rtt.ToMicroseconds(), rtt_.ToMicroseconds());
292 sender->rtt_stats->UpdateRtt(measured_rtt,
293 QuicTime::Delta::Zero(),
294 clock_->Now());
295 sender->send_algorithm->OnCongestionEvent(
296 true, transfer->bytes_in_flight, acked_packets, lost_packets);
297 DCHECK_LE(kPacketSize * (acked_packets.size() + lost_packets.size()),
298 transfer->bytes_in_flight);
299 transfer->bytes_in_flight -=
300 kPacketSize * (acked_packets.size() + lost_packets.size());
302 sender->RecordStats();
303 transfer->bytes_acked += acked_packets.size() * kPacketSize;
304 transfer->bytes_lost += lost_packets.size() * kPacketSize;
305 if (transfer->bytes_acked >= transfer->num_bytes) {
306 // Remove completed transfers and record transfer bandwidth.
307 QuicTime::Delta transfer_time =
308 clock_->Now().Subtract(transfer->start_time);
309 sender->last_transfer_loss_rate = static_cast<float>(transfer->bytes_lost) /
310 (transfer->bytes_lost + transfer->bytes_acked);
311 sender->last_transfer_bandwidth =
312 QuicBandwidth::FromBytesAndTimeDelta(transfer->num_bytes,
313 transfer_time);
314 DCHECK_GE(bandwidth_.ToBitsPerSecond(),
315 sender->last_transfer_bandwidth.ToBitsPerSecond());
316 for (vector<Transfer>::iterator it = pending_transfers_.begin();
317 it != pending_transfers_.end(); ++it) {
318 if (transfer == &(*it)) {
319 pending_transfers_.erase(it);
320 break;
326 void SendAlgorithmSimulator::SendDataNow(Transfer* transfer) {
327 Sender* sender = transfer->sender;
328 ++sender->last_sent;
329 DVLOG(1) << "Sending packet:" << sender->last_sent
330 << " bytes_in_flight:" << transfer->bytes_in_flight
331 << " Now():" << (clock_->Now().ToDebuggingValue() / 1000) << "ms";
332 sender->send_algorithm->OnPacketSent(
333 clock_->Now(), transfer->bytes_in_flight,
334 sender->last_sent, kPacketSize, HAS_RETRANSMITTABLE_DATA);
335 // Lose the packet immediately if the buffer is full.
336 if (sent_packets_.size() * kPacketSize < buffer_size_) {
337 // TODO(ianswett): This buffer simulation is an approximation.
338 // An ack time of zero means loss.
339 bool packet_lost =
340 forward_loss_rate_ * kuint64max > simple_random_.RandUint64();
341 // Handle correlated loss.
342 if (!sent_packets_.empty() && sent_packets_.back().lost &&
343 loss_correlation_ * kuint64max > simple_random_.RandUint64()) {
344 packet_lost = true;
346 DVLOG(1) << "losing packet:" << sender->last_sent
347 << " due to random loss.";
349 // If the number of bytes in flight are less than the bdp, there's
350 // no buffering delay. Bytes lost from the buffer are not counted.
351 QuicByteCount bdp = bandwidth_.ToBytesPerPeriod(rtt_);
352 QuicTime ack_time = clock_->Now().Add(rtt_);
353 if (kPacketSize > bdp) {
354 ack_time = ack_time.Add(bandwidth_.TransferTime(kPacketSize - bdp));
356 QuicTime queue_ack_time = sent_packets_.empty() ? QuicTime::Zero() :
357 sent_packets_.back().ack_time.Add(bandwidth_.TransferTime(kPacketSize));
358 ack_time = QuicTime::Max(ack_time, queue_ack_time);
359 sent_packets_.push_back(SentPacket(
360 sender->last_sent, clock_->Now(), ack_time, packet_lost, transfer));
361 } else {
362 DVLOG(1) << "losing packet:" << sender->last_sent
363 << " because the buffer was full.";
365 transfer->bytes_in_flight += kPacketSize;
368 // Advance the time by |delta| without sending anything.
369 void SendAlgorithmSimulator::AdvanceTime(QuicTime::Delta delta) {
370 clock_->AdvanceTime(delta);
373 } // namespace net