From 41957bd369ef39697aba39d5b60297bbbbf44f7f Mon Sep 17 00:00:00 2001
From: "B. Watson" <yalhcru@gmail.com>
Date: Fri, 23 Jul 2021 14:24:11 -0400
Subject: Add fractional microsecond support

---
 Makefile   |  3 +++
 slowbaud.c | 20 +++++++++++++++++++-
 2 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/Makefile b/Makefile
index 084bee4..3cd67e0 100644
--- a/Makefile
+++ b/Makefile
@@ -16,6 +16,9 @@ $(PROJ).1: $(PROJ).rst
 README.txt: $(PROJ).1
 	man ./$(PROJ).1 | sed 's,_\010,,' > README.txt
 
+test: all
+	sh test.sh
+
 # Don't remove the man page or README here, it's in git.
 clean:
 	rm -f $(PROJ) core *.o
diff --git a/slowbaud.c b/slowbaud.c
index 63a8a3b..e0ad048 100644
--- a/slowbaud.c
+++ b/slowbaud.c
@@ -41,6 +41,13 @@ struct timeval tv;
 struct itimerval itv, itv_disarm;
 sigset_t sigmask;
 
+#define FRACTIONAL_USEC
+
+#ifdef FRACTIONAL_USEC
+#define FRAC_US_DENOM 100
+int frac_us_num;
+#endif
+
 #define NOW_USEC() ( (gettimeofday(&tv, NULL)), tv.tv_sec * 1000000L + tv.tv_usec )
 
 void die(const char *msg) {
@@ -77,6 +84,10 @@ void slow_write(int outfd, char c) {
 
 	target = NOW_USEC() + interval;
 
+#ifdef FRACTIONAL_USEC
+	if((random() % FRAC_US_DENOM) < frac_us_num) target++;
+#endif
+
 	write(outfd, &c, 1);
 	outbytes++;
 	sigwait(&sigmask, &j);
@@ -85,7 +96,8 @@ void slow_write(int outfd, char c) {
 	now = NOW_USEC();
 	if(now > target) {
 		overslept = now - target;
-		if(overslept < interval) {
+		if(overslept < itv.it_interval.tv_usec) {
+			// fprintf(stderr, "overslept %luus\n", overslept);
 			itv.it_interval.tv_usec -= overslept;
 			itv.it_value.tv_usec = itv.it_interval.tv_usec;
 		}
@@ -287,6 +299,12 @@ int main(int argc, char **argv) {
 	interval = (unsigned long)(1000000.0L / ((double)bps / 10.0L));
 	if(debug) fprintf(stderr, "interval %ld us\n", interval);
 
+#ifdef FRACTIONAL_USEC
+	frac_us_num = (double)FRAC_US_DENOM * ((1000000.0L / ((double)bps / 10.0L) - interval));
+	fprintf(stderr, "%d %d\n", interval, frac_us_num);
+	// srandom(NOW_USEC());
+#endif
+
 	if(*argv && argv[0][0] == '-' && argv[0][1] == '-' && !argv[0][2]) {
 		if(debug) fprintf(stderr, "skipping -- argument\n");
 		argv++, argc--;
-- 
cgit v1.2.3