[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20180806170953.164776-2-ysseung@google.com>
Date: Mon, 6 Aug 2018 10:09:51 -0700
From: Yousuk Seung <ysseung@...gle.com>
To: netdev@...r.kernel.org
Cc: Stephen Hemminger <stephen@...workplumber.org>,
David Ahern <dsahern@...il.com>,
Michael McLennan <nefario@...gle.com>,
Priyaranjan Jha <priyarjha@...gle.com>,
Dave Taht <dave.taht@...il.com>,
Yousuk Seung <ysseung@...gle.com>,
Neal Cardwell <ncardwell@...gle.com>
Subject: [PATCH iproute2-next 1/3] tc: support conversions to or from 64 bit
nanosecond-based time
From: Dave Taht <dave.taht@...il.com>
Using a 32 bit field to represent time in nanoseconds results in a
maximum value of about 4.3 seconds, which is well below many observed
delays in WiFi and LTE, and barely in the ballpark for a trip past the
Earth's moon, Luna.
Using 64 bit time fields in nanoseconds allows us to simulate
network diameters of several hundred light-years. However, only
conversions to and from ns, us, ms, and seconds are provided.
Signed-off-by: Yousuk Seung <ysseung@...gle.com>
Signed-off-by: Dave Taht <dave.taht@...il.com>
Signed-off-by: Neal Cardwell <ncardwell@...gle.com>
---
tc/tc_core.h | 4 ++++
tc/tc_util.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tc/tc_util.h | 3 +++
3 files changed, 62 insertions(+)
diff --git a/tc/tc_core.h b/tc/tc_core.h
index 1dfa9a4f773b..a0fe0923d171 100644
--- a/tc/tc_core.h
+++ b/tc/tc_core.h
@@ -7,6 +7,10 @@
#define TIME_UNITS_PER_SEC 1000000
+#define NSEC_PER_USEC 1000
+#define NSEC_PER_MSEC 1000000
+#define NSEC_PER_SEC 1000000000LL
+
enum link_layer {
LINKLAYER_UNSPEC,
LINKLAYER_ETHERNET,
diff --git a/tc/tc_util.c b/tc/tc_util.c
index d7578528a31b..c39c9046dcae 100644
--- a/tc/tc_util.c
+++ b/tc/tc_util.c
@@ -385,6 +385,61 @@ char *sprint_ticks(__u32 ticks, char *buf)
return sprint_time(tc_core_tick2time(ticks), buf);
}
+/* 64 bit times are represented internally in nanoseconds */
+int get_time64(__s64 *time, const char *str)
+{
+ double nsec;
+ char *p;
+
+ nsec = strtod(str, &p);
+ if (p == str)
+ return -1;
+
+ if (*p) {
+ if (strcasecmp(p, "s") == 0 ||
+ strcasecmp(p, "sec") == 0 ||
+ strcasecmp(p, "secs") == 0)
+ nsec *= NSEC_PER_SEC;
+ else if (strcasecmp(p, "ms") == 0 ||
+ strcasecmp(p, "msec") == 0 ||
+ strcasecmp(p, "msecs") == 0)
+ nsec *= NSEC_PER_MSEC;
+ else if (strcasecmp(p, "us") == 0 ||
+ strcasecmp(p, "usec") == 0 ||
+ strcasecmp(p, "usecs") == 0)
+ nsec *= NSEC_PER_USEC;
+ else if (strcasecmp(p, "ns") == 0 ||
+ strcasecmp(p, "nsec") == 0 ||
+ strcasecmp(p, "nsecs") == 0)
+ nsec *= 1;
+ else
+ return -1;
+ }
+
+ *time = nsec;
+ return 0;
+}
+
+void print_time64(char *buf, int len, __s64 time)
+{
+ double nsec = time;
+
+ if (time >= NSEC_PER_SEC)
+ snprintf(buf, len, "%.3fs", nsec/NSEC_PER_SEC);
+ else if (time >= NSEC_PER_MSEC)
+ snprintf(buf, len, "%.3fms", nsec/NSEC_PER_MSEC);
+ else if (time >= NSEC_PER_USEC)
+ snprintf(buf, len, "%.3fus", nsec/NSEC_PER_USEC);
+ else
+ snprintf(buf, len, "%lldns", time);
+}
+
+char *sprint_time64(__s64 time, char *buf)
+{
+ print_time64(buf, SPRINT_BSIZE-1, time);
+ return buf;
+}
+
int get_size(unsigned int *size, const char *str)
{
double sz;
diff --git a/tc/tc_util.h b/tc/tc_util.h
index 6632c4f9c528..87be951c622d 100644
--- a/tc/tc_util.h
+++ b/tc/tc_util.h
@@ -82,12 +82,14 @@ int get_percent_rate64(__u64 *rate, const char *str, const char *dev);
int get_size(unsigned int *size, const char *str);
int get_size_and_cell(unsigned int *size, int *cell_log, char *str);
int get_time(unsigned int *time, const char *str);
+int get_time64(__s64 *time, const char *str);
int get_linklayer(unsigned int *val, const char *arg);
void print_rate(char *buf, int len, __u64 rate);
void print_size(char *buf, int len, __u32 size);
void print_qdisc_handle(char *buf, int len, __u32 h);
void print_time(char *buf, int len, __u32 time);
+void print_time64(char *buf, int len, __s64 time);
void print_linklayer(char *buf, int len, unsigned int linklayer);
void print_devname(enum output_type type, int ifindex);
@@ -96,6 +98,7 @@ char *sprint_size(__u32 size, char *buf);
char *sprint_qdisc_handle(__u32 h, char *buf);
char *sprint_tc_classid(__u32 h, char *buf);
char *sprint_time(__u32 time, char *buf);
+char *sprint_time64(__s64 time, char *buf);
char *sprint_ticks(__u32 ticks, char *buf);
char *sprint_linklayer(unsigned int linklayer, char *buf);
--
2.18.0.597.ga71716f1ad-goog
Powered by blists - more mailing lists