shithub: snippets

Download patch

ref: 78e765a33d9bb9c0662d205db1de7ecdf74aa867
parent: fc4811a72c36a617ffd1bd08770aaf46cfdc80b7
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Jan 13 13:27:33 EST 2021

add nanosec.c

--- a/README.md
+++ b/README.md
@@ -5,4 +5,5 @@
 
 * `lrint.c` lrint* implementation
 * `msr.c` MSR reading tool
+* `nanosec.c` nanosec(), a replacement for (way more expensive) nsec()
 * `qt.[ch]` [QP tries](https://dotat.at/prog/qp/README.html)
--- /dev/null
+++ b/nanosec.c
@@ -1,0 +1,36 @@
+#include <u.h>
+#include <libc.h>
+#include <tos.h>
+
+/*
+ * nsec() is wallclock and can be adjusted by timesync
+ * so need to use cycles() instead, but fall back to
+ * nsec() in case we can't
+ */
+uvlong
+nanosec(void)
+{
+	static uvlong fasthz, xstart;
+	uvlong x, div;
+
+	if(fasthz == ~0ULL)
+		return nsec() - xstart;
+
+	if(fasthz == 0){
+		if(_tos->cyclefreq){
+			fasthz = _tos->cyclefreq;
+			cycles(&xstart);
+		} else {
+			fasthz = ~0ULL;
+			xstart = nsec();
+		}
+		return 0;
+	}
+	cycles(&x);
+	x -= xstart;
+
+	/* this is ugly */
+	for(div = 1000000000ULL; x < 0x1999999999999999ULL && div > 1 ; div /= 10ULL, x *= 10ULL);
+
+	return x / (fasthz / div);
+}