Add a timer and a discard option.
authormdw <mdw>
Fri, 4 Aug 2000 23:24:15 +0000 (23:24 +0000)
committermdw <mdw>
Fri, 4 Aug 2000 23:24:15 +0000 (23:24 +0000)
rspit.c

diff --git a/rspit.c b/rspit.c
index ac19580..01ebf4d 100644 (file)
--- a/rspit.c
+++ b/rspit.c
@@ -1,6 +1,6 @@
 /* -*-c-*-
  *
- * $Id: rspit.c,v 1.8 2000/07/29 22:05:47 mdw Exp $
+ * $Id: rspit.c,v 1.9 2000/08/04 23:24:15 mdw Exp $
  *
  * Spit out random numbers
  *
@@ -30,6 +30,9 @@
 /*----- Revision history --------------------------------------------------* 
  *
  * $Log: rspit.c,v $
+ * Revision 1.9  2000/08/04 23:24:15  mdw
+ * Add a timer and a discard option.
+ *
  * Revision 1.8  2000/07/29 22:05:47  mdw
  * Fix error in help message about Maurer test syntax.
  *
@@ -226,7 +229,9 @@ enum {
   f_progress = 1,
   f_file = 2,
   f_fips = 4,
-  f_maurer = 8
+  f_maurer = 8,
+  f_timer = 16,
+  f_discard = 32
 };
 
 /*----- Help options ------------------------------------------------------*/
@@ -265,6 +270,8 @@ common core set:\n\
 -o, --output FILE      Write output to FILE, not stdout.\n\
 -z, --size SIZE                Emit SIZE bytes, not an unlimited number.\n\
 -p, --progress         Show a little progress meter (on stderr).\n\
+-T, --timer            Keep track of the CPU time used by the generator.\n\
+-d, --discard          Discard the generated output.\n\
 \n\
 (A SIZE may be followed by `g' for gigabytes, `m' for megabytes, or\n\
 `k' for kilobytes.  If unqualified, an amount in bytes is assumed.)\n\
@@ -289,13 +296,15 @@ static struct option opts[] = {
   { "output",  OPTF_ARGREQ,    0,      'o' },
   { "size",    OPTF_ARGREQ,    0,      'z' },
   { "progress",        0,              0,      'p' },
+  { "timer",   0,              0,      'T' },
+  { "discard", 0,              0,      'd' },
 
   /* --- End of main table --- */
 
   { 0,         0,              0,      0 }
 };
 
-static const char *sopts = "hvu lfm::o:z:p";
+static const char *sopts = "hvu lfm::o:z:pTd";
 
 #ifndef OPTION_V
    DA_DECL(option_v, struct option);
@@ -409,6 +418,12 @@ static int opt(void)
       case 'p':
        flags |= f_progress;
        break;
+      case 'T':
+       flags |= f_timer;
+       break;
+      case 'd':
+       flags |= f_discard;
+       break;
       default:
        return (i);
     }
@@ -1108,12 +1123,15 @@ static int generate(grand *r, size_t outsz,
                    int (*func)(const void *buf, size_t sz, void *p),
                    void *p)
 {
+  static char kmg[] = { ' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y', 0 };
+
   unsigned percent = 0;
   size_t kb = 0;
   time_t last;
   static char baton[] = "-\\|/";
   char *bp;
   int rc;
+  clock_t clk = 0;
 
   /* --- Spit out random data --- */
 
@@ -1133,9 +1151,10 @@ static int generate(grand *r, size_t outsz,
   signal(SIGPIPE, SIG_IGN);
 #endif
 
-  for (;;) {
+  do {
     octet buf[BUFSIZ];
     size_t sz = sizeof(buf);
+    clock_t c_start, c_stop;
 
     /* --- Emit a bufferful (or less) of data --- */
 
@@ -1143,8 +1162,11 @@ static int generate(grand *r, size_t outsz,
       if (sz > outsz - kb)
        sz = outsz - kb;
     }
+    c_start = clock();
     r->ops->fill(r, buf, sz);
-    if ((rc = func(buf, sz, p)) != 0)
+    c_stop = clock();
+    clk += c_stop - c_start;
+    if (func && (rc = func(buf, sz, p)) != 0)
       return (rc);
     kb += sz;
 
@@ -1181,12 +1203,12 @@ static int generate(grand *r, size_t outsz,
 
       if (up) {
        size_t q = kb;
-       char *suff = " KMG";
-       while (q > 8192 && suff[1]) {
+       char *kk = kmg;
+       while (q > 8192 && kk[1]) {
          q >>= 10;
-         suff++;
+         kk++;
        }
-       fprintf(stderr, "%4i%c\r[", q, *suff);
+       fprintf(stderr, "%4i%c\r[", q, *kk);
        if (outsz) {
          unsigned pc;
          for (pc = 0; pc < (percent & ~1); pc += 2)
@@ -1209,12 +1231,20 @@ static int generate(grand *r, size_t outsz,
 
     /* --- Terminate the loop --- */
 
-    if (outsz && kb >= outsz)
-      break;
-  }
+  } while (!outsz || kb < outsz);
 
   if (flags & f_progress)
     fputc('\n', stderr);
+  if (flags & f_timer) {
+    double sec = (double)clk/CLOCKS_PER_SEC;
+    double bps = (outsz << 3)/sec;
+    char *kk;
+
+    for (kk = kmg; bps > 1024 && kk[1]; kk++, bps /= 1024)
+      ;
+    fprintf(stderr, "generated %lu bytes in %g secs (%g %cb/s)\n",
+           (unsigned long)outsz, sec, bps, *kk);
+  }
   return (0);
 }
 
@@ -1293,7 +1323,7 @@ int main(int ac, char *av[])
     if (rc & FIPSTEST_LONGRUNS)
       moan("failed long runs test");
     if (!rc && (flags & f_progress))
-      puts("test passed");
+      fputs("test passed\n", stderr);
     return (rc ? EXIT_FAILURE : 0);
   }
 
@@ -1341,12 +1371,19 @@ int main(int ac, char *av[])
        }
       }
       if (flags & f_progress)
-       printf("bits = %u, Z_u = %g\n", i, z);
+       fprintf(stderr, "bits = %u, Z_u = %g\n", i, z);
     }
 
     return (rc);
   }
 
+  /* --- Discard --- */
+
+  if (flags & f_discard) {
+    generate(r, outsz, 0, 0);
+    return (0);
+  }
+
   /* --- Write to a file --- */
 
 #ifndef PORTABLE