| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/fix_rate_sender.h" | 5 #include "net/quic/congestion_control/fix_rate_sender.h" |
| 6 | 6 |
| 7 #include <math.h> | 7 #include <math.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "net/quic/quic_protocol.h" | 10 #include "net/quic/quic_protocol.h" |
| 11 | 11 |
| 12 namespace { | 12 namespace { |
| 13 const int kInitialBitrate = 100000; // In bytes per second. | 13 const int kInitialBitrate = 100000; // In bytes per second. |
| 14 const uint64 kWindowSizeUs = 10000; // 10 ms. | 14 const uint64 kWindowSizeUs = 10000; // 10 ms. |
| 15 } | 15 } |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 FixRateSender::FixRateSender(const QuicClock* clock) | 19 FixRateSender::FixRateSender(const QuicClock* clock) |
| 20 : bitrate_(QuicBandwidth::FromBytesPerSecond(kInitialBitrate)), | 20 : bitrate_(QuicBandwidth::FromBytesPerSecond(kInitialBitrate)), |
| 21 fix_rate_leaky_bucket_(clock, bitrate_), | 21 fix_rate_leaky_bucket_(bitrate_), |
| 22 paced_sender_(clock, bitrate_), | 22 paced_sender_(bitrate_), |
| 23 data_in_flight_(0) { | 23 data_in_flight_(0) { |
| 24 DLOG(INFO) << "FixRateSender"; | 24 DLOG(INFO) << "FixRateSender"; |
| 25 } | 25 } |
| 26 | 26 |
| 27 void FixRateSender::OnIncomingQuicCongestionFeedbackFrame( | 27 void FixRateSender::OnIncomingQuicCongestionFeedbackFrame( |
| 28 const QuicCongestionFeedbackFrame& feedback, | 28 const QuicCongestionFeedbackFrame& feedback, |
| 29 QuicTime feedback_receive_time, |
| 30 QuicBandwidth /*sent_bandwidth*/, |
| 29 const SentPacketsMap& /*sent_packets*/) { | 31 const SentPacketsMap& /*sent_packets*/) { |
| 30 DCHECK(feedback.type == kFixRate) << | 32 DCHECK(feedback.type == kFixRate) << |
| 31 "Invalid incoming CongestionFeedbackType:" << feedback.type; | 33 "Invalid incoming CongestionFeedbackType:" << feedback.type; |
| 32 if (feedback.type == kFixRate) { | 34 if (feedback.type == kFixRate) { |
| 33 bitrate_ = feedback.fix_rate.bitrate; | 35 bitrate_ = feedback.fix_rate.bitrate; |
| 34 fix_rate_leaky_bucket_.SetDrainingRate(bitrate_); | 36 fix_rate_leaky_bucket_.SetDrainingRate(feedback_receive_time, bitrate_); |
| 35 paced_sender_.UpdateBandwidthEstimate(bitrate_); | 37 paced_sender_.UpdateBandwidthEstimate(feedback_receive_time, bitrate_); |
| 36 } | 38 } |
| 37 // Silently ignore invalid messages in release mode. | 39 // Silently ignore invalid messages in release mode. |
| 38 } | 40 } |
| 39 | 41 |
| 40 void FixRateSender::OnIncomingAck( | 42 void FixRateSender::OnIncomingAck( |
| 41 QuicPacketSequenceNumber /*acked_sequence_number*/, | 43 QuicPacketSequenceNumber /*acked_sequence_number*/, |
| 42 QuicByteCount bytes_acked, | 44 QuicByteCount bytes_acked, |
| 43 QuicTime::Delta /*rtt*/) { | 45 QuicTime::Delta /*rtt*/) { |
| 44 data_in_flight_ -= bytes_acked; | 46 data_in_flight_ -= bytes_acked; |
| 45 } | 47 } |
| 46 | 48 |
| 47 void FixRateSender::OnIncomingLoss(int /*number_of_lost_packets*/) { | 49 void FixRateSender::OnIncomingLoss(QuicTime /*ack_receive_time*/) { |
| 48 // Ignore losses for fix rate sender. | 50 // Ignore losses for fix rate sender. |
| 49 } | 51 } |
| 50 | 52 |
| 51 void FixRateSender::SentPacket(QuicPacketSequenceNumber /*sequence_number*/, | 53 void FixRateSender::SentPacket(QuicTime sent_time, |
| 54 QuicPacketSequenceNumber /*sequence_number*/, |
| 52 QuicByteCount bytes, | 55 QuicByteCount bytes, |
| 53 bool is_retransmission) { | 56 bool is_retransmission) { |
| 54 fix_rate_leaky_bucket_.Add(bytes); | 57 fix_rate_leaky_bucket_.Add(sent_time, bytes); |
| 55 paced_sender_.SentPacket(bytes); | 58 paced_sender_.SentPacket(sent_time, bytes); |
| 56 if (!is_retransmission) { | 59 if (!is_retransmission) { |
| 57 data_in_flight_ += bytes; | 60 data_in_flight_ += bytes; |
| 58 } | 61 } |
| 59 } | 62 } |
| 60 | 63 |
| 61 QuicTime::Delta FixRateSender::TimeUntilSend(bool /*is_retransmission*/) { | 64 QuicTime::Delta FixRateSender::TimeUntilSend(QuicTime now, |
| 62 if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending()) { | 65 bool /*is_retransmission*/) { |
| 66 if (CongestionWindow() > fix_rate_leaky_bucket_.BytesPending(now)) { |
| 63 if (CongestionWindow() <= data_in_flight_) { | 67 if (CongestionWindow() <= data_in_flight_) { |
| 64 // We need an ack before we send more. | 68 // We need an ack before we send more. |
| 65 return QuicTime::Delta::Infinite(); | 69 return QuicTime::Delta::Infinite(); |
| 66 } | 70 } |
| 67 return paced_sender_.TimeUntilSend(QuicTime::Delta::Zero()); | 71 return paced_sender_.TimeUntilSend(now, QuicTime::Delta::Zero()); |
| 68 } | 72 } |
| 69 QuicTime::Delta time_remaining = fix_rate_leaky_bucket_.TimeRemaining(); | 73 QuicTime::Delta time_remaining = fix_rate_leaky_bucket_.TimeRemaining(now); |
| 70 if (time_remaining.IsZero()) { | 74 if (time_remaining.IsZero()) { |
| 71 // We need an ack before we send more. | 75 // We need an ack before we send more. |
| 72 return QuicTime::Delta::Infinite(); | 76 return QuicTime::Delta::Infinite(); |
| 73 } | 77 } |
| 74 return paced_sender_.TimeUntilSend(time_remaining); | 78 return paced_sender_.TimeUntilSend(now, time_remaining); |
| 75 } | 79 } |
| 76 | 80 |
| 77 QuicByteCount FixRateSender::CongestionWindow() { | 81 QuicByteCount FixRateSender::CongestionWindow() { |
| 78 QuicByteCount window_size_bytes = bitrate_.ToBytesPerPeriod( | 82 QuicByteCount window_size_bytes = bitrate_.ToBytesPerPeriod( |
| 79 QuicTime::Delta::FromMicroseconds(kWindowSizeUs)); | 83 QuicTime::Delta::FromMicroseconds(kWindowSizeUs)); |
| 80 // Make sure window size is not less than a packet. | 84 // Make sure window size is not less than a packet. |
| 81 return std::max(kMaxPacketSize, window_size_bytes); | 85 return std::max(kMaxPacketSize, window_size_bytes); |
| 82 } | 86 } |
| 83 | 87 |
| 84 QuicByteCount FixRateSender::AvailableCongestionWindow() { | |
| 85 QuicByteCount congestion_window = CongestionWindow(); | |
| 86 if (data_in_flight_ >= congestion_window) { | |
| 87 return 0; | |
| 88 } | |
| 89 QuicByteCount available_congestion_window = congestion_window - | |
| 90 data_in_flight_; | |
| 91 return paced_sender_.AvailableWindow(available_congestion_window); | |
| 92 } | |
| 93 | |
| 94 QuicBandwidth FixRateSender::BandwidthEstimate() { | 88 QuicBandwidth FixRateSender::BandwidthEstimate() { |
| 95 return bitrate_; | 89 return bitrate_; |
| 96 } | 90 } |
| 97 | 91 |
| 98 } // namespace net | 92 } // namespace net |
| OLD | NEW |