shithub: wl3d

Download patch

ref: 69186af9696370daef50510db16787d69f9b6099
parent: 8704f54821db7652060336480bde2579a7ed52cc
author: qwx <qwx@sciops.net>
date: Fri Feb 7 20:18:51 EST 2025

use nanosec(2) instead of nsec(2) to avoid timesync issues (thanks sigrid, thedaemon)

--- a/fns.h
+++ b/fns.h
@@ -1,4 +1,5 @@
 void*	emalloc(ulong);
+u64int	nanosec(void);
 void	grab(int);
 void	toss(void);
 void	flush(void);
--- a/mkfile
+++ b/mkfile
@@ -9,6 +9,7 @@
 	gm.$O\
 	hub.$O\
 	map.$O\
+	nanosec.$O\
 	opl2.$O\
 	rend.$O\
 	snd.$O\
--- /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
+ */
+u64int
+nanosec(void)
+{
+	static u64int fasthz, xstart;
+	u64int 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);
+}
--- a/wl3d.c
+++ b/wl3d.c
@@ -280,7 +280,7 @@
 	initsnd();
 	init(df, m, d);
 	cson++;
-	t0 = nsec();
+	t0 = nanosec();
 	Δtc = 1;
 	step = qstep;
 	for(;;){
@@ -290,7 +290,7 @@
 			resetfb();
 		}
 		step();
-		t = nsec();
+		t = nanosec();
 		tc = (t - t0) / Td;
 		if(tc <= 0)
 			tc = 1;