You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.9 KiB
120 lines
3.9 KiB
#pragma once |
|
#include <stdint.h> |
|
|
|
#ifdef __cplusplus |
|
extern "C" { |
|
#endif |
|
|
|
#define BBR_SCALE 8 |
|
#define BBR_UNIT (1 << BBR_SCALE) |
|
#define BW_SCALE 24 |
|
#define BW_UNIT (1 << BW_SCALE) |
|
|
|
#define BBR_STARTUP_PACING_GAIN (BBR_UNIT * 277 / 100 + 1) |
|
#define BBR_STARTUP_CWND_GAIN (BBR_UNIT * 2) |
|
#define BBR_DRAIN_GAIN (BBR_UNIT * 1000 / 2885) |
|
#define BBR_CWND_GAIN (BBR_UNIT * 2) |
|
#define BBR_PROBE_RTT_CWND_GAIN (BBR_UNIT * 1 / 2) |
|
#define BBR_CWND_MIN_TARGET 4 |
|
#define BBR_FULL_BW_THRESH (BBR_UNIT * 5 / 4) |
|
#define BBR_FULL_BW_CNT 3 |
|
#define BBR_LOSS_THRESH (BBR_UNIT * 2 / 100) |
|
#define BBR_BETA (BBR_UNIT * 30 / 100) |
|
#define BBR_INFLIGHT_HEADROOM (BBR_UNIT * 15 / 100) |
|
#define BBR_EXTRA_ACKED_GAIN BBR_UNIT |
|
#define BBR_EXTRA_ACKED_WIN_RTTS 5 |
|
#define BBR_ACK_EPOCH_ACKED_RESET_THRESH (1U << 20) |
|
#define BBR_EXTRA_ACKED_MAX_US (100 * 1000) |
|
#define BBR_FULL_LOSS_CNT 6 |
|
#define BBR_BW_PROBE_MAX_ROUNDS 63 |
|
#define BBR_BW_PROBE_RAND_ROUNDS 2 |
|
#define BBR_BW_PROBE_BASE_US (2 * 1000000) |
|
#define BBR_BW_PROBE_RAND_US (1 * 1000000) |
|
#define BBR_PROBE_RTT_WIN_MS 5000 |
|
#define BBR_MIN_RTT_WIN_SEC 10 |
|
#define BBR_PROBE_RTT_MS 200 |
|
|
|
enum bbr_mode { BBR_STARTUP = 0, BBR_DRAIN = 1, BBR_PROBE_BW = 2, BBR_PROBE_RTT = 3 }; |
|
enum bbr_bw_probe_cyc { BBR_BW_PROBE_UP = 0, BBR_BW_PROBE_DOWN = 1, BBR_BW_PROBE_CRUISE = 2, BBR_BW_PROBE_REFILL = 3 }; |
|
enum bbr_ack_phase { BBR_ACKS_INIT = 0, BBR_ACKS_REFILLING, BBR_ACKS_PROBE_STARTING, BBR_ACKS_PROBE_FEEDBACK, BBR_ACKS_PROBE_STOPPING }; |
|
|
|
struct bbr_rate_sample { |
|
uint32_t delivered; |
|
uint32_t interval_us; |
|
uint32_t rtt_us; |
|
uint32_t acked_sacked; |
|
uint32_t prior_delivered; |
|
uint32_t tx_in_flight; |
|
int lost; |
|
int is_app_limited; |
|
}; |
|
|
|
typedef void (*bbr_cwnd_update_fn)(void* ctx, uint32_t new_cwnd); |
|
|
|
struct bbr { |
|
uint32_t min_rtt_us; |
|
uint32_t bw_lo; |
|
uint32_t bw_hi[2]; |
|
uint32_t inflight_lo; |
|
uint32_t inflight_hi; |
|
uint32_t bw_latest; |
|
uint32_t inflight_latest; |
|
uint8_t mode; |
|
uint8_t cycle_idx; |
|
uint16_t pacing_gain; |
|
uint16_t cwnd_gain; |
|
uint32_t next_rtt_delivered; |
|
uint8_t round_start : 1; |
|
uint8_t full_bw_reached : 1; |
|
uint8_t loss_in_round : 1; |
|
uint8_t loss_in_cycle : 1; |
|
uint8_t idle_restart : 1; |
|
uint8_t try_fast_path : 1; |
|
uint8_t has_seen_rtt : 1; |
|
uint8_t initialized : 1; |
|
uint32_t loss_round_delivered; |
|
uint32_t bw_probe_up_cnt; |
|
uint32_t bw_probe_up_acks; |
|
uint8_t bw_probe_up_rounds; |
|
uint8_t bw_probe_samples : 1; |
|
uint8_t prev_probe_too_high: 1; |
|
uint8_t stopped_risky_probe: 1; |
|
uint8_t rounds_since_probe; |
|
uint32_t probe_wait_us; |
|
uint64_t cycle_mstamp_tb; |
|
uint32_t probe_rtt_min_us; |
|
uint64_t probe_rtt_min_stamp_tb; |
|
uint64_t probe_rtt_done_stamp_tb; |
|
uint8_t probe_rtt_round_done : 1; |
|
uint16_t extra_acked[2]; |
|
uint32_t ack_epoch_acked; |
|
uint64_t ack_epoch_mstamp_tb; |
|
uint8_t extra_acked_win_idx : 1; |
|
uint8_t extra_acked_win_rtts : 5; |
|
uint32_t prior_cwnd; |
|
uint8_t init_cwnd : 7; |
|
uint8_t full_bw_cnt : 2; |
|
uint8_t ack_phase : 3; |
|
uint8_t loss_events_in_round : 4; |
|
uint32_t delivered; |
|
uint32_t full_bw; |
|
uint64_t min_rtt_stamp_tb; |
|
uint8_t loss_round_start : 1; |
|
uint8_t full_bw_now : 1; |
|
uint8_t pad_unused : 6; |
|
uint8_t link_id; // local_link_id for debug logging |
|
uint64_t now_tb; // 0 = real get_time_tb(); >0 = test-controlled time |
|
bbr_cwnd_update_fn on_cwnd_update; |
|
void* cwnd_update_ctx; |
|
}; |
|
|
|
void bbr_init(struct bbr* bbr); |
|
void bbr_main(struct bbr* bbr, const struct bbr_rate_sample* rs, |
|
uint32_t* cwnd_out, uint32_t* pacing_rate_out, |
|
uint32_t mss, uint32_t inflight_bytes, int is_cwnd_limited); |
|
void bbr_note_loss(struct bbr* bbr); |
|
void bbr_tx_start(struct bbr* bbr); |
|
|
|
#ifdef __cplusplus |
|
} |
|
#endif
|
|
|