1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 25392f7a3SLiteSpeed Tech#ifndef LSQUIC_BW_SAMPLER_H 35392f7a3SLiteSpeed Tech#define LSQUIC_BW_SAMPLER_H 1 45392f7a3SLiteSpeed Tech 55392f7a3SLiteSpeed Tech/* Translated from Chromium. */ 65392f7a3SLiteSpeed Tech// Copyright 2016 The Chromium Authors. All rights reserved. 75392f7a3SLiteSpeed Tech 85392f7a3SLiteSpeed Techstruct lsquic_packet_out; 95392f7a3SLiteSpeed Tech 105392f7a3SLiteSpeed Tech/* This struct provides a type for bits per second units. It's made into 115392f7a3SLiteSpeed Tech * a struct so that it is a little harder to make a mistake. The Chromium 125392f7a3SLiteSpeed Tech * equivalent of this is QuicBandwidth. Use macros to operate. 135392f7a3SLiteSpeed Tech */ 145392f7a3SLiteSpeed Techstruct bandwidth 155392f7a3SLiteSpeed Tech{ 165392f7a3SLiteSpeed Tech uint64_t value; /* Bits per second */ 175392f7a3SLiteSpeed Tech}; 185392f7a3SLiteSpeed Tech 195392f7a3SLiteSpeed Tech#define BW_INFINITE() ((struct bandwidth) { .value = UINT64_MAX, }) 205392f7a3SLiteSpeed Tech#define BW_ZERO() ((struct bandwidth) { .value = 0, }) 215392f7a3SLiteSpeed Tech#define BW_FROM_BYTES_AND_DELTA(bytes_, usecs_) \ 225392f7a3SLiteSpeed Tech ((struct bandwidth) { .value = (bytes_) * 8 * 1000000 / (usecs_), }) 235392f7a3SLiteSpeed Tech#define BW_IS_ZERO(bw_) ((bw_)->value == 0) 245392f7a3SLiteSpeed Tech#define BW_TO_BYTES_PER_SEC(bw_) ((bw_)->value / 8) 255392f7a3SLiteSpeed Tech#define BW_VALUE(bw_) (+(bw_)->value) 265392f7a3SLiteSpeed Tech#define BW_TIMES(bw_, factor_) \ 275392f7a3SLiteSpeed Tech ((struct bandwidth) { .value = BW_VALUE(bw_) * (factor_), }) 285392f7a3SLiteSpeed Tech#define BW(initial_value_) ((struct bandwidth) { .value = (initial_value_) }) 295392f7a3SLiteSpeed Tech 305392f7a3SLiteSpeed Techstruct bw_sampler 315392f7a3SLiteSpeed Tech{ 325392f7a3SLiteSpeed Tech struct lsquic_conn *bws_conn; 335392f7a3SLiteSpeed Tech uint64_t bws_total_sent, 345392f7a3SLiteSpeed Tech bws_total_acked, 355392f7a3SLiteSpeed Tech bws_total_lost; 365392f7a3SLiteSpeed Tech /* Value of bws_total_sent at the time last ACKed packet was sent. Only 375392f7a3SLiteSpeed Tech * valid if bws_last_acked_sent_time is valid. 385392f7a3SLiteSpeed Tech */ 395392f7a3SLiteSpeed Tech uint64_t bws_last_acked_total_sent; 405392f7a3SLiteSpeed Tech /* Time when last acked packet was sent. Zero if no valid timestamp is 415392f7a3SLiteSpeed Tech * available. 425392f7a3SLiteSpeed Tech */ 435392f7a3SLiteSpeed Tech lsquic_time_t bws_last_acked_sent_time; 445392f7a3SLiteSpeed Tech lsquic_time_t bws_last_acked_packet_time; 455392f7a3SLiteSpeed Tech lsquic_packno_t bws_last_sent_packno; 465392f7a3SLiteSpeed Tech lsquic_packno_t bws_end_of_app_limited_phase; 475392f7a3SLiteSpeed Tech struct malo *bws_malo; /* For struct osp_state objects */ 485392f7a3SLiteSpeed Tech enum quic_ft_bit bws_retx_frames; 495392f7a3SLiteSpeed Tech enum { 505392f7a3SLiteSpeed Tech BWS_CONN_ABORTED = 1 << 0, 515392f7a3SLiteSpeed Tech BWS_WARNED = 1 << 1, 525392f7a3SLiteSpeed Tech BWS_APP_LIMITED = 1 << 2, 535392f7a3SLiteSpeed Tech } bws_flags; 545392f7a3SLiteSpeed Tech}; 555392f7a3SLiteSpeed Tech 565392f7a3SLiteSpeed Techstruct bw_sample 575392f7a3SLiteSpeed Tech{ 585392f7a3SLiteSpeed Tech TAILQ_ENTRY(bw_sample) next; 595392f7a3SLiteSpeed Tech struct bandwidth bandwidth; 605392f7a3SLiteSpeed Tech lsquic_time_t rtt; 615392f7a3SLiteSpeed Tech int is_app_limited; 625392f7a3SLiteSpeed Tech}; 635392f7a3SLiteSpeed Tech 645392f7a3SLiteSpeed Techint 655392f7a3SLiteSpeed Techlsquic_bw_sampler_init (struct bw_sampler *, struct lsquic_conn *, 665392f7a3SLiteSpeed Tech enum quic_ft_bit); 675392f7a3SLiteSpeed Tech 685392f7a3SLiteSpeed Techvoid 695392f7a3SLiteSpeed Techlsquic_bw_sampler_packet_sent (struct bw_sampler *, struct lsquic_packet_out *, 705392f7a3SLiteSpeed Tech uint64_t in_flight); 715392f7a3SLiteSpeed Tech 725392f7a3SLiteSpeed Tech/* Free returned sample via lsquic_malo_put() after you're done */ 735392f7a3SLiteSpeed Techstruct bw_sample * 745392f7a3SLiteSpeed Techlsquic_bw_sampler_packet_acked (struct bw_sampler *, struct lsquic_packet_out *, 755392f7a3SLiteSpeed Tech lsquic_time_t ack_time); 765392f7a3SLiteSpeed Tech 775392f7a3SLiteSpeed Techvoid 785392f7a3SLiteSpeed Techlsquic_bw_sampler_packet_lost (struct bw_sampler *, struct lsquic_packet_out *); 795392f7a3SLiteSpeed Tech 805392f7a3SLiteSpeed Techvoid 815392f7a3SLiteSpeed Techlsquic_bw_sampler_app_limited (struct bw_sampler *); 825392f7a3SLiteSpeed Tech 835392f7a3SLiteSpeed Techvoid 845392f7a3SLiteSpeed Techlsquic_bw_sampler_cleanup (struct bw_sampler *); 855392f7a3SLiteSpeed Tech 865392f7a3SLiteSpeed Techunsigned 875392f7a3SLiteSpeed Techlsquic_bw_sampler_entry_count (const struct bw_sampler *); 885392f7a3SLiteSpeed Tech 895392f7a3SLiteSpeed Tech#define lsquic_bw_sampler_total_acked(sampler_) (+(sampler_)->bws_total_acked) 905392f7a3SLiteSpeed Tech 915392f7a3SLiteSpeed Tech/* The following types are exposed in the header file because of unit tests. 925392f7a3SLiteSpeed Tech * Do not use outside of lsquic_bw_sampler.c. 935392f7a3SLiteSpeed Tech */ 945392f7a3SLiteSpeed Techstruct bwps_send_state 955392f7a3SLiteSpeed Tech{ 965392f7a3SLiteSpeed Tech uint64_t total_bytes_sent, 975392f7a3SLiteSpeed Tech total_bytes_acked, 985392f7a3SLiteSpeed Tech total_bytes_lost; 995392f7a3SLiteSpeed Tech int is_app_limited; 1005392f7a3SLiteSpeed Tech}; 1015392f7a3SLiteSpeed Tech 1025392f7a3SLiteSpeed Techstruct bwp_state /* BWP State stands for Bandwidth Packet State */ 1035392f7a3SLiteSpeed Tech{ 1045392f7a3SLiteSpeed Tech struct bwps_send_state bwps_send_state; 1055392f7a3SLiteSpeed Tech uint64_t bwps_sent_at_last_ack; 1065392f7a3SLiteSpeed Tech lsquic_time_t bwps_last_ack_sent_time; 1075392f7a3SLiteSpeed Tech lsquic_time_t bwps_last_ack_ack_time; 1085392f7a3SLiteSpeed Tech unsigned short bwps_packet_size; 1095392f7a3SLiteSpeed Tech}; 1105392f7a3SLiteSpeed Tech 1115392f7a3SLiteSpeed Tech#endif 112