259 lines · 5.1 KB · C
RawDownload
/*  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 <u.h>#include <libc.h>#include <ctype.h>#include <fcall.h>#include <thread.h>#include <9p.h>#include <mp.h>#include <libsec.h>#include <stdio.h>#include "debug.h"#include "timeit.h" static voidusage(void){	fprint(2, "stat_run [-D] [-v debug_level] [-N num_tasks] [-m mtpt] [-t tmpfile] [-l log_file] command\n"); 	exits("usage");} static intmountgang(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;} voidmain(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<argc; i++){		command = erealloc9p(command, strlen(command)+strlen(argv[i])+2);		strcat(command, " ");		strcat(command, argv[i]);	} 	DPRINT(DARG, "Main: command=(%s)\n", command);	DPRINT(DARG, "\ttmpfile=(%s)\n", (tmpfile!=nil)?tmpfile:"<nil>");	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; i<num_tasks; i++){			// read in a full buffer....			n = read(gfdo, line, 1024);			if(n<=0) break;						n = write(tmpfd, line, n);			if(n<=0) break;		};				stamp("OUT"); 		// FIXME: close the ctl file timing...		stamp("TERM");				timeit_setfd(2);		timeit_end(); 		timeit_settype(TIMIT_FLOAT); 		timeit_tag_dt2_sec("BEGIN", "RES", "Time for stat_run RES");		timeit_tag_dt2_sec("finish opening stdout", "EXEC", "Time for EXEC");		timeit_tag_dt2_sec("EXEC", "OUT", "Time for OUT");		timeit_tag_dt2_sec("OUT", "TERM", "Time for TERM");				timeit_tag_dt2_sec("BEGIN", "OUT", "Total time");				if(tmpfd>1)			close(tmpfd);		close(gfdi);		close(gfdo);				timeit_dump();		fprint(2, "\n"); 		loop /= 2;		num_tasks = loop;			} while (num_tasks>0); 	exits(0);}