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