| Index: net/quic/core/congestion_control/cubic.cc
|
| diff --git a/net/quic/core/congestion_control/cubic.cc b/net/quic/core/congestion_control/cubic.cc
|
| index 7b7d9f8325ba4f219173b65d92583ddf137a23f1..a273b39dcb596d320ae0c73962c0354b4cb384ae 100644
|
| --- a/net/quic/core/congestion_control/cubic.cc
|
| +++ b/net/quic/core/congestion_control/cubic.cc
|
| @@ -44,7 +44,8 @@ Cubic::Cubic(const QuicClock* clock)
|
| num_connections_(kDefaultNumConnections),
|
| epoch_(QuicTime::Zero()),
|
| app_limited_start_time_(QuicTime::Zero()),
|
| - last_update_time_(QuicTime::Zero()) {
|
| + last_update_time_(QuicTime::Zero()),
|
| + fix_convex_mode_(false) {
|
| Reset();
|
| }
|
|
|
| @@ -80,6 +81,7 @@ void Cubic::Reset() {
|
| origin_point_congestion_window_ = 0;
|
| time_to_origin_point_ = 0;
|
| last_target_congestion_window_ = 0;
|
| + fix_convex_mode_ = false;
|
| }
|
|
|
| void Cubic::OnApplicationLimited() {
|
| @@ -88,6 +90,10 @@ void Cubic::OnApplicationLimited() {
|
| epoch_ = QuicTime::Zero();
|
| }
|
|
|
| +void Cubic::SetFixConvexMode(bool fix_convex_mode) {
|
| + fix_convex_mode_ = fix_convex_mode;
|
| +}
|
| +
|
| QuicPacketCount Cubic::CongestionWindowAfterPacketLoss(
|
| QuicPacketCount current_congestion_window) {
|
| if (current_congestion_window < last_max_congestion_window_) {
|
| @@ -139,16 +145,29 @@ QuicPacketCount Cubic::CongestionWindowAfterAck(
|
| // Change the time unit from microseconds to 2^10 fractions per second. Take
|
| // the round trip time in account. This is done to allow us to use shift as a
|
| // divide operator.
|
| - int64_t elapsed_time =
|
| + const int64_t elapsed_time =
|
| ((current_time + delay_min - epoch_).ToMicroseconds() << 10) /
|
| kNumMicrosPerSecond;
|
| + DCHECK_GE(elapsed_time, 0);
|
|
|
| int64_t offset = time_to_origin_point_ - elapsed_time;
|
| + if (fix_convex_mode_) {
|
| + // Right-shifts of negative, signed numbers have
|
| + // implementation-dependent behavior. Force the offset to be
|
| + // positive, similar to the kernel implementation.
|
| + offset = labs(time_to_origin_point_ - elapsed_time);
|
| + }
|
| +
|
| QuicPacketCount delta_congestion_window =
|
| (kCubeCongestionWindowScale * offset * offset * offset) >> kCubeScale;
|
|
|
| + const bool add_delta = elapsed_time > time_to_origin_point_;
|
| + DCHECK(add_delta ||
|
| + (origin_point_congestion_window_ > delta_congestion_window));
|
| QuicPacketCount target_congestion_window =
|
| - origin_point_congestion_window_ - delta_congestion_window;
|
| + (fix_convex_mode_ && add_delta)
|
| + ? origin_point_congestion_window_ + delta_congestion_window
|
| + : origin_point_congestion_window_ - delta_congestion_window;
|
|
|
| // Limit the CWND increase to half the acked packets rounded up to the
|
| // nearest packet.
|
|
|