xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/quic/core/congestion_control/bbr2_probe_bw.h (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 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.
4 
5 #ifndef QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
6 #define QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
7 
8 #include <cstdint>
9 
10 #include "quiche/quic/core/congestion_control/bbr2_misc.h"
11 #include "quiche/quic/core/quic_time.h"
12 #include "quiche/quic/core/quic_types.h"
13 #include "quiche/quic/platform/api/quic_export.h"
14 #include "quiche/quic/platform/api/quic_flags.h"
15 
16 namespace quic {
17 
18 class Bbr2Sender;
19 class QUICHE_EXPORT Bbr2ProbeBwMode final : public Bbr2ModeBase {
20  public:
21   using Bbr2ModeBase::Bbr2ModeBase;
22 
23   void Enter(QuicTime now,
24              const Bbr2CongestionEvent* congestion_event) override;
Leave(QuicTime,const Bbr2CongestionEvent *)25   void Leave(QuicTime /*now*/,
26              const Bbr2CongestionEvent* /*congestion_event*/) override {}
27 
28   Bbr2Mode OnCongestionEvent(
29       QuicByteCount prior_in_flight, QuicTime event_time,
30       const AckedPacketVector& acked_packets,
31       const LostPacketVector& lost_packets,
32       const Bbr2CongestionEvent& congestion_event) override;
33 
34   Limits<QuicByteCount> GetCwndLimits() const override;
35 
36   bool IsProbingForBandwidth() const override;
37 
38   Bbr2Mode OnExitQuiescence(QuicTime now,
39                             QuicTime quiescence_start_time) override;
40 
41   enum class CyclePhase : uint8_t {
42     PROBE_NOT_STARTED,
43     PROBE_UP,
44     PROBE_DOWN,
45     PROBE_CRUISE,
46     PROBE_REFILL,
47   };
48 
49   static const char* CyclePhaseToString(CyclePhase phase);
50 
51   struct QUICHE_EXPORT DebugState {
52     CyclePhase phase;
53     QuicTime cycle_start_time = QuicTime::Zero();
54     QuicTime phase_start_time = QuicTime::Zero();
55   };
56 
57   DebugState ExportDebugState() const;
58 
59  private:
60   const Bbr2Params& Params() const;
61   float PacingGainForPhase(CyclePhase phase) const;
62 
63   void UpdateProbeUp(QuicByteCount prior_in_flight,
64                      const Bbr2CongestionEvent& congestion_event);
65   void UpdateProbeDown(QuicByteCount prior_in_flight,
66                        const Bbr2CongestionEvent& congestion_event);
67   void UpdateProbeCruise(const Bbr2CongestionEvent& congestion_event);
68   void UpdateProbeRefill(const Bbr2CongestionEvent& congestion_event);
69 
70   enum AdaptUpperBoundsResult : uint8_t {
71     ADAPTED_OK,
72     ADAPTED_PROBED_TOO_HIGH,
73     NOT_ADAPTED_INFLIGHT_HIGH_NOT_SET,
74     NOT_ADAPTED_INVALID_SAMPLE,
75   };
76 
77   // Return whether adapted inflight_hi. If inflight is too high, this function
78   // will not adapt inflight_hi and will return false.
79   AdaptUpperBoundsResult MaybeAdaptUpperBounds(
80       const Bbr2CongestionEvent& congestion_event);
81 
82   void EnterProbeDown(bool probed_too_high, bool stopped_risky_probe,
83                       QuicTime now);
84   void EnterProbeCruise(QuicTime now);
85   void EnterProbeRefill(uint64_t probe_up_rounds, QuicTime now);
86   void EnterProbeUp(QuicTime now);
87 
88   // Call right before the exit of PROBE_DOWN.
89   void ExitProbeDown();
90 
91   float PercentTimeElapsedToProbeBandwidth(
92       const Bbr2CongestionEvent& congestion_event) const;
93 
94   bool IsTimeToProbeBandwidth(
95       const Bbr2CongestionEvent& congestion_event) const;
96   bool HasStayedLongEnoughInProbeDown(
97       const Bbr2CongestionEvent& congestion_event) const;
98   bool HasCycleLasted(QuicTime::Delta duration,
99                       const Bbr2CongestionEvent& congestion_event) const;
100   bool HasPhaseLasted(QuicTime::Delta duration,
101                       const Bbr2CongestionEvent& congestion_event) const;
102   bool IsTimeToProbeForRenoCoexistence(
103       double probe_wait_fraction,
104       const Bbr2CongestionEvent& congestion_event) const;
105 
106   void RaiseInflightHighSlope();
107   void ProbeInflightHighUpward(const Bbr2CongestionEvent& congestion_event);
108 
109   struct QUICHE_EXPORT Cycle {
110     QuicTime cycle_start_time = QuicTime::Zero();
111     CyclePhase phase = CyclePhase::PROBE_NOT_STARTED;
112     uint64_t rounds_in_phase = 0;
113     QuicTime phase_start_time = QuicTime::Zero();
114     QuicRoundTripCount rounds_since_probe = 0;
115     QuicTime::Delta probe_wait_time = QuicTime::Delta::Zero();
116     uint64_t probe_up_rounds = 0;
117     QuicByteCount probe_up_bytes = std::numeric_limits<QuicByteCount>::max();
118     QuicByteCount probe_up_acked = 0;
119     bool probe_up_app_limited_since_inflight_hi_limited_ = false;
120     // Whether max bandwidth filter window has advanced in this cycle. It is
121     // advanced once per cycle.
122     bool has_advanced_max_bw = false;
123     bool is_sample_from_probing = false;
124   } cycle_;
125 
126   bool last_cycle_probed_too_high_;
127   bool last_cycle_stopped_risky_probe_;
128 };
129 
130 QUICHE_EXPORT std::ostream& operator<<(
131     std::ostream& os, const Bbr2ProbeBwMode::DebugState& state);
132 
133 QUICHE_EXPORT std::ostream& operator<<(std::ostream& os,
134                                        const Bbr2ProbeBwMode::CyclePhase phase);
135 
136 }  // namespace quic
137 
138 #endif  // QUICHE_QUIC_CORE_CONGESTION_CONTROL_BBR2_PROBE_BW_H_
139