1a74702c6SGeorge Wang/* Copyright (c) 2017 - 2022 LiteSpeed Technologies Inc. See LICENSE. */ 2fbc6cc04SDmitri Tikhonov/* 3fbc6cc04SDmitri Tikhonov * lsquic_hpi.h - HPI: (Extensible) HTTP Priority Iterator 4fbc6cc04SDmitri Tikhonov * 5fbc6cc04SDmitri Tikhonov * https://tools.ietf.org/html/draft-ietf-httpbis-priority-01 6fbc6cc04SDmitri Tikhonov * 7fbc6cc04SDmitri Tikhonov * Changing a stream's priority when the stream is in the iterator 8fbc6cc04SDmitri Tikhonov * does not change the stream's position in the iterator. 9fbc6cc04SDmitri Tikhonov */ 10fbc6cc04SDmitri Tikhonov 11fbc6cc04SDmitri Tikhonov#ifndef LSQUIC_HPI 12fbc6cc04SDmitri Tikhonov#define LSQUIC_HPI 1 13fbc6cc04SDmitri Tikhonov 14f198a02dSDmitri Tikhonov#ifndef LSQUIC_TEST 15f198a02dSDmitri Tikhonov#define LSQUIC_TEST 0 16f198a02dSDmitri Tikhonov#endif 17f198a02dSDmitri Tikhonov 18fbc6cc04SDmitri Tikhonovstruct lsquic_conn_public; 19fbc6cc04SDmitri Tikhonov 20fbc6cc04SDmitri Tikhonov/* We add 1 to the urgency when we place them on hpi_streams. Critical 21fbc6cc04SDmitri Tikhonov * streams get the highest-priority slot zero. 22fbc6cc04SDmitri Tikhonov */ 23fbc6cc04SDmitri Tikhonov#define N_HPI_PRIORITIES (2 + LSQUIC_MAX_HTTP_URGENCY) 24fbc6cc04SDmitri Tikhonov 25fbc6cc04SDmitri Tikhonov 26fbc6cc04SDmitri Tikhonovstruct http_prio_iter 27fbc6cc04SDmitri Tikhonov{ 28fbc6cc04SDmitri Tikhonov const char *hpi_name; /* Used for logging */ 29fbc6cc04SDmitri Tikhonov struct lsquic_conn_public *hpi_conn_pub; 30fbc6cc04SDmitri Tikhonov enum { 31fbc6cc04SDmitri Tikhonov HPI_MH_4K = 1 << 0, 32fbc6cc04SDmitri Tikhonov HPI_MH_MALLOC = 1 << 1, 33fbc6cc04SDmitri Tikhonov } hpi_flags; 34fbc6cc04SDmitri Tikhonov unsigned hpi_set[2]; /* Bitmask */ 35fbc6cc04SDmitri Tikhonov unsigned hpi_counts[N_HPI_PRIORITIES]; /* For non-incr only */ 36fbc6cc04SDmitri Tikhonov unsigned hpi_heaped; /* Bitmask */ 37fbc6cc04SDmitri Tikhonov struct lsquic_streams_tailq hpi_streams[2][N_HPI_PRIORITIES]; 38fbc6cc04SDmitri Tikhonov struct min_heap hpi_min_heap; 39fbc6cc04SDmitri Tikhonov /* We do this because http_prio_iter is used in a union with 40fbc6cc04SDmitri Tikhonov * stream_prio_iter, which is over 4KB on the stack. Since we 41fbc6cc04SDmitri Tikhonov * are already allocating this memory on the stack, we might as well 42fbc6cc04SDmitri Tikhonov * use it. 43fbc6cc04SDmitri Tikhonov */ 44fbc6cc04SDmitri Tikhonov struct min_heap_elem hpi_min_heap_els[236]; 45fbc6cc04SDmitri Tikhonov}; 46fbc6cc04SDmitri Tikhonov 47fbc6cc04SDmitri Tikhonov 48fbc6cc04SDmitri Tikhonovvoid 49fbc6cc04SDmitri Tikhonovlsquic_hpi_init (void *, struct lsquic_stream *first, 50fbc6cc04SDmitri Tikhonov struct lsquic_stream *last, uintptr_t next_ptr_offset, 51fbc6cc04SDmitri Tikhonov struct lsquic_conn_public *, const char *name, 52fbc6cc04SDmitri Tikhonov int (*filter)(void *filter_ctx, struct lsquic_stream *), 53fbc6cc04SDmitri Tikhonov void *filter_ctx); 54fbc6cc04SDmitri Tikhonov 55fbc6cc04SDmitri Tikhonovstruct lsquic_stream * 56fbc6cc04SDmitri Tikhonovlsquic_hpi_first (void *); 57fbc6cc04SDmitri Tikhonov 58fbc6cc04SDmitri Tikhonovstruct lsquic_stream * 59fbc6cc04SDmitri Tikhonovlsquic_hpi_next (void *); 60fbc6cc04SDmitri Tikhonov 61fbc6cc04SDmitri Tikhonovvoid 62fbc6cc04SDmitri Tikhonovlsquic_hpi_drop_non_high (void *); 63fbc6cc04SDmitri Tikhonov 64fbc6cc04SDmitri Tikhonovvoid 65fbc6cc04SDmitri Tikhonovlsquic_hpi_drop_high (void *); 66fbc6cc04SDmitri Tikhonov 67fbc6cc04SDmitri Tikhonovvoid 68fbc6cc04SDmitri Tikhonovlsquic_hpi_cleanup (void *); 69fbc6cc04SDmitri Tikhonov 70fbc6cc04SDmitri Tikhonov#ifndef NDEBUG 71fbc6cc04SDmitri Tikhonov#define LSQUIC_HPI_HEAP_TEST_STACK_OK (1 << 0) 72fbc6cc04SDmitri Tikhonov#define LSQUIC_HPI_HEAP_TEST_4K_OK (1 << 1) 73fbc6cc04SDmitri Tikhonov#if LSQUIC_TEST 74fbc6cc04SDmitri Tikhonovvoid 75fbc6cc04SDmitri Tikhonovlsquic_hpi_set_heap_test (int val); 76fbc6cc04SDmitri Tikhonov#endif 77fbc6cc04SDmitri Tikhonov#endif 78fbc6cc04SDmitri Tikhonov 79fbc6cc04SDmitri Tikhonov#endif 80