From 3a7bce16c5df6ed7e2ac5a6188ac9a5197396e62 Mon Sep 17 00:00:00 2001
From: Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>
Date: Tue, 19 May 2020 22:34:51 +0900
Subject: [PATCH] Measure delivery_rate in seconds

---
 lib/includes/ngtcp2/ngtcp2.h |  5 +++--
 lib/ngtcp2_cc.c              | 36 ++++++++++++++++++------------------
 lib/ngtcp2_cc.h              |  4 ++--
 lib/ngtcp2_rst.c             |  2 +-
 4 files changed, 24 insertions(+), 23 deletions(-)

diff --git a/lib/includes/ngtcp2/ngtcp2.h b/lib/includes/ngtcp2/ngtcp2.h
index 9174244d..8a81b3b2 100644
--- a/lib/includes/ngtcp2/ngtcp2.h
+++ b/lib/includes/ngtcp2/ngtcp2.h
@@ -583,8 +583,9 @@ typedef struct ngtcp2_conn_stat {
   /* bytes_recv is the number of bytes received in this particular
      connection, including discarded packets. */
   uint64_t bytes_recv;
-  /* delivery_rate is the current sending rate. */
-  double delivery_rate;
+  /* delivery_rate_sec is the current sending rate measured per
+     second. */
+  uint64_t delivery_rate_sec;
   /* recv_rate_sec is the current receiving rate of application data
      measured in per second. */
   uint64_t recv_rate_sec;
diff --git a/lib/ngtcp2_cc.c b/lib/ngtcp2_cc.c
index 9d3cfa85..27447152 100644
--- a/lib/ngtcp2_cc.c
+++ b/lib/ngtcp2_cc.c
@@ -41,7 +41,7 @@ ngtcp2_cc_pkt *ngtcp2_cc_pkt_init(ngtcp2_cc_pkt *pkt, int64_t pkt_num,
 }
 
 static void reno_cc_reset(ngtcp2_reno_cc *cc) {
-  cc->max_delivery_rate = 0.;
+  cc->max_delivery_rate_sec = 0;
   cc->target_cwnd = 0;
 }
 
@@ -148,19 +148,19 @@ void ngtcp2_cc_reno_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
   /* TODO Use sliding window for min rtt measurement */
   /* TODO Use sliding window */
-  cc->max_delivery_rate =
-      ngtcp2_max(cc->max_delivery_rate, cstat->delivery_rate);
+  cc->max_delivery_rate_sec =
+      ngtcp2_max(cc->max_delivery_rate_sec, cstat->delivery_rate_sec);
 
-  if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate > 1e-9) {
+  if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate_sec) {
     target_cwnd =
-        (uint64_t)(2.89 * cc->max_delivery_rate * (double)cstat->min_rtt);
+        cc->max_delivery_rate_sec * cstat->min_rtt * 289 / NGTCP2_SECONDS / 100;
     min_cwnd = 2 * cstat->max_packet_size;
     cc->target_cwnd = ngtcp2_max(min_cwnd, target_cwnd);
 
-    ngtcp2_log_info(
-        cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
-        "target_cwnd=%" PRIu64 " max_delivery_rate=%.02f min_rtt=%" PRIu64,
-        cc->target_cwnd, cc->max_delivery_rate * 1000000000, cstat->min_rtt);
+    ngtcp2_log_info(cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
+                    "target_cwnd=%" PRIu64 " max_delivery_rate_sec=%" PRIu64
+                    " min_rtt=%" PRIu64,
+                    cc->target_cwnd, cc->max_delivery_rate_sec, cstat->min_rtt);
   }
 }
 
@@ -170,7 +170,7 @@ void ngtcp2_cc_reno_cc_reset(ngtcp2_cc *ccx) {
 }
 
 static void cubic_cc_reset(ngtcp2_cubic_cc *cc) {
-  cc->max_delivery_rate = 0.;
+  cc->max_delivery_rate_sec = 0;
   cc->target_cwnd = 0;
   cc->w_last_max = 0;
   cc->w_tcp = 0;
@@ -363,20 +363,20 @@ void ngtcp2_cc_cubic_cc_on_ack_recv(ngtcp2_cc *ccx, ngtcp2_conn_stat *cstat,
 
   /* TODO Use sliding window for min rtt measurement */
   /* TODO Use sliding window */
-  cc->max_delivery_rate =
-      ngtcp2_max(cc->max_delivery_rate, cstat->delivery_rate);
+  cc->max_delivery_rate_sec =
+      ngtcp2_max(cc->max_delivery_rate_sec, cstat->delivery_rate_sec);
 
-  if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate > 1e-9) {
+  if (cstat->min_rtt != UINT64_MAX && cc->max_delivery_rate_sec) {
     target_cwnd =
-        (uint64_t)(2.89 * cc->max_delivery_rate * (double)cstat->min_rtt);
+        cc->max_delivery_rate_sec * cstat->min_rtt * 289 / NGTCP2_SECONDS / 100;
 
     min_cwnd = 2 * cstat->max_packet_size;
     cc->target_cwnd = ngtcp2_max(min_cwnd, target_cwnd);
 
-    ngtcp2_log_info(
-        cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
-        "target_cwnd=%" PRIu64 " max_delivery_rate=%.02f min_rtt=%" PRIu64,
-        cc->target_cwnd, cc->max_delivery_rate * 1000000000, cstat->min_rtt);
+    ngtcp2_log_info(cc->ccb.log, NGTCP2_LOG_EVENT_RCV,
+                    "target_cwnd=%" PRIu64 " max_delivery_rate_sec=%" PRIu64
+                    " min_rtt=%" PRIu64,
+                    cc->target_cwnd, cc->max_delivery_rate_sec, cstat->min_rtt);
   }
 }
 
diff --git a/lib/ngtcp2_cc.h b/lib/ngtcp2_cc.h
index fad7886e..c606d854 100644
--- a/lib/ngtcp2_cc.h
+++ b/lib/ngtcp2_cc.h
@@ -43,7 +43,7 @@ ngtcp2_cc_pkt *ngtcp2_cc_pkt_init(ngtcp2_cc_pkt *pkt, int64_t pkt_num,
 /* ngtcp2_reno_cc is the RENO congestion controller. */
 struct ngtcp2_reno_cc {
   ngtcp2_cc_base ccb;
-  double max_delivery_rate;
+  uint64_t max_delivery_rate_sec;
   uint64_t target_cwnd;
 };
 
@@ -77,7 +77,7 @@ void ngtcp2_cc_reno_cc_reset(ngtcp2_cc *cc);
 /* ngtcp2_cubic_cc is CUBIC congestion controller. */
 typedef struct ngtcp2_cubic_cc {
   ngtcp2_cc_base ccb;
-  double max_delivery_rate;
+  uint64_t max_delivery_rate_sec;
   uint64_t target_cwnd;
   uint64_t w_last_max;
   uint64_t w_tcp;
diff --git a/lib/ngtcp2_rst.c b/lib/ngtcp2_rst.c
index 97b684e5..ec0df8a5 100644
--- a/lib/ngtcp2_rst.c
+++ b/lib/ngtcp2_rst.c
@@ -77,7 +77,7 @@ int ngtcp2_rst_on_ack_recv(ngtcp2_rst *rst, ngtcp2_conn_stat *cstat) {
   }
 
   if (rs->interval) {
-    cstat->delivery_rate = (double)rs->delivered / (double)rs->interval;
+    cstat->delivery_rate_sec = rs->delivered * NGTCP2_SECONDS / rs->interval;
   }
 
   return 1;
-- 
GitLab