Esempio n. 1
0
//int PDQ_CreateNode(char *name, int device, int sched)
void PDQ_CreateNode(char *name, int device, int sched)
{
	extern          NODE_TYPE *node;
	extern char     s1[], s2[];
	extern int      nodes;
	extern int      PDQ_DEBUG;
	char           *p = "PDQ_CreateNode";
	FILE*			out_fd;

	if (PDQ_DEBUG)
	{
		debug(p, "Entering");
		out_fd = fopen("PDQ.out", "a");
		fprintf(out_fd, "name : %s  device : %d  sched : %d\n", name, device, sched);
		//PJP this really needed to be fclose
		//close(out_fd);
		fclose(out_fd);
	}

	if (k > MAXNODES) {
		sprintf(s1, "Allocating \"%s\" exceeds %d max nodes",
			name, MAXNODES);
		errmsg(p, s1);
	}

	if (strlen(name) >= MAXCHARS) {
		sprintf(s1, "Nodename \"%s\" is longer than %d characters",
			name, MAXCHARS);
		errmsg(p, s1);
	}

	strcpy(node[k].devname, name);

	
	if (sched == MSQ && device < 0) { 
		// interpret node as multiserver and
		// number of servers must be positive integer
		sprintf(s1, "Must specify MSQ node with CEN equal to positive number of servers");
		errmsg(p, s1);
	} 
	
	node[k].devtype = device;
	node[k].sched = sched;

	if (PDQ_DEBUG) {
		typetostr(s1, node[k].devtype);
		typetostr(s2, node[k].sched);
		PRINTF("\tNode[%d]: %s %s \"%s\"\n",
		  k, s1, s2, node[k].devname);
		resets(s1);
		resets(s2);
	};

	if (PDQ_DEBUG)
		debug(p, "Exiting");

    // update global node count
    k = ++nodes;
	
}  // PDQ_CreateNode
Esempio n. 2
0
int
getnode_index(char *name)
{
	char             *p = "getnode_index()";

	extern char       s1[];

	int               k = 0;

	if (PDQ_DEBUG)
		debug(p, "Entering");

	for (k = 0; k < nodes; k++) {
		if (strcmp(node[k].devname, name) == 0) {
			if (PDQ_DEBUG) {
				resets(s1);
				sprintf(s1, "node:\"%s\"  index: %d", name, k);
				debug(p, s1);
				resets(s1);
				debug(p, "Exiting");
			}
			return (k);
		}
	}

	/* if you are here, you're in deep yoghurt! */

	resets(s1);
	sprintf(s1, "Node name \"%s\" not found at index: %d", name, k);
	errmsg(p, s1);

	g_debug("[getnode_index]  Bad return value");

	return -1;
}  /* getnode_index */
Esempio n. 3
0
int
getjob_index(char *wname)
{
	char           *p = "getjob_index()";

	extern char     s1[];

	int             n = 0;

	if (PDQ_DEBUG)
		debug(p, "Entering");

	// g_debugf("=====>  wname -> \"%s\"\n", wname);
	
	if (wname) {
		for (n = 0; n < streams; n++) {
			char
				*job_term_name;

			if (0) {
				g_debugf("n[%d]  &job[%p]\n", n, &(job[n]));
				g_debugf("job[]:[%p]\n", &(job[n]));
				g_debugf("job[].term:[%p]\n", &(job[n].term));
				g_debugf("job[].term->name:[%s]\n", job[n].term->name);
			}

			if (job[n].term)
				job_term_name = job[n].term->name;
         else
				job_term_name = "UNDEFINED";
		 
			// g_debugf("job_term_name:[%s]\n", job_term_name);

			if ((strcmp(job_term_name, wname) == 0) ||
				   (strcmp(job[n].batch->name, wname) == 0) ||
				   (strcmp(job[n].trans->name, wname) == 0)) {
				if (PDQ_DEBUG) {
				   resets(s1);
				   sprintf(s1, "stream:\"%s\"  index: %d", wname, n);
				   debug(p, s1);
				   resets(s1);
				   debug(p, "Exiting");
				}
				return (n);
			}
		}
	}

	// g_debug("*** CRITICAL *** function needs to return something!\n");

   return -1;
}  /* getjob_index */
Esempio n. 4
0
void namex(int i, char *s, char *r)
/* append index i to string s and return it in r */
{
   extern char     s1[], s2[];
   extern void     resets();

   resets(r);
   resets(s1);
   resets(s2);
   strcpy(s1, s);
   itoa(i, s2);
   strcat(s1, s2);
   strcpy(r, s1);
}
Esempio n. 5
0
void create_batch_stream(int net, char* label, double number)
{
	extern JOB_TYPE *job;
	extern char     s1[];
	extern int      PDQ_DEBUG;
	char           *p = "create_batch_stream()";

	if (PDQ_DEBUG)
		debug(p, "Entering");

	/***** using global value of n *****/

	strcpy(job[c].batch->name, label);

	job[c].should_be_class = BATCH;
	job[c].network = net;
	job[c].batch->pop = number;

	if (PDQ_DEBUG) {
		typetostr(s1, job[c].should_be_class);
		PRINTF("\tStream[%d]: %s \"%s\"; N: %3.1f\n",
		  c, s1, job[c].batch->name, job[c].batch->pop);
		resets(s1);
	}

	if (PDQ_DEBUG)
		debug(p, "Exiting");

}  // create_batch_stream
Esempio n. 6
0
void create_term_stream(int circuit, char *label, double pop, double think)
{
	extern JOB_TYPE *job;
	extern char     s1[];
	extern int      PDQ_DEBUG;
	char           *p = "create_term_stream()";

	if (PDQ_DEBUG)
		debug(p, "Entering");

	strcpy(job[c].term->name, label);
	job[c].should_be_class = TERM;
	job[c].network = circuit;
	job[c].term->think = think;
	job[c].term->pop = pop;

	if (PDQ_DEBUG) {
		typetostr(s1, job[c].should_be_class);
		PRINTF("\tStream[%d]: %s \"%s\"; N: %3.1f, Z: %3.2f\n",
		  c, s1,
		  job[c].term->name,
		  job[c].term->pop,
		  job[c].term->think
			);
		resets(s1);
	}

	if (PDQ_DEBUG)
		debug(p, "Exiting");

}  // create_term_stream
Esempio n. 7
0
void PDQ_SetTUnit(char* unitName)
{
	extern char     tUnit[];
	extern int      streams;
	char           *p = "PDQ_SetTUnit()";

	// Flag this, otherwise a user may not know why their units don't show up
	// in the PDQ report.
	if (streams == 0) {
		errmsg(p, "Must call CreateOpen or CreateClosed first\n");
	}
	if (strlen(unitName) > 10)
		errmsg(p, "Name > 10 characters");

	resets(tUnit);
	strcpy(tUnit, unitName);

}  // PDQ_SetTUnit
Esempio n. 8
0
void WidgetGL::keyPressEvent(QKeyEvent *e)
{
    switch( e->key() )
    {
    case Qt::Key_Space:
        {
            resets();
        }
        break;
    case Qt::Key_F:
        m_fullscreen = !m_fullscreen;
        fullScreen(m_fullscreen);
        updateGL();
        break;
    case Qt::Key_L://是否使用色彩混合,高亮
        {
            blend = !blend;
            if(blend)
            {
                glEnable(GL_BLEND);//色彩融合和深度缓存不能同时开启
                glDisable(GL_DEPTH_TEST);
            }
            else
            {
                glDisable(GL_BLEND);
                glEnable(GL_DEPTH_TEST);
            }
            updateGL();
        }
        break;
    case Qt::Key_Z:
        {
            bAnimate = !bAnimate;
            if( bAnimate )
                timer->start(40);
            else
                timer->stop();
        }
        break;
    case Qt::Key_Escape:
        close();
    }
}
Esempio n. 9
0
//-------------------------------------------------------------------------
// Subroutines
//-------------------------------------------------------------------------
void create_transaction(int net, char* label, double lambda)
{
	extern JOB_TYPE *job;
	extern char     s1[];
	extern int PDQ_DEBUG;

	strcpy(job[c].trans->name, label);

	job[c].should_be_class = TRANS;
	job[c].network = net;
	job[c].trans->arrival_rate = lambda;

	if (PDQ_DEBUG) {
		typetostr(s1, job[c].should_be_class);
		PRINTF("\tStream[%d]:  %s\t\"%s\";\tLambda: %3.1f\n",
		  c, s1, job[c].trans->name, job[c].trans->arrival_rate);
		resets(s1);
	}
    
}  // create_transaction
Esempio n. 10
0
void PDQ_Init(char *name)
{
	extern char             model[];
	extern char             s1[];
	extern char     		tUnit[];
	extern char     		wUnit[];
	extern int              demand_ext;
	extern int              method;
	extern double           tolerance;
	
	// These 3 globals are reset = 0 at the end of this proc
	extern int              nodes;
	extern int              streams;
	extern int              demands; // set = 1 by SetDemand()
	
	extern int              prev_init;
	extern NODE_TYPE        *node;
	extern JOB_TYPE         *job;
	extern TERMINAL_TYPE    *tm;
	extern BATCH_TYPE       *bt;
	extern TRANSACTION_TYPE *tx;
	extern SYSTAT_TYPE      *sys;
	extern int               PDQ_DEBUG;
	extern void              allocate_nodes();
	extern void              allocate_jobs();
	char                    *p = "PDQ_Init()";
	
	if (PDQ_DEBUG)
		debug(p, "Entering");

	if (strlen(name) > MAXCHARS) {
		resets(s1);
		sprintf(s1, "Model name > %d characters", MAXCHARS);
		errmsg(p, s1);
	}
    
    // There may be multiple Inits in the same model
	if (prev_init) {
		for (c = 0; c < MAXSTREAMS; c++) {
			if (job[c].term) {
				if (job[c].term->sys) {
					PDQ_FREE(job[c].term->sys);
					job[c].term->sys = NULL;
					job[c].batch->sys = NULL;
					job[c].trans->sys = NULL;
				}
				PDQ_FREE(job[c].term);
				job[c].term = NULL;
			}
			if (job[c].batch) {
				if (job[c].batch->sys) {
					PDQ_FREE(job[c].batch->sys);
					job[c].term->sys = NULL;
					job[c].batch->sys = NULL;
					job[c].trans->sys = NULL;
				}
				PDQ_FREE(job[c].batch);
				job[c].batch = NULL;
			}
			if (job[c].trans) {
				if (job[c].trans->sys) {
					PDQ_FREE(job[c].trans->sys);
					job[c].term->sys = NULL;
					job[c].batch->sys = NULL;
					job[c].trans->sys = NULL;
				}
				PDQ_FREE(job[c].trans);
				job[c].trans = NULL;
			}
		}   // over c loop

		if (job) {
			PDQ_FREE(job);
			job = NULL;
		}
		if (node) {
			PDQ_FREE(node);
			node = NULL;
		}

		resets(model);
		resets(wUnit);
		resets(tUnit);
	}

	// Copy user-supplied name string into PDQ global model[]
	strcpy(model, name);
    Comment[0] = '\0';  // NULL string

	demand_ext = VOID;
	method = VOID;
	tolerance = TOL;

	allocate_nodes(MAXNODES+1);
	allocate_jobs(MAXSTREAMS+1);

/********************************************************************************** 
	On 12/6/06 John Strunk (Carnegie Mellon Univ.) sent the following comment:
		"My code analyzes a large number of models within a single
		invocation, so I call PDQ::Init to re-init the state before each
		model is analyzed. Unfortunately, a large portion of execution time
		(of my whole program) is spent in PDQ_Init, and I've tracked it
		down to the nested loop at PDQ_Build.c:130.  Perhaps it would be
		possible to remove this set of loops entirely since calloc in
		allocate_*() right above that inits the memory to zero.  These
		changes can provide a 6x speedup in my application."

	for (cc = 0; cc < MAXSTREAMS; cc++) {
		for (kk = 0; kk < MAXNODES; kk++) {
			node[kk].devtype = VOID;
			node[kk].sched = VOID;
			node[kk].demand[cc] = 0.0;
			node[kk].resit[cc] = 0.0;
			node[kk].qsize[cc] = 0.0;
		}
		job[cc].should_be_class = VOID;
		job[cc].network = VOID;
	}

	NJG on Tue, Apr 3, 2007
	Since the speedup would be nearly an order of magnitude, it's worth a
	try. I was probably being overly defensive when I originally zeroed out
	every array element. After commenting out the above loops, a simple PDQ
	test (no re-Init calls), does not reveal any integrity problems.
	
	The VOID constant in PDQ_Lib.h also set to zero instead of -1.
**********************************************************************************/
	
	// reset circuit counters 
	nodes = streams = demands = 0; 

	c = k = 0;
	prev_init = TRUE;

	if (PDQ_DEBUG) {
		debug(p, "Exiting");
	}
	
}  /* PDQ_Init */
Esempio n. 11
0
//-------------------------------------------------------------------------
int PDQ_CreateClosed_p(char *name, int should_be_class, double *pop, double *think)
{
	extern char     s1[];
	extern int      streams;
	extern char     tUnit[];
	extern char     wUnit[];
	extern int      PDQ_DEBUG;
    
	char           *p = "PDQ_CreateClosed()";

	FILE           *out_fd;

	if (PDQ_DEBUG)
	{
		debug(p, "Entering");
		out_fd = fopen("PDQ.out", "a");
		fprintf(out_fd, "name : %s  should_be_class : %d  pop : %f  think : %f\n", name, should_be_class, *pop, *think);
		//PJP This really should be fclose
		//close(out_fd);
		fclose(out_fd);
	}

	if (strlen(name) >= MAXCHARS) {
		sprintf(s1, "Nodename \"%s\" is longer than %d characters",
			name, MAXCHARS);
		errmsg(p, s1);
	}

	if (c > MAXSTREAMS) {
		PRINTF("c = %d\n", c);
		sprintf(s1, "Allocating \"%s\" exceeds %d max streams",
			name, MAXSTREAMS);
		errmsg(p, s1);
	}

	switch (should_be_class) {
		case TERM:
			if (*pop == 0.0) {
				resets(s1);
				sprintf(s1, "Stream: \"%s\", has zero population", name);
				errmsg(p, s1);
			}
			create_term_stream(CLOSED, name, *pop, *think);
			// Set default units 
			strcpy(wUnit, "Users");
			strcpy(tUnit, "Sec");
			break;
		case BATCH:
			if (*pop == 0.0) {
				resets(s1);
				sprintf(s1, "Stream: \"%s\", has zero population", name);
				errmsg(p, s1);
			}
			create_batch_stream(CLOSED, name, *pop);
			// Set default units 
			strcpy(wUnit, "Jobs");
			strcpy(tUnit, "Sec");
			break;
		default:
			sprintf(s1, "Unknown stream: %d", should_be_class);
			errmsg(p, s1);
			break;
	}

	if (PDQ_DEBUG)
		debug(p, "Exiting");

	c =  ++streams;

	return(0); // silence gcc warnings

}  // PDQ_CreateClosed
Esempio n. 12
0
void PDQ_CreateMultiserverClosed(int servers, char *name, int device, int sched) {
	
	extern NODE_TYPE *node;
	extern char     s1[], s2[];
	extern int      nodes;
	extern int      PDQ_DEBUG;
	
	FILE*			out_fd;
    
	char           *p = "PDQ_CreateMultiserverClosed";
    
    // hack to force FESC node type
	//sched = FESC; 
	//device = servers;

	if (PDQ_DEBUG)
	{
		debug(p, "Entering");
		out_fd = fopen("PDQ.out", "a");
		fprintf(out_fd, "name : %s  device : %d  sched : %d\n", name, device, sched);
		//The following should really be fclose
		//		close(out_fd);
		fclose(out_fd);
	}
	
	if (streams > 1) {
		sprintf(s1, "Only single workload allowed with CreateMultiserverClosed()\n");
		errmsg(p, s1);
	} 

	if (k > 1) {
		sprintf(s1, "Allocating \"%s\" exceeds %d max nodes", name, MAXNODES);
		errmsg(p, s1);
	}

	if (strlen(name) >= MAXCHARS) {
		sprintf(s1, "Nodename \"%s\" is longer than %d characters",
			name, MAXCHARS);
		errmsg(p, s1);
	}

	strcpy(node[k].devname, name);

	if (servers <= 0) { 
		// number of servers must be positive integer
		sprintf(s1, "Must specify a positive number of servers");
		errmsg(p, s1);
	} 
	
	// Added by NJG on Dec 29, 2018
	node[k].devtype = device;
	node[k].sched   = sched;
	node[k].servers = servers;

	if (PDQ_DEBUG) {
		typetostr(s1, node[k].devtype);
		typetostr(s2, node[k].sched);
		PRINTF("\tNode[%d]: %s %s \"%s\"\n",
		  k, s1, s2, node[k].devname);
		resets(s1);
		resets(s2);
	};

	if (PDQ_DEBUG)
		debug(p, "Exiting");

    // update global node count
	k = ++nodes;
	
} // PDQ_CreateMultiserverClosed
Esempio n. 13
0
void approx(void)
{
	extern int        PDQ_DEBUG, iterations, streams, nodes;
	extern char       s1[], s2[], s3[], s4[];
	extern double     tolerance;
	extern JOB_TYPE  *job;
	extern NODE_TYPE *node;
	extern void       typetostr();
	extern void       getjob_name();

	int               k, c;
	int               should_be_class;
	double            sumQ();
	double            sumR[MAXSTREAMS];
	double            delta = 2 * TOL;
	int               iterate;
	char              jobname[MAXBUF];
	NODE_TYPE        *last;
	char             *p = "approx()";

	if (PDQ_DEBUG)
		debug(p, "Entering");

	if (nodes == 0 || streams == 0)
		errmsg(p, "Network nodes and streams not defined.");
#ifndef __R_PDQ
	if ((last = (NODE_TYPE *) calloc(sizeof(NODE_TYPE), nodes)) == NULL)
#else
	  if ((last = (NODE_TYPE *) Calloc((size_t) nodes,  NODE_TYPE )) == NULL)
#endif
		errmsg(p, "Node (last) allocation failed!\n");

	iterations = 0;

	if (PDQ_DEBUG) {
		sprintf(s1, "\nIteration: %d", iterations);
		debug(p, s1);
		resets(s1);
	}

	/* initialize all queues */

	for (c = 0; c < streams; c++) {
		should_be_class = job[c].should_be_class;

		for (k = 0; k < nodes; k++) {
			switch (should_be_class) {
				case TERM:
					last[k].qsize[c] = node[k].qsize[c] = job[c].term->pop / nodes;
					break;
				case BATCH:
					last[k].qsize[c] = node[k].qsize[c] = job[c].batch->pop / nodes;
					break;
				default:
					break;
			}

			if (PDQ_DEBUG) {
				getjob_name(jobname, c);
				sprintf(s2, "Que[%s][%s]: %3.4f (D=%f)",
					node[k].devname,
					jobname,
					node[k].qsize[c],
					delta);
				debug(p, s2);
				resets(s2);
				resets(jobname);
			}
		}  /* over k */
	}  /* over c */

	do {
		iterations++;

		if (PDQ_DEBUG) {
			sprintf(s1, "\nIteration: %d", iterations);
			debug(p, s1);
			resets(s1);
		}

		for (c = 0; c < streams; c++) {
			getjob_name(jobname, c);

			sumR[c] = 0.0;

			if (PDQ_DEBUG) {
				sprintf(s1, "\nStream: %s", jobname);
				debug(p, s1);
				resets(s1);
			}

			should_be_class = job[c].should_be_class;

			for (k = 0; k < nodes; k++) {
				if (PDQ_DEBUG) {
					sprintf(s2, "Que[%s][%s]: %3.4f (D=%1.5f)",
						node[k].devname,
						jobname,
						node[k].qsize[c],
						delta);
					debug(p, s2);
					resets(s1);
				}

				/* approximate avg queue length */

				switch (should_be_class) {
					double  N;
					case TERM:
						N = job[c].term->pop;
						node[k].avqsize[c] = sumQ(k, c) +
							(node[k].qsize[c] * (N - 1.0) / N);
						break;
					case BATCH:
						N = job[c].batch->pop;
						node[k].avqsize[c] =
							sumQ(k, c) + (node[k].qsize[c] * (N - 1.0) / N);
						break;
					default:
						typetostr(s1, should_be_class);
						sprintf(s2, "Unknown should_be_class: %s", s1);
						errmsg(p, s2);
						resets(s2);
						break;
					}

					if (PDQ_DEBUG) {
						sprintf(s2, "<Q>[%s][%s]: %3.4f (D=%1.5f)",
							node[k].devname,
							jobname,
							node[k].avqsize[c],
							delta
					);
					debug(p, s2);
					resets(s2);
			}

			/* residence times */

			switch (node[k].sched) {
				case FCFS:
				case PSHR:
				case LCFS:
					node[k].resit[c] =
				node[k].demand[c] * (node[k].avqsize[c] + 1.0);
					break;
				case ISRV:
					node[k].resit[c] = node[k].demand[c];
					break;
				default:
					typetostr(s1, node[k].sched);
					sprintf(s2, "Unknown queue type: %s", s1);
					errmsg(p, s2);
					break;
			}

			sumR[c] += node[k].resit[c];


			if (PDQ_DEBUG) {
				PRINTF("\tTot ResTime[%s] = %3.4f\n", jobname, sumR[c]);

				PRINTF("\tnode[%s].qsize[%s] = %3.4f\n",
					node[k].devname,
					jobname,
					node[k].qsize[c]
				);

				PRINTF("\tnode[%s].demand[%s] = %3.4f\n",
					node[k].devname,
					jobname,
					node[k].demand[c]
				);

				PRINTF("\tnode[%s].resit[%s] = %3.4f\n",
					node[k].devname,
					jobname,
					node[k].resit[c]
				);
			}
		}			/* over k */


		/* system throughput, residency & response-time */

		switch (should_be_class) {
			case TERM:
				job[c].term->sys->thruput =
					(job[c].term->pop / (sumR[c] + job[c].term->think));
				job[c].term->sys->response =
					(job[c].term->pop / job[c].term->sys->thruput) - job[c].term->think;
				job[c].term->sys->residency =
					job[c].term->pop - (job[c].term->sys->thruput * job[c].term->think);

				if (PDQ_DEBUG) {
					sprintf(s2, "\tTERM<X>[%s]: %5.4f",
						jobname, job[c].term->sys->thruput);
					debug(p, s2);
					resets(s2);
					sprintf(s2, "\tTERM<R>[%s]: %5.4f",
						jobname, job[c].term->sys->response);
					debug(p, s2);
					resets(s2);
				}
				break;

			case BATCH:
				job[c].batch->sys->thruput = job[c].batch->pop / sumR[c];
				job[c].batch->sys->response =
					(job[c].batch->pop / job[c].batch->sys->thruput);
				job[c].batch->sys->residency = job[c].batch->pop;

				if (PDQ_DEBUG) {
					sprintf(s2, "\t<X>[%s]: %3.4f",
						jobname, job[c].batch->sys->thruput);
					debug(p, s2);
					resets(s2);
					sprintf(s2, "\t<R>[%s]: %3.4f",
						jobname, job[c].batch->sys->response);
					debug(p, s2);
					resets(s2);
				}

				break;
					default:
						sprintf(s1, "Unknown should_be_class: %s", should_be_class);
						errmsg(p, s1);
						break;
			}

			resets(jobname);
		}  /* over c */

		/* update queue sizes */

		for (c = 0; c < streams; c++) {
			getjob_name(jobname, c);
			should_be_class = job[c].should_be_class;
			iterate = FALSE;

			if (PDQ_DEBUG) {
				sprintf(s1, "Updating queues of \"%s\"", jobname);
				PRINTF("\n");
				debug(p, s1);
				resets(s1);
			}

			for (k = 0; k < nodes; k++) {
				switch (should_be_class) {
					case TERM:
						node[k].qsize[c] = job[c].term->sys->thruput * node[k].resit[c];
						break;
					case BATCH:
						node[k].qsize[c] = job[c].batch->sys->thruput * node[k].resit[c];
						break;
					default:
						sprintf(s1, "Unknown should_be_class: %s", should_be_class);
						errmsg(p, s1);
						break;
				}

				/* check convergence */

				delta = fabs((double) (last[k].qsize[c] - node[k].qsize[c]));

				if (delta > tolerance)	/* for any node */
					iterate = TRUE;	/* but complete all queue updates */

				last[k].qsize[c] = node[k].qsize[c];

				if (PDQ_DEBUG) {
					sprintf(s2, "Que[%s][%s]: %3.4f (D=%1.5f)",
						node[k].devname,
						jobname,
						node[k].qsize[c],
						delta);
					debug(p, s2);
					resets(s2);
				}
			}			/* over k */

			resets(jobname);
		}				/* over c */

		if (PDQ_DEBUG)
			debug(p, "Update complete");
	} while (iterate);

	/* cleanup */

	if (last) {
	  PDQ_FREE(last); 
	  last = NULL; 
	}

	if (PDQ_DEBUG)
		debug(p, "Exiting");
}  /* approx */
Esempio n. 14
0
int main(void)
{
   extern int      nodes, streams;
   extern JOB_TYPE *job;
   extern NODE_TYPE *node;
   extern char     s1[];
   char            transCD[MAXCHARS], transRQ[MAXCHARS], transSU[MAXCHARS];
   char            dummyCD[MAXCHARS], dummyRQ[MAXCHARS], dummySU[MAXCHARS];
   char            nodePC[MAXCHARS], nodeFS[MAXCHARS], nodeGW[MAXCHARS];
   char            nodeMF[MAXCHARS], nodeTR[MAXCHARS];
   double          demand[MAXPROC][MAXDEV], util[MAXDEV], udsk[MAXDEV],
                   udasd[MAXDEV], RTexpect[MAXPROC];
   double          fsd, RTmean, ulan, ufs, uws, ugw, umf;
   int             work, dev, i, j;

   /*
   Disk-array data structures probably should go into PDQ_Build.c one
   day.
   */

   devarray_type  *FDarray;
   devarray_type  *MDarray;

   if ((FDarray = (devarray_type *) calloc(sizeof(devarray_type), 10)) == NULL)
      errmsg("", "FDarray allocation failed!\n");

   if ((MDarray = (devarray_type *) calloc(sizeof(devarray_type), 10)) == NULL)
      errmsg("", "MDarray allocation failed!\n");

   for (i = 0; i < FS_DISKS; i++) {
      FDarray[i].id = FD + i;
      resets(s1);
      sprintf(s1, "FSDK%d", i);
      strcpy(FDarray[i].label, s1);
   }

   for (i = 0; i < MF_DISKS; i++) {
      MDarray[i].id = MD + i;
      resets(s1);
      sprintf(s1, "MFDK%d", i);
      strcpy(MDarray[i].label, s1);
   }

   /*
   CPU service times are calculated from instruction counts tabulated
   in original 1993 CMG paper.
   */

   demand[CD_Req][PC] = 200 * k / PC_MIPS;
   demand[CD_Rpy][PC] = 100 * k / PC_MIPS;
   demand[RQ_Req][PC] = 150 * k / PC_MIPS;
   demand[RQ_Rpy][PC] = 200 * k / PC_MIPS;
   demand[SU_Req][PC] = 300 * k / PC_MIPS;
   demand[SU_Rpy][PC] = 300 * k / PC_MIPS;
   demand[Req_CD][FS] = 50 * k / FS_MIPS;
   demand[Req_RQ][FS] = 70 * k / FS_MIPS;
   demand[Req_SU][FS] = 10 * k / FS_MIPS;
   demand[CD_Msg][FS] = 35 * k / FS_MIPS;
   demand[RQ_Msg][FS] = 35 * k / FS_MIPS;
   demand[SU_Msg][FS] = 35 * k / FS_MIPS;
   demand[GT_Snd][GW] = 50 * k / GW_MIPS;
   demand[GT_Rcv][GW] = 50 * k / GW_MIPS;
   demand[MF_CD][MF] = 50 * k / MF_MIPS;
   demand[MF_RQ][MF] = 150 * k / MF_MIPS;
   demand[MF_SU][MF] = 20 * k / MF_MIPS;

   /*
    Service time on the LAN to send and recv packets from any of the PC
    desktop, the file server or the SNA gateway.
    8 bits per Byte.
    */
   
   demand[LAN_TX][PC] = (double) TR_Bytes * 8 / TR_Mbps;
   demand[LAN_TX][FS] = (double) TR_Bytes * 8 / TR_Mbps;
   demand[LAN_TX][GW] = (double) TR_Bytes * 8 / TR_Mbps;

   /*
    * File server disk IOs = number of accesses x caching / (max IOs / Sec)
    */

   for (i = 0; i < FS_DISKS; i++) {
      demand[Req_CD][FDarray[i].id] = (1.0 * 0.5 / 128.9) / FS_DISKS;
      demand[Req_RQ][FDarray[i].id] = (1.5 * 0.5 / 128.9) / FS_DISKS;
      demand[Req_SU][FDarray[i].id] = (0.2 * 0.5 / 128.9) / FS_DISKS;
      demand[CD_Msg][FDarray[i].id] = (1.0 * 0.5 / 128.9) / FS_DISKS;
      demand[RQ_Msg][FDarray[i].id] = (1.5 * 0.5 / 128.9) / FS_DISKS;
      demand[SU_Msg][FDarray[i].id] = (0.5 * 0.5 / 128.9) / FS_DISKS;
   }


   /* Mainframe DASD IOs = (#accesses / (max IOs/Sec)) / #disks */
   for (i = 0; i < MF_DISKS; i++) {
      demand[MF_CD][MDarray[i].id] = (2.0 / 60.24) / MF_DISKS;
      demand[MF_RQ][MDarray[i].id] = (4.0 / 60.24) / MF_DISKS;
      demand[MF_SU][MDarray[i].id] = (1.0 / 60.24) / MF_DISKS;
   }

   /* Now, start building the PDQ model... */

   PDQ_Init(scenario);

   /* Define physical resources as PDQ queueing nodes. */
   strcpy(nodePC, "PCDESK");
   strcpy(nodeFS, "FSERVR");
   strcpy(nodeGW, "GATWAY");
   strcpy(nodeMF, "MFRAME");
   strcpy(nodeTR, "TRLAN");

   PDQ_CreateNode(nodePC, CEN, FCFS);
   PDQ_CreateNode(nodeFS, CEN, FCFS);
   PDQ_CreateNode(nodeGW, CEN, FCFS);
   PDQ_CreateNode(nodeMF, CEN, FCFS);

   for (i = 0; i < FS_DISKS; i++) {
      PDQ_CreateNode(FDarray[i].label, CEN, FCFS);
   }

   for (i = 0; i < MF_DISKS; i++) {
      PDQ_CreateNode(MDarray[i].label, CEN, FCFS);
   }

   /*
    * NOTE: Although the token ring LAN is a passive computational device, it
    * is treated as a separate node so as to agree with the results presented
    * in the original CMG 1993 paper.
    */

   PDQ_CreateNode(nodeTR, CEN, FCFS);

   /*
    * Because the desktop PCs are all of the same type and emitting the same
    * homogeneous transaction workload, the focus can be placed on the
    * response time performance of a single PC workstation and generalized to
    * the others. Rather than having N * 3 workload streams or classes, we
    * simply model 2 PC desktops: the "real" one of interest and a dummy PC
    * representing the remaining (N-1) * 3 streams.
    */

   strcpy(transCD, "CatDisplay");
   strcpy(transRQ, "RemotQuote");
   strcpy(transSU, "StatUpdate");

   /* Aggregate transactions */
   strcpy(dummyCD, "CatDispAgg");
   strcpy(dummyRQ, "RemQuotAgg");
   strcpy(dummySU, "StatUpdAgg");

   PDQ_CreateOpen(transCD, 1 * 4.0 * TPS);
   PDQ_CreateOpen(transRQ, 1 * 8.0 * TPS);
   PDQ_CreateOpen(transSU, 1 * 1.0 * TPS);
   PDQ_CreateOpen(dummyCD, (USERS - 1) * 4.0 * TPS);
   PDQ_CreateOpen(dummyRQ, (USERS - 1) * 8.0 * TPS);
   PDQ_CreateOpen(dummySU, (USERS - 1) * 1.0 * TPS);

   /*
   Define the service demands on each physical resource.
   CD request + reply chain from workflow diagram
   Note that only the "real" PC demand is defined, and the aggregated (N-1) PCs.
   */

   /******************* RQ request + reply chain ... *******************/
   PDQ_SetDemand(nodePC, transCD, demand[CD_Req][PC] + (5 * demand[CD_Rpy][PC]));
   PDQ_SetDemand(nodeFS, transCD, demand[Req_CD][FS] + (5 * demand[CD_Msg][FS]));
   PDQ_SetDemand(nodeFS, dummyCD, demand[Req_CD][FS] + (5 * demand[CD_Msg][FS]));
   PDQ_SetDemand(nodeGW, transCD, demand[GT_Snd][GW] + (5 * demand[GT_Rcv][GW]));
   PDQ_SetDemand(nodeGW, dummyCD, demand[GT_Snd][GW] + (5 * demand[GT_Rcv][GW]));
   PDQ_SetDemand(nodeMF, transCD, demand[MF_CD][MF]);
   PDQ_SetDemand(nodeMF, dummyCD, demand[MF_CD][MF]);
   
   for (i = 0; i < FS_DISKS; i++) {
      fsd = demand[Req_CD][FDarray[i].id] + (5 * demand[CD_Msg][FDarray[i].id]);
      PDQ_SetDemand(FDarray[i].label, transCD, fsd);
      PDQ_SetDemand(FDarray[i].label, dummyCD, fsd);
   }

   for (i = 0; i < MF_DISKS; i++) {
      PDQ_SetDemand(MDarray[i].label, transCD, demand[MF_CD][MDarray[i].id]);
      PDQ_SetDemand(MDarray[i].label, dummyCD, demand[MF_CD][MDarray[i].id]);
   }


   /*
   NOTE:Synchronous process execution causes data for the CD transaction to
   cross the LAN 12 times as depicted in the following parameterization of
   PDQ_SetDemand.
   */

   PDQ_SetDemand(nodeTR, transCD,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (5 * demand[LAN_TX][GW]) +
		 (5 * demand[LAN_TX][FS]) +
		 (5 * demand[LAN_TX][PC]));

   PDQ_SetDemand(nodeTR, dummyCD,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (5 * demand[LAN_TX][GW]) +
		 (5 * demand[LAN_TX][FS]) +
		 (5 * demand[LAN_TX][PC]));



   /******************* RQ request + reply chain ... *******************/
   PDQ_SetDemand(nodePC, transRQ, demand[RQ_Req][PC] + (3 * demand[RQ_Rpy][PC]));
   PDQ_SetDemand(nodeFS, transRQ, demand[Req_RQ][FS] + (3 * demand[RQ_Msg][FS]));
   PDQ_SetDemand(nodeFS, dummyRQ, demand[Req_RQ][FS] + (3 * demand[RQ_Msg][FS]));

   for (i = 0; i < FS_DISKS; i++) {
      PDQ_SetDemand(FDarray[i].label, transRQ,
		    demand[Req_RQ][FDarray[i].id] +
		    (3 * demand[RQ_Msg][FDarray[i].id]));
      PDQ_SetDemand(FDarray[i].label, dummyRQ,
		    demand[Req_RQ][FDarray[i].id] +
		    (3 * demand[RQ_Msg][FDarray[i].id]));
   }

   PDQ_SetDemand(nodeGW, transRQ, demand[GT_Snd][GW] + (3 * demand[GT_Rcv][GW]));
   PDQ_SetDemand(nodeGW, dummyRQ, demand[GT_Snd][GW] + (3 * demand[GT_Rcv][GW]));
   PDQ_SetDemand(nodeMF, transRQ, demand[MF_RQ][MF]);
   PDQ_SetDemand(nodeMF, dummyRQ, demand[MF_RQ][MF]);

   for (i = 0; i < MF_DISKS; i++) {
      PDQ_SetDemand(MDarray[i].label, transRQ,
		    demand[MF_RQ][MDarray[i].id]);
      PDQ_SetDemand(MDarray[i].label, dummyRQ,
		    demand[MF_RQ][MDarray[i].id]);
   }

   PDQ_SetDemand(nodeTR, transRQ,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (3 * demand[LAN_TX][GW]) +
		 (3 * demand[LAN_TX][FS]) +
		 (3 * demand[LAN_TX][PC]));
   PDQ_SetDemand(nodeTR, dummyRQ,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (3 * demand[LAN_TX][GW]) +
		 (3 * demand[LAN_TX][FS]) +
		 (3 * demand[LAN_TX][PC]));




   /******************* SU request + reply chain *******************/
   PDQ_SetDemand(nodePC, transSU, demand[SU_Req][PC] + demand[SU_Rpy][PC]);
   PDQ_SetDemand(nodeFS, transSU, demand[Req_SU][FS] + demand[SU_Msg][FS]);
   PDQ_SetDemand(nodeFS, dummySU, demand[Req_SU][FS] + demand[SU_Msg][FS]);

   for (i = 0; i < FS_DISKS; i++) {
      PDQ_SetDemand(FDarray[i].label, transSU,
		    demand[Req_SU][FDarray[i].id] +
		    demand[SU_Msg][FDarray[i].id]);
      PDQ_SetDemand(FDarray[i].label, dummySU,
		    demand[Req_SU][FDarray[i].id] +
		    demand[SU_Msg][FDarray[i].id]);
   }

   PDQ_SetDemand(nodeGW, transSU, demand[GT_Snd][GW] + demand[GT_Rcv][GW]);
   PDQ_SetDemand(nodeGW, dummySU, demand[GT_Snd][GW] + demand[GT_Rcv][GW]);
   PDQ_SetDemand(nodeMF, transSU, demand[MF_SU][MF]);
   PDQ_SetDemand(nodeMF, dummySU, demand[MF_SU][MF]);

   for (i = 0; i < MF_DISKS; i++) {
      PDQ_SetDemand(MDarray[i].label, transSU,
		    demand[MF_SU][MDarray[i].id]);
      PDQ_SetDemand(MDarray[i].label, dummySU,
		    demand[MF_SU][MDarray[i].id]);
   }

   PDQ_SetDemand(nodeTR, transSU,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (1 * demand[LAN_TX][GW]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][PC]));
   PDQ_SetDemand(nodeTR, dummySU,
		 (1 * demand[LAN_TX][PC]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][GW]) +
		 (1 * demand[LAN_TX][GW]) +
		 (1 * demand[LAN_TX][FS]) +
		 (1 * demand[LAN_TX][PC]));

   PDQ_SetDebug(FALSE);
   PDQ_SetWUnit("Trans");
   PDQ_Solve(CANON);
   if (PRINT_REPORT) {
      PDQ_Report();
   }
   
   /*
    Break out each tx response time together with resource utilizations.
    The order of print out is the same as the 1993 CMG paper.
    */

   /* Mean response times reported in the CMG93 paper */
   RTexpect[0] = 0.2754;
   RTexpect[1] = 0.2625;
   RTexpect[2] = 0.1252;
   RTexpect[3] = 0.2624;
   RTexpect[4] = 0.2470;
   RTexpect[5] = 0.1120;

   printf("*** Metric breakout for \"%s\" with %d clients ***\n\n",
	  scenario, USERS);
   printf("Transaction\t    R (Sec)\t  CMG paper\n");
   printf("-----------\t    -------\t  ---------\n");

   for (work = 0; work < streams; work++) {
      resets(s1);
      strcpy(s1, job[work].trans->name);
      RTmean = PDQ_GetResponse(TRANS, s1);
      printf("%-15s\t%10.4f\t%10.4f\n", s1, RTmean, RTexpect[work]);
   }

   printf("\n\n");

   /*
    * Get node utilizations. This is a bit of a hack and should be written as
    * a subroutine.
    */
   for (dev = 0; dev < nodes; dev++) {
      util[dev] = 0.0;		/* reset array */
      for (work = 0; work < streams; work++) {
          util[dev] += 100 * PDQ_GetUtilization(node[dev].devname, job[work].trans->name, TRANS);
      }
   }

   for (dev = 0; dev < nodes; dev++) {
       for (i = 0; i < MF_DISKS; i++) {
           if (strcmp(node[dev].devname, MDarray[i].label) == 0) {
               udasd[i] = util[dev];
           }
       }
       for (i = 0; i < FS_DISKS; i++) {
           if (strcmp(node[dev].devname, FDarray[i].label) == 0) {
               udsk[i] = util[dev];
           }
       }       
       if (strcmp(node[dev].devname, nodePC) == 0) {
           uws = util[dev];
       }
       if (strcmp(node[dev].devname, nodeGW) == 0) {
           ugw = util[dev];
       }
       if (strcmp(node[dev].devname, nodeFS) == 0) {
           ufs = util[dev];
       }
       if (strcmp(node[dev].devname, nodeMF) == 0) {
           umf = util[dev];
       }
       if (strcmp(node[dev].devname, nodeTR) == 0) {
           ulan = util[dev];
       }
   }
   
   printf("PDQ Node       \t    %% Busy\t  CMG paper\n");
   printf("--------       \t    -------\t  ---------\n");
   printf("%-15s\t%10.4f\t%10.4f\n", "Token ring", ulan, 49.3333);
   printf("%-15s\t%10.4f\t%10.4f\n", "PC Desktop", uws,  0.5802);
   printf("%-15s\t%10.4f\t%10.4f\n", "File server", ufs, 11.9157);
   printf("%-15s\t%10.4f\t%10.4f\n", "Gateway CPU", ugw, 60.4167);
   printf("%-15s\t%10.4f\t%10.4f\n", "Mainframe", umf,   14.0873);


   for (i = 0; i < FS_DISKS; i++) {
      printf("%s%d\t%10.4f\t%10.4f\n", "FS disks",
	     FDarray[i].id, udsk[i], 59.0028);
   }

   for (i = 0; i < MF_DISKS; i++) {
      printf("%s%d\t%10.4f\t%10.4f\n", "DASD disk",
	     MDarray[i].id, udasd[i], 35.5502);
   }

}				/* main */