From 77fb4c791241998a85496388337a2d4c80e512c7 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 22 Jul 2021 16:50:09 -0400 Subject: Add -b (benchmark) flag --- slowbaud.c | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) (limited to 'slowbaud.c') diff --git a/slowbaud.c b/slowbaud.c index bbf31ac..63a8a3b 100644 --- a/slowbaud.c +++ b/slowbaud.c @@ -26,7 +26,7 @@ #include #endif -#define DEFAULT_BPS 1200 +#define DEFAULT_BPS 2400 #define MIN_BPS 1 #define MAX_BPS 500000 @@ -67,6 +67,8 @@ void setup_timer(void) { sigprocmask(SIG_BLOCK, &sigmask, NULL); } +/* on both Linux and OSX, using setitimer() and sigwait() gives better + timing accuracy than usleep() or nanosleep(). */ void slow_write(int outfd, char c) { int j; unsigned long now, target, overslept; @@ -84,13 +86,8 @@ void slow_write(int outfd, char c) { if(now > target) { overslept = now - target; if(overslept < interval) { - unsigned long old = itv.it_interval.tv_usec; itv.it_interval.tv_usec -= overslept; itv.it_value.tv_usec = itv.it_interval.tv_usec; - if(debug) { - fprintf(stderr, "tv_usec was %ldms, overslept %ld, new tv_usec %ldms\n", - old, overslept, itv.it_interval.tv_usec); - } } } else { while(NOW_USEC() < target) @@ -99,24 +96,25 @@ void slow_write(int outfd, char c) { } void debug_stats(void) { - if(outbytes && debug) { + if(outbytes) { unsigned long elapsed_us = NOW_USEC() - starttime; double elapsed_sec = ((double)elapsed_us/1000000.0L); double finterval = (1000000.0L / ((double)bps / 10.0L)); double actual = ((double)outbytes * 10.0L) / elapsed_sec; double offby = 100.0L * (((double)bps / actual) - 1.0L); fprintf(stderr, - "outbytes %lu, elapsed_us %lu, requested bps %d (%.2fms), " + "outbytes %lu, elapsed_us %lu, tv_usec %lu, requested bps %d (%.2fms), " "actual %.2f, accuracy %.2f%%\n", - outbytes, elapsed_us, bps, finterval, actual, 100.0 - offby); + outbytes, elapsed_us, itv.it_value.tv_usec, bps, finterval, actual, 100.0 - offby); } - outbytes = 0; } void slowcat(int infd) { int c; + outbytes = 0; starttime = NOW_USEC(); + while(read(infd, &c, 1) == 1) { slow_write(1, c); } @@ -216,12 +214,32 @@ void echo_args(char **args) { exit(0); } +void benchmark(char **args) { + int bytes = 0, devnull; + + if(*args) bytes = atoi(*args); + if(bytes < 1) bytes = 4096; + fprintf(stderr, "benchmarking with %d bytes\n", bytes); + + devnull = open("/dev/null", O_RDONLY); + if(devnull < 1) die("/dev/null"); + + starttime = NOW_USEC(); + while(bytes--) + slow_write(devnull, 0); + close(devnull); + + debug_stats(); + exit(0); +} + void usage(int exitstat) { printf("Usage: %s [] [ [ ...]]\n", self); printf(" With no filenames, reads stdin.\n"); printf("or: %s [] -c [ [ ...]]\n", self); printf(" With no command, spawns a shell.\n"); printf("or: %s [] -e [ ...]\n", self); + printf("or: %s [] -b []\n", self); printf("With no , default rate is %d\n", DEFAULT_BPS); exit(exitstat); } @@ -232,6 +250,7 @@ int main(int argc, char **argv) { if(getenv("SLOWBAUD_DEBUG")) debug = 1; + /* for usage message, we want "slowbaud", not "/path/to/slowbaud" */ self = argv[0]; for(p = argv[0]; *p; p++) { if(*p == '/') self = p + 1; @@ -259,7 +278,12 @@ int main(int argc, char **argv) { } /* if we used only integer math here, we couldn't support bps not - a multiple of 10 (e.g. 75 would be taken as 70). */ + a multiple of 10 (e.g. 75 would be taken as 70). + We still have a rounding problem: 115200bps is 86.81ms/char, but + it gets rounded down to 86 here. Which would be around 116279bps, + or almost 1% too fast. We never reach 100% speed anyway, so the + loss from overhead actually offsets the extra bit of speed. + */ interval = (unsigned long)(1000000.0L / ((double)bps / 10.0L)); if(debug) fprintf(stderr, "interval %ld us\n", interval); @@ -284,6 +308,9 @@ int main(int argc, char **argv) { if(debug) fprintf(stderr, "-e given, echoing args\n"); echo_args(++argv); break; + case 'b': + benchmark(++argv); + break; case 'h': case '?': usage(0); -- cgit v1.2.3