*** empty log message ***
authorMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 7 Sep 2006 07:25:33 +0000 (07:25 +0000)
committerMatthew Mondor <mmondor@pulsar-zone.net>
Thu, 7 Sep 2006 07:25:33 +0000 (07:25 +0000)
tests/entropy/entropy_disk.c

index 03fcec2..ce559ae 100644 (file)
  * Maximum number of BLOCK_SIZE blocks to read in a single read(2)
  */
 #define BLOCK_MULTIPLE 16
+/*
+ * Minimum and maximum number of reads to perform in a single direction before
+ * switching direction
+ */
+#define DIRECTION_MIN  64
+#define DIRECTION_MAX  2048
+
+enum direction {
+       DIR_FORWARD = 0,
+       DIR_BACKWARDS = 1
+};
 
 typedef struct drive_entry {
        SLIST_ENTRY(drive_entry) chain;
        char    *name;
-       off_t   max, lastpos;
-       int     lastdir, fd;
+       off_t   max, pos;
+       int     fd;
+       int     dir, dircnt;
 } disk_t;
 
 SLIST_HEAD(slisthead, drive_entry);
@@ -153,8 +165,9 @@ main(int argc, char **argv)
 
        /* Main loop */
        while (run) {
-               disk_t  *e;
-               int     blocks;
+               disk_t          *e;
+               int             blocks;
+               unsigned long   diff;
 
                /* Choose a disk */
                e = disks_array[random() % ndisks];
@@ -163,12 +176,39 @@ main(int argc, char **argv)
                blocks = random() % BLOCK_MULTIPLE;
 
                /*
-                * Choose a position relative to a previous one and which can
-                * withstand the block size
+                * Choose a position relative to a previous one and doesn't
+                * exceed e->max (which already accounts for the block size
+                * and is already BLOCK_SIZE aligned).  Our new position must
+                * also be BLOCK_SIZE aligned.
                 */
-               /* XXX */
+               diff = BALIGN_CEIL(random() % (e->max / DIRECTION_MIN),
+                   BLOCK_SIZE);
+               if (e->dir == DIR_BACKWARDS) {
+                       if ((e->pos -= diff) < 0)
+                               e->dir = DIR_FORWARD;
+               }
+               if (e->dir == DIR_FORWARD)
+                       e->pos = BALIGN_CEIL((e->pos + diff) % (e->max + 1),
+                           BLOCK_SIZE);
+               if (--e->dircnt < 0) {
+                       e->dir = (e->dir == DIR_FORWARD ?
+                           DIR_BACKWARDS : DIR_FORWARD);
+                       e->dircnt = DIRECTION_MIN +
+                           (random() % (DIRECTION_MAX - DIRECTION_MIN));
+               }
 
-               /* Finally read block and clear buffer */
+               /* Seek and read block(s) */
+               if (lseek(e->fd, e->pos, SEEK_SET) != -1) {
+                       if (read(e->fd, readbuf, blocks * BLOCK_SIZE) !=
+                           blocks * BLOCK_SIZE)
+                               (void) fprintf(stderr,
+                                   "read(%s, %llu, %u): %s\n",
+                                   e->name, e->pos, blocks * BLOCK_SIZE,
+                                   strerror(errno));
+               } else
+                       (void) fprintf(stderr,
+                           "lseek(%s, %llu): %s\n",
+                           e->name, e->pos, strerror(errno));
 
                /* Sleep for a slight random delay */
                (void) usleep(random() % 1000);
@@ -364,8 +404,22 @@ disk_open(const char *dname)
                    "lseek(%s): %s\n", devname, strerror(errno));
                goto err;
        }
-       e->lastpos = -1;
-       e->lastdir = 0;
+       /*
+        * Substract so that any position is valid for reading up to
+        * BLOCK_SIZE * BLOCK_MULTIPLE bytes.  We also ensure that size
+        * is always a multiple of BLOCK_SIZE.
+        */
+       e->max = BALIGN_CEIL(e->max - (BLOCK_SIZE * BLOCK_MULTIPLE),
+           BLOCK_SIZE);
+
+       /* Set a random but valid start position, BLOCK_SIZE aligned. */
+       e->pos = BALIGN_CEIL(((off_t)random() * (off_t)random()) %
+           (e->max + 1), BLOCK_SIZE);
+
+       /* And a random direction/count */
+       e->dir = random() % 2;
+       e->dircnt = DIRECTION_MIN +
+           (random() % (DIRECTION_MAX - DIRECTION_MIN));
 
        SLIST_INSERT_HEAD(&disks_list, e, chain);
        ndisks++;