Jacks program for testing multiple concurrent reader scalability.
authorfsgqa <fsgqa>
Thu, 5 Feb 2004 02:59:08 +0000 (02:59 +0000)
committerfsgqa <fsgqa>
Thu, 5 Feb 2004 02:59:08 +0000 (02:59 +0000)
src/scaleread.c [new file with mode: 0644]
src/scaleread.sh [new file with mode: 0644]

diff --git a/src/scaleread.c b/src/scaleread.c
new file mode 100644 (file)
index 0000000..a0ddbc1
--- /dev/null
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2003-2004 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * 
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+/*
+ * Test scaling of multiple processes opening/reading
+ * a number of small files simultaneously.
+ *     - create <f> files
+ *     - fork <n> processes
+ *     - wait for all processes ready
+ *     - start all proceses at the same time
+ *     - each processes opens , read, closes each file
+ *     - option to resync each process at each file
+ *
+ *     test [-c cpus] [-b bytes] [-f files] [-v] [-s] [-S]
+ *                     OR
+ *     test -i [-b bytes] [-f files] 
+ */
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <sys/ipc.h>
+#include <sys/shm.h>
+
+void do_initfiles(void);
+void slave(int);
+
+#define VPRINT(x...)   do { if(verbose) fprintf(x);} while(0)
+#define perrorx(s) do {perror(s); exit(1);} while (0)
+
+long bytes=8192;
+int cpus=1;
+int init=0;
+int strided=0;
+int files=1;
+int blksize=512;
+int syncstep=0;
+int verbose=0;
+
+typedef struct {
+        volatile long   go;
+        long            fill[15];
+        volatile long   rdy[512];
+} share_t;
+
+share_t        *sharep;
+
+
+int
+runon(int cpu)
+{
+#ifdef sys_sched_setaffinity
+       unsigned long mask[8];
+       
+       if (cpu < 0 || cpu >= 512)
+               return -1;
+       memset(mask, 0, sizeof(mask));
+       mask[cpu/64] |= 1UL<<(cpu&63);
+
+       if (syscall(sys_sched_setaffinity, 0, sizeof(mask), mask))
+               return -1;
+#endif
+       return 0;
+}
+
+long
+scaled_atol(char *p)
+{
+       long val;
+       char  *pe;
+
+       val = strtol(p, &pe, 0);
+       if (*pe == 'K' || *pe == 'k')
+               val *= 1024L;
+       else if (*pe == 'M' || *pe == 'm')
+               val *= 1024L*1024L;
+       else if (*pe == 'G' || *pe == 'g')
+               val *= 1024L*1024L*1024L;
+       else if (*pe == 'p' || *pe == 'P')
+               val *= getpagesize();
+       return val;
+}
+
+
+int
+main(int argc, char** argv) {
+        int shmid;
+        static  char            optstr[] = "c:b:f:sSivH";
+        int                     notdone, stat, i, j, c, er=0;
+
+        opterr=1;
+        while ((c = getopt(argc, argv, optstr)) != EOF)
+                switch (c) {
+                case 'c':
+                        cpus = atoi(optarg);
+                        break;
+                case 'b':
+                        bytes = scaled_atol(optarg);
+                        break;
+                case 'f':
+                        files = atoi(optarg);
+                        break;
+                case 'i':
+                        init++;
+                        break;
+                case 's':
+                        syncstep++;
+                        break;
+                case 'S':
+                        strided++;
+                        break;
+                case 'v':
+                        verbose++;
+                        break;
+                case '?':
+                        er = 1;
+                        break;
+                }
+        if (er) {
+                printf("usage: %s %s\n", argv[0], optstr);
+                exit(1);
+        }
+
+
+       if ((shmid = shmget(IPC_PRIVATE, sizeof (share_t), IPC_CREAT|SHM_R|SHM_W))  == -1)
+               perrorx("shmget failed");
+       sharep = (share_t*)shmat(shmid, (void*)0, SHM_R|SHM_W);
+       memset(sharep, -1, sizeof (share_t));
+
+       if (init) {
+               do_initfiles();
+               exit(0);
+       }
+        for (i=0; i<cpus; i++) {
+                if (fork() == 0)
+                        slave(i);
+        }
+
+       for (i=0; i<files; i++) {
+               VPRINT(stderr, "%d:", i);
+               notdone = cpus;
+               do {
+                       for (j=0; j<cpus; j++) {
+                               if (sharep->rdy[j] == i) {
+                                       sharep->rdy[j] = -1;
+                                       VPRINT(stderr, " %d", j);
+                                       notdone--;
+                               }
+                       }
+               } while (notdone);
+               VPRINT(stderr, "\n");
+               sharep->go = i;
+               if (!syncstep)
+                       break;
+       }
+       VPRINT(stderr, "\n");
+
+        while (wait(&stat)> 0)
+               VPRINT(stderr, ".");
+       VPRINT(stderr, "\n");
+
+       exit(0);
+}
+
+void 
+slave(int id)
+{
+       int     i, fd, byte;
+       char    *buf, filename[32];
+
+       runon (id+1);
+       buf = malloc(blksize);
+       bzero(buf, blksize);
+       for (i=0; i<files; i++) {
+               if (!i || syncstep) {
+                       sharep->rdy[id] = i;
+                       while(sharep->go != i);
+               }
+               sprintf(filename, "/tmp/tst.%d", (strided ? ((i + id) % files) : i));
+               if ((fd = open (filename, O_RDONLY)) < 0) {
+                       perrorx(filename);
+               }
+       
+               for (byte=0; byte<bytes; byte+=blksize) {
+                       if (read (fd, buf, blksize) != blksize)
+                               perrorx("read of file failed");
+               }
+               close(fd);
+       }
+       exit(0);
+}
+
+void
+do_initfiles(void)
+{
+       int     i, fd, byte;
+       char    *buf, filename[32];
+
+       buf = malloc(blksize);
+       bzero(buf, blksize);
+
+       for (i=0; i<files; i++) {
+               sprintf(filename, "/tmp/tst.%d", i);
+               unlink(filename);
+               if ((fd = open (filename, O_RDWR|O_CREAT, 0644)) < 0)
+                       perrorx(filename);
+       
+               for (byte=0; byte<bytes; byte+=blksize) {
+                       if (write (fd, buf, blksize) != blksize)
+                               perrorx("write of file failed");
+               }
+               close(fd);
+       }
+       sync();
+}
+
+
diff --git a/src/scaleread.sh b/src/scaleread.sh
new file mode 100644 (file)
index 0000000..acc1283
--- /dev/null
@@ -0,0 +1,92 @@
+#!/bin/sh
+#
+# Copyright (c) 2003-2004 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or modify it
+# under the terms of version 2 of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+#
+# Further, this software is distributed without any warranty that it is
+# free of the rightful claim of any third person regarding infringement
+# or the like.  Any license provided herein, whether implied or
+# otherwise, applies only to this software file.  Patent licenses, if
+# any, provided herein do not apply to combinations of this program with
+# other software, or any other product whatsoever.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write the Free Software Foundation, Inc., 59
+# Temple Place - Suite 330, Boston MA 02111-1307, USA.
+#
+# Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+# Mountain View, CA  94043, or:
+#
+# http://www.sgi.com
+#
+# For further information regarding this notice, see:
+#
+# http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+#
+
+help() {
+cat <<END
+Measure scaling of multiple cpus readin the same set of files.
+(NASA testcase).
+       Usage:  $0 [-b <bytes>] [-f <files>] [-s] [-B] [-v] cpus ...
+                       or
+               $0 -i [-b <bytes>] [-f <files>] 
+
+         -b file size in bytes
+         -f number of files
+         -s keep processes synchronized when reading files
+         -B use bcfree to free buffer cache pages before each run
+END
+exit 1
+}
+
+err () {
+       echo "ERROR - $*"
+       exit 1
+}
+
+BYTES=8192
+FILES=10
+SYNC=""
+VERBOSE=""
+STRIDED=""
+BCFREE=0
+INIT=0
+OPTS="f:b:vsiSBH"
+while getopts "$OPTS" c ; do
+       case $c in
+               H)  help;;
+               f)  FILES=${OPTARG};;
+               b)  BYTES=${OPTARG};;
+               i)  INIT=1;;
+               B)  BCFREE=1;;
+               S)  STRIDED="-S";;
+               s)  SYNC="-s";;
+               v)  VERBOSE="-v";;
+               \?) help;;
+       esac
+
+done
+shift `expr $OPTIND - 1`
+
+if [ $INIT -gt 0 ] ; then
+       echo "Initializing $BYTES bytes, $FILES files"
+       ./scaleread $VERBOSE -i -b $BYTES -f $FILES 
+       sync
+else
+       [ $# -gt 0 ] || help
+       echo "Testing $BYTES bytes, $FILES files"
+       for CPUS in $* ; do
+               [ $BCFREE -eq 0 ] || bcfree -a
+               /usr/bin/time -f "$CPUS:  %e wall,    %S sys,   %U user" ./scaleread \
+                       $SYNC $STRIDED $VERBOSE -b $BYTES -f $FILES -c $CPUS
+       done
+fi
+