11cb0ef41Sopenharmony_ci/*
21cb0ef41Sopenharmony_ci * nghttp3
31cb0ef41Sopenharmony_ci *
41cb0ef41Sopenharmony_ci * Copyright (c) 2019 nghttp3 contributors
51cb0ef41Sopenharmony_ci *
61cb0ef41Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining
71cb0ef41Sopenharmony_ci * a copy of this software and associated documentation files (the
81cb0ef41Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
91cb0ef41Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
101cb0ef41Sopenharmony_ci * distribute, sublicense, and/or sell copies of the Software, and to
111cb0ef41Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
121cb0ef41Sopenharmony_ci * the following conditions:
131cb0ef41Sopenharmony_ci *
141cb0ef41Sopenharmony_ci * The above copyright notice and this permission notice shall be
151cb0ef41Sopenharmony_ci * included in all copies or substantial portions of the Software.
161cb0ef41Sopenharmony_ci *
171cb0ef41Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
181cb0ef41Sopenharmony_ci * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
191cb0ef41Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
201cb0ef41Sopenharmony_ci * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
211cb0ef41Sopenharmony_ci * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
221cb0ef41Sopenharmony_ci * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
231cb0ef41Sopenharmony_ci * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
241cb0ef41Sopenharmony_ci */
251cb0ef41Sopenharmony_ci#include "nghttp3_tnode.h"
261cb0ef41Sopenharmony_ci
271cb0ef41Sopenharmony_ci#include <assert.h>
281cb0ef41Sopenharmony_ci
291cb0ef41Sopenharmony_ci#include "nghttp3_macro.h"
301cb0ef41Sopenharmony_ci#include "nghttp3_stream.h"
311cb0ef41Sopenharmony_ci#include "nghttp3_conn.h"
321cb0ef41Sopenharmony_ci#include "nghttp3_conv.h"
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_cinghttp3_node_id *nghttp3_node_id_init(nghttp3_node_id *nid,
351cb0ef41Sopenharmony_ci                                      nghttp3_node_id_type type, int64_t id) {
361cb0ef41Sopenharmony_ci  nid->type = type;
371cb0ef41Sopenharmony_ci  nid->id = id;
381cb0ef41Sopenharmony_ci  return nid;
391cb0ef41Sopenharmony_ci}
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ciint nghttp3_node_id_eq(const nghttp3_node_id *a, const nghttp3_node_id *b) {
421cb0ef41Sopenharmony_ci  return a->type == b->type && a->id == b->id;
431cb0ef41Sopenharmony_ci}
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_civoid nghttp3_tnode_init(nghttp3_tnode *tnode, const nghttp3_node_id *nid,
461cb0ef41Sopenharmony_ci                        uint64_t seq, uint8_t pri) {
471cb0ef41Sopenharmony_ci  assert(nghttp3_pri_uint8_urgency(pri) < NGHTTP3_URGENCY_LEVELS);
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci  tnode->pe.index = NGHTTP3_PQ_BAD_INDEX;
501cb0ef41Sopenharmony_ci  tnode->nid = *nid;
511cb0ef41Sopenharmony_ci  tnode->seq = seq;
521cb0ef41Sopenharmony_ci  tnode->cycle = 0;
531cb0ef41Sopenharmony_ci  tnode->pri = pri;
541cb0ef41Sopenharmony_ci}
551cb0ef41Sopenharmony_ci
561cb0ef41Sopenharmony_civoid nghttp3_tnode_free(nghttp3_tnode *tnode) { (void)tnode; }
571cb0ef41Sopenharmony_ci
581cb0ef41Sopenharmony_cistatic void tnode_unschedule(nghttp3_tnode *tnode, nghttp3_pq *pq) {
591cb0ef41Sopenharmony_ci  assert(tnode->pe.index != NGHTTP3_PQ_BAD_INDEX);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci  nghttp3_pq_remove(pq, &tnode->pe);
621cb0ef41Sopenharmony_ci  tnode->pe.index = NGHTTP3_PQ_BAD_INDEX;
631cb0ef41Sopenharmony_ci}
641cb0ef41Sopenharmony_ci
651cb0ef41Sopenharmony_civoid nghttp3_tnode_unschedule(nghttp3_tnode *tnode, nghttp3_pq *pq) {
661cb0ef41Sopenharmony_ci  if (tnode->pe.index == NGHTTP3_PQ_BAD_INDEX) {
671cb0ef41Sopenharmony_ci    return;
681cb0ef41Sopenharmony_ci  }
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ci  tnode_unschedule(tnode, pq);
711cb0ef41Sopenharmony_ci}
721cb0ef41Sopenharmony_ci
731cb0ef41Sopenharmony_cistatic uint64_t pq_get_first_cycle(nghttp3_pq *pq) {
741cb0ef41Sopenharmony_ci  nghttp3_tnode *top;
751cb0ef41Sopenharmony_ci
761cb0ef41Sopenharmony_ci  if (nghttp3_pq_empty(pq)) {
771cb0ef41Sopenharmony_ci    return 0;
781cb0ef41Sopenharmony_ci  }
791cb0ef41Sopenharmony_ci
801cb0ef41Sopenharmony_ci  top = nghttp3_struct_of(nghttp3_pq_top(pq), nghttp3_tnode, pe);
811cb0ef41Sopenharmony_ci  return top->cycle;
821cb0ef41Sopenharmony_ci}
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ciint nghttp3_tnode_schedule(nghttp3_tnode *tnode, nghttp3_pq *pq,
851cb0ef41Sopenharmony_ci                           uint64_t nwrite) {
861cb0ef41Sopenharmony_ci  uint64_t penalty = nwrite / NGHTTP3_STREAM_MIN_WRITELEN;
871cb0ef41Sopenharmony_ci
881cb0ef41Sopenharmony_ci  if (tnode->pe.index == NGHTTP3_PQ_BAD_INDEX) {
891cb0ef41Sopenharmony_ci    tnode->cycle = pq_get_first_cycle(pq) +
901cb0ef41Sopenharmony_ci                   ((nwrite == 0 || !nghttp3_pri_uint8_inc(tnode->pri))
911cb0ef41Sopenharmony_ci                        ? 0
921cb0ef41Sopenharmony_ci                        : nghttp3_max(1, penalty));
931cb0ef41Sopenharmony_ci  } else if (nwrite > 0) {
941cb0ef41Sopenharmony_ci    if (!nghttp3_pri_uint8_inc(tnode->pri) || nghttp3_pq_size(pq) == 1) {
951cb0ef41Sopenharmony_ci      return 0;
961cb0ef41Sopenharmony_ci    }
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci    nghttp3_pq_remove(pq, &tnode->pe);
991cb0ef41Sopenharmony_ci    tnode->pe.index = NGHTTP3_PQ_BAD_INDEX;
1001cb0ef41Sopenharmony_ci    tnode->cycle += nghttp3_max(1, penalty);
1011cb0ef41Sopenharmony_ci  } else {
1021cb0ef41Sopenharmony_ci    return 0;
1031cb0ef41Sopenharmony_ci  }
1041cb0ef41Sopenharmony_ci
1051cb0ef41Sopenharmony_ci  return nghttp3_pq_push(pq, &tnode->pe);
1061cb0ef41Sopenharmony_ci}
1071cb0ef41Sopenharmony_ci
1081cb0ef41Sopenharmony_ciint nghttp3_tnode_is_scheduled(nghttp3_tnode *tnode) {
1091cb0ef41Sopenharmony_ci  return tnode->pe.index != NGHTTP3_PQ_BAD_INDEX;
1101cb0ef41Sopenharmony_ci}
111