summaryrefslogtreecommitdiff
path: root/src/network/tc/tc-util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/network/tc/tc-util.c')
-rw-r--r--src/network/tc/tc-util.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/src/network/tc/tc-util.c b/src/network/tc/tc-util.c
new file mode 100644
index 0000000000..7e1cf53e11
--- /dev/null
+++ b/src/network/tc/tc-util.c
@@ -0,0 +1,63 @@
+/* SPDX-License-Identifier: LGPL-2.1+
+ * Copyright © 2019 VMware, Inc. */
+
+#include "alloc-util.h"
+#include "fileio.h"
+#include "parse-util.h"
+#include "tc-util.h"
+#include "time-util.h"
+
+static int tc_init(double *ticks_in_usec) {
+ uint32_t clock_resolution, ticks_to_usec, usec_to_ticks;
+ _cleanup_free_ char *line = NULL;
+ double clock_factor;
+ int r;
+
+ r = read_one_line_file("/proc/net/psched", &line);
+ if (r < 0)
+ return r;
+
+ r = sscanf(line, "%08x%08x%08x", &ticks_to_usec, &usec_to_ticks, &clock_resolution);
+ if (r < 3)
+ return -EIO;
+
+ clock_factor = (double) clock_resolution / USEC_PER_SEC;
+ *ticks_in_usec = (double) ticks_to_usec / usec_to_ticks * clock_factor;
+
+ return 0;
+}
+
+int tc_time_to_tick(usec_t t, uint32_t *ret) {
+ static double ticks_in_usec = -1;
+ usec_t a;
+ int r;
+
+ assert(ret);
+
+ if (ticks_in_usec < 0) {
+ r = tc_init(&ticks_in_usec);
+ if (r < 0)
+ return r;
+ }
+
+ a = t * ticks_in_usec;
+ if (a > UINT32_MAX)
+ return -ERANGE;
+
+ *ret = a;
+ return 0;
+}
+
+int parse_tc_percent(const char *s, uint32_t *percent) {
+ int r;
+
+ assert(s);
+ assert(percent);
+
+ r = parse_permille(s);
+ if (r < 0)
+ return r;
+
+ *percent = (double) r / 1000 * UINT32_MAX;
+ return 0;
+}