pimp readtest.
authorRobin Gareus <robin@gareus.org>
Thu, 12 Mar 2015 12:15:12 +0000 (13:15 +0100)
committerRobin Gareus <robin@gareus.org>
Thu, 12 Mar 2015 12:15:12 +0000 (13:15 +0100)
tools/readtest.c
tools/run-readtest.sh

index 4e046295838a63e758d9f9f621e4949cc4436a52..95907f530e2489a3e920cdf4f1a79426515d568e 100644 (file)
@@ -1,5 +1,9 @@
 /* gcc -o readtest readtest.c `pkg-config --cflags --libs glib-2.0` -lm */
 
+#ifndef _WIN32
+#  define HAVE_MMAP
+#endif
+
 #include <stdlib.h>
 #include <errno.h>
 #include <stdio.h>
 #include <fcntl.h>
 #include <math.h>
 
+#ifdef HAVE_MMAP
+#  include <sys/stat.h>
+#  include <sys/mman.h>
+#endif
+
 #include <glib.h>
 
 char* data = 0;
@@ -17,22 +26,30 @@ char* data = 0;
 void
 usage ()
 {
-       fprintf (stderr, "readtest [ -b BLOCKSIZE ] [-l FILELIMIT] [ -D ] filename-template\n");
+       fprintf (stderr, "readtest [ -b BLOCKSIZE ] [-l FILELIMIT] [ -D ] [ -R ] [ -M ] filename-template\n");
 }
 
 int
 main (int argc, char* argv[])
 {
        int* files;
-       char optstring[] = "b:Dl:q";
+       char optstring[] = "b:DRMl:q";
        uint32_t block_size = 64 * 1024 * 4;
        int max_files = -1;
 #ifdef __APPLE__
        int direct = 0;
+       int noreadahead = 0;
+#endif
+#ifdef HAVE_MMAP
+       int use_mmap = 0;
+       void  **addr;
+       size_t *flen;
 #endif
        const struct option longopts[] = {
                { "blocksize", 1, 0, 'b' },
                { "direct", 0, 0, 'D' },
+               { "mmap", 0, 0, 'M' },
+               { "noreadahead", 0, 0, 'R' },
                { "limit", 1, 0, 'l' },
                { 0, 0, 0, 0 }
        };
@@ -60,6 +77,16 @@ main (int argc, char* argv[])
                case 'D':
 #ifdef __APPLE__
                        direct = 1;
+#endif
+                       break;
+               case 'M':
+#ifdef HAVE_MMAP
+                       use_mmap = 1;
+#endif
+                       break;
+               case 'R':
+#ifdef __APPLE__
+                       noreadahead = 1;
 #endif
                        break;
                case 'q':
@@ -105,6 +132,15 @@ main (int argc, char* argv[])
        
        nfiles = n;
        files = (int *) malloc (sizeof (int) * nfiles);
+#ifdef HAVE_MMAP
+       if (use_mmap) {
+               if (!quiet) {
+                       printf ("# Using mmap().\n");
+               }
+               addr = malloc (sizeof (void*) * nfiles);
+               flen = (size_t*) malloc (sizeof (size_t) * nfiles);
+       }
+#endif
 
        for (n = 0; n < nfiles; ++n) {
 
@@ -128,9 +164,35 @@ main (int argc, char* argv[])
                                fprintf (stderr, "Cannot set F_NOCACHE on file #%d\n", n);
                        }
                }
+
+               if (noreadahead) {
+                       if (fcntl (fd, F_RDAHEAD, 0) == -1) {
+                               fprintf (stderr, "Cannot set F_READAHED on file #%d\n", n);
+                       }
+               }
 #endif
 
                files[n] = fd;
+
+#ifdef HAVE_MMAP
+               if (use_mmap) {
+                       struct stat s;
+                       if (fstat (fd, & s)) {
+                               fprintf (stderr, "Could not stat fd #%d @ %s\n", n, path);
+                               return 1;
+                       }
+                       if (s.st_size < block_size) {
+                               fprintf (stderr, "file is shorter than blocksize #%d @ %s\n", n, path);
+                               return 1;
+                       }
+                       flen[n] = s.st_size;
+                       addr[n] = mmap (0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+                       if (addr[n] == MAP_FAILED) {
+                               fprintf (stderr, "Could not mmap file #%d @ %s (%s)\n", n, path, strerror (errno));
+                               return 1;
+                       }
+               }
+#endif
        }
 
        data = (char*) malloc (sizeof (char) * block_size);
@@ -145,10 +207,22 @@ main (int argc, char* argv[])
                gint64 before;
                before = g_get_monotonic_time();
 
-               for (n = 0; n < nfiles; ++n) {
-
-                       if (read (files[n], (char*) data, block_size) != block_size) {
-                               goto out;
+#ifdef HAVE_MMAP
+               if (use_mmap) {
+                       for (n = 0; n < nfiles; ++n) {
+                               if (_read + n + block_size > flen[n]) {
+                                       goto out;
+                               }
+                               memmove(data, &addr[n][_read], block_size);
+                       }
+               }
+               else
+#endif
+               {
+                       for (n = 0; n < nfiles; ++n) {
+                               if (read (files[n], (char*) data, block_size) != block_size) {
+                                       goto out;
+                               }
                        }
                }
 
index e10a066fc854db19311448451f72e56753ab0faf..abdfb254c7b6260fbddfea7d29cfcc8dcb2dd5aa 100755 (executable)
@@ -7,6 +7,7 @@ nocache=
 interleave=
 needfiles=1
 write_blocksize=262144
+args=
 
 if uname -a | grep --silent arwin ; then
     ddmega=m
@@ -19,6 +20,9 @@ while [ $# -gt 1 ] ; do
        -d) dir=$2; shift; shift ;;
        -f) filesize=$2; shift; shift ;;
        -n) numfiles=$2; shift; shift ;;
+       -M) args="$args -M"; shift ;;
+       -D) args="$args -D"; shift ;;
+       -R) args="$args -R"; shift ;;
         *) break ;;
     esac
 done
@@ -81,5 +85,5 @@ for bs in $@ ; do
     fi
     
     echo "# Blocksize $bs"
-    ./readtest -b $bs -q $dir/testfile_%d
+    ./readtest $args -b $bs -q $dir/testfile_%d
 done