From: ian Date: Sun, 16 Jan 2005 00:09:04 +0000 (+0000) Subject: usleep_gettod to replace usleep (which is very coarse and tends to sleep for 20ms... X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ijackson/git?a=commitdiff_plain;h=e6bc056b9f817471e3b43980f6fb913d86ce8065;p=trains.git usleep_gettod to replace usleep (which is very coarse and tends to sleep for 20ms every time! also, siggen supports limiting total number of iterations --- diff --git a/parport/lib.c b/parport/lib.c index f36eef4..096fc7c 100644 --- a/parport/lib.c +++ b/parport/lib.c @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include #include @@ -33,3 +35,24 @@ unsigned long number(const char *a) { } return v; } + +static void gettod(struct timeval *now_r) { + int r; + r= gettimeofday(now_r,0); + if (r) { perror("gettimeofday failed"); exit(127); } +} + +void usleep_gettod(unsigned long us) { + struct timeval start, end, now; + ldiv_t ld; + + gettod(&start); + + ld= ldiv(start.tv_usec + us, 1000000); + end.tv_sec= start.tv_sec + ld.quot; + end.tv_usec= ld.rem; + + do { + gettod(&now); + } while (timercmp(&now,&end,<)); +} diff --git a/parport/lib.h b/parport/lib.h index 8372ec8..77f4583 100644 --- a/parport/lib.h +++ b/parport/lib.h @@ -4,6 +4,7 @@ #define LIB_H void doioctl(int ioctlnum, void *vp, unsigned long vpv); +void usleep_gettod(unsigned long us); unsigned long number(const char *a); extern int fd; diff --git a/parport/siggen.c b/parport/siggen.c index c5bc73a..c04004e 100644 --- a/parport/siggen.c +++ b/parport/siggen.c @@ -18,23 +18,40 @@ static void badusage(void) { " t PPWDATA value\n" " w usleep(value)\n" "options:\n" + " n do whole list n times\n" " m do every item m times\n"); } int main(int argc, const char *const *argv) { - int ii, io=0, m=1; + int ii, io=0, m=1, n=-1, loops_count, loops_n, loops_incr; + unsigned long ul; unsigned char v; const char *a; argc--; argv++; - if (argc>=1 && (a=argv[0]) && a[0]=='m') { - m= number(a+1); + while (argc>=1 && (a=argv[0])) { + switch (a[0]) { + case 'm': m= number(a+1); break; + case 'n': n= number(a+1); break; + default: goto loop_break_options; + } argc--; argv++; } +loop_break_options: if (argc<1) badusage(); - for (ii=0; ; ii++, ii%=(argc*m)) { + + if (n==-1) { + loops_n= 1; + loops_incr= 0; + } else { + loops_n= n * argc * m; + loops_incr= 1; + } + for (ii=0, loops_count=0; + loops_count < loops_n; + ii++, ii%=(argc*m), loops_count += loops_incr) { a= argv[ii/m]; switch (a[0]) { case 'k': io= PPWCONTROL; break; @@ -42,11 +59,13 @@ int main(int argc, const char *const *argv) { case 'w': io= -1; break; default: badusage(); } - v= number(a+1); + ul= number(a+1); if (io==-1) { - usleep(v); + usleep_gettod(ul); } else { + v= ul; doioctl(io, &v, v); } } + return 0; }