/* stat_run - a simple front end to gangfs to help with timing tests prerun "rc scale 1" to start things up Copyright (C) 2010, IBM Corporation, John (EBo) David (jldavid@us.ibm.com) */ #include #include #include #include #include #include <9p.h> #include #include #include #include "debug.h" #include "timeit.h" static void usage(void) { fprint(2, "stat_run [-D] [-v debug_level] [-N num_tasks] [-m mtpt] [-t tmpfile] [-l log_file] command\n"); exits("usage"); } static int mountgang(char *srv, char *path, char *name) { int fd, ret; char *srvpt = smprint("/srv/%s", srv); fd = open(srvpt, ORDWR); if(fd<0) { DPRINT(DERR, "*ERROR*: couldn't open %s: %r\n", srvpt); free(srvpt); return -1; } free(srvpt); DPRINT(DFID, "mountgang: mounting name=(%s) on path=(%s) pid=(%d) fd=%d\n", name, path, getpid(), fd); ret = mount(fd, -1, path, MBEFORE|MCREATE, name); if(ret<0) DPRINT(DERR, "\t*ERROR*: mpipe mount failed: %r\n"); close(fd); return ret; } void main(int argc, char **argv) { char *command, *procpath="/n/io/proc"; //char *tmpfile="/tmp/tmp1"; //char *tmpfile="tests/.test/tmp1"; char *tmpfile=nil; char *srvnm="io"; char *log_file=nil; int i, num_tasks=1; char *x; int loop=0, use_cycles=0; char line[1024], gstdout[1024]; ARGBEGIN{ case 'D': chatty9p++; break; case 'v': x = ARGF(); if(x) vflag = atol(x); break; case 'm': /* mntpt override */ procpath = ARGF(); break; case 'l': log_file = ARGF(); break; case 'L': loop = 1; break; case 't': tmpfile = estrdup9p(ARGF()); break; case 'N': num_tasks = atoi(ARGF()); break; case 'C': use_cycles = 1; break; default: usage(); }ARGEND if(argc <= 0) usage(); command = estrdup9p(argv[0]); for(i=1; i"); DPRINT(DARG, "\tprocpath=(%s)\n", procpath); DPRINT(DARG, "\tnum_tasks=(%d)\n", num_tasks); mountgang(srvnm, "/n/io", ""); /* uvlong ftime, stime; uvlong ttime; slice(ftime); sleep(10000); slice(stime); ttime = (stime-ftime)/10; fprint(2,"f/stime = %ulld\n", ttime); */ timeit_init(); timeit_settype(TIMIT_DEFAULT); timeit_setcycles(use_cycles); if(log_file) timeit_setout(log_file); if(loop) loop = num_tasks; if(num_tasks<=0){ DPRINT(DERR, "*ERROR*: num_tasks must be greater than 0\n"); exits("invalid num_tasks"); } do{ int gfdi, gfdo; int gnum, n; int tmpfd=1; snprint(line, 1024, "%s/gclone", procpath); if((gfdi=open(line,ORDWR)) < 0){ DPRINT(DERR, "*ERROR*: could not open gclone file (%s)\n", line); exits("could not open gclone"); } if(loop) num_tasks = loop; print("tasks = %d\n", num_tasks); n = read(gfdi, line, 256); if(n<0){ DPRINT(DERR, "*ERROR*: read failed\n"); exits("could not read clone file"); } line[n] = 0; gnum = atoi(line); DPRINT(DFID, "Main: gclone number = g%d\n", gnum); DPRINT(DFID, "\tnum_tests=%d\n", num_tasks); stamp("BEGIN"); fprint(gfdi, "res %d", num_tasks); stamp("RES"); snprint(gstdout, 1024, "%s/g%d/stdout", procpath, gnum); gfdo = open(gstdout,OREAD); if(gfdo < 0){ DPRINT(DERR, "*ERROR*: could not open stdout file (%s)\n", gstdout); exits("could not open stdout"); } stamp("finish opening stdout"); fprint(gfdi, "exec %s", command); stamp("EXEC"); if(tmpfile!=nil){ sprint(line, "%s", tmpfile); print("opening tmpfile %s\n", line); if((tmpfd=open(line,OWRITE|OTRUNC)) < 0){ if((tmpfd=create(line,OWRITE,0666)) < 0){ DPRINT(DERR, "*ERROR*: could not open tmpfile (%s)\n", line); exits("could not open tmpfile"); } } } /* // FIXME: bind sais this is inconsistent if(tmpfile!=nil){ int ret; //close(gfdo); ret = bind(tmpfile, gstdout, MBEFORE); if(ret < 0){ DPRINT(DERR, "bind failed: %r\n"); exits("bind failed"); } } dup(gfdo, 1); */ // dup(tmpfd, 1); // int p[2]; // pipe(p); // dup(p[1], 1); // close(p[0]); // close(p[1]); // FIXME: there is a better way to do this than here... DPRINT(DFID, "num_tasks=(%d) for output\n", num_tasks); for(i=0; i1) close(tmpfd); close(gfdi); close(gfdo); timeit_dump(); fprint(2, "\n"); loop /= 2; num_tasks = loop; } while (num_tasks>0); exits(0); }