/*You are required to simulate a multilevel queue CPU scheduling that
has the following four-priority queues.
Processes are assigned to one of the queues according to their
individual priority number. 

      System processes queue. Processes with highest priority (0). When
a process with this priority comes in, it
      preempts immediately any process of lower priority and gets the
CPU. It executes until it finishes. 
      Express processes queue. Processes with priority (1). A process is
assigned the CPU as soon as the current
      process leaves the CPU, provided that "system processes" queue is
empty. A process from this queue will
      have the CPU until it finishes execution or when a process with
higher priority comes in. 
      Interactive processes queue. Processes with priority (2).
Processes in this queue are executed in a Round
      Robin scheduling with Q=2 time units. 
      Batch processes queue. Processes with lowest priority (3). Batch
processes are executed First Come First
      Served scheduling. 

Scheduling between queues is done as follows: 

      When there are no processes with priority number less than 3
(priority higher than that of batch
      processes), the system devotes the CPU completely to batch
processes. 
      When there are interactive and batch processes, the CPU time is
divided between interactive and batch
      processes queues, giving 20 time units to the former and 5 time
units to the latter. 
      Otherwise, a process is preempted from the CPU when another
process with higher priority comes in. The
      remaining time slot is given to the preempted process when
processes with higher priorities have finished. 

Each process includes the following parameters: 

      Process number 
      Time of arrival 
      CPU burst time 
      Priority number 

            0: system

            1: express

            2: interactive

            3: batch

Your simulator should generate the Gantt chart and calculate the average
waiting and turnaround times for any
possible set of processes. For this assignment, your simulator will read
a stream of processes with their
parameters from a manually generated file.
*/
/* Anan Tongprasith */
/********************/
#include
#include
/*** New structure type ***/
struct ml {	int procnum;		/* process number */
		int arrvtime;		/* arrival time */
		int cpub;		/* cpu burst time */
		int priority;		/* priority of the process */
	  };
struct q1 {	int procnum[5];		/* arriving process */
		int runproc;		/* running process */
		int finishproc;		/* exiting process */
	  };
struct q2 {	int procnum;		/* process number */
		int cpubleft;		/* more cpu burst needed */
	  };
struct q3 {	int procnum;		/* process number */
		int cpubleft;		/* more cpu burst needed */
		int tquantumleft; /*time quantum left from the original 2*/
	  };

/*** Global variables ***/
struct ml mainlist[100]; /*"mainlist[order]" contains each process' data read
			   from input file in consecutive order*/ 
struct q1 eventlist[500]; /*"eventlist[time]" contains events happen along the
			   timeline, eg. processes'arrival, running
			   process, exiting process*/
struct q2 systemq[25]; /*"systemq[queue-order]" contains ready-to-run system 
			processes*/
struct q2 expressq[25]; /*"expressq" contains ready-to-run express processes*/
struct q3 interacq[25]; /*"interacq" contains ready-to run interactive
			 processes*/
struct q2 batchq[25]; /*"batchq" contains ready-to-run batch processes*/
int mytime=0,timer=0,dedicated=0;
/*** Main function ***/
int main(int *argc, char *argv[])
{	int i,j,k,runq,mytotal,turnaroundtime[100],waitingtime[100];
	FILE *fp;
	char newline[30];char buf1[5],buf2[20],buf3[25];
/* Initialize the mainlist */
  for(i=0;i<100;i++)
  	mainlist[i].procnum=-1;
/* Read the lines from input file and put into the main list*/
  i=0;
  fp=fopen(argv[1],"r");
  while(fgets(newline,100,fp) != NULL)
  {	sscanf(newline,"%s %25c",buf1,buf3);
	mainlist[i].procnum=atoi(buf1);
  	sscanf(buf3,"%s %20c",buf1,buf2);
	mainlist[i].arrvtime=atoi(buf1);
  	sscanf(buf2,"%s %20c",buf1,buf3);
	mainlist[i].cpub=atoi(buf1);
	mainlist[i].priority=atoi(buf3);
	i++;
  }
  mytotal=i;
  fclose(fp);
/* Initialize eventlist, timeline ends at 499 time units */
  for(i=0;i<500;i++)
  {	eventlist[i].finishproc=-1;	/*exiting process*/
	eventlist[i].runproc=-1;	/*running process*/
	for(j=0;j<5;j++)
		eventlist[i].procnum[j]=-1;	/*arriving processes*/
  }
/* Write eventlist out from mainlist */
  i=0;
  while(mainlist[i].procnum>0) 
  {
	j=0;
	while(eventlist[mainlist[i].arrvtime].procnum[j]>0)
		j++;
	eventlist[mainlist[i].arrvtime].procnum[j]=mainlist[i].procnum;
	i++;
  }
/* Initialize queues */
for(i=0;i<25;i++)
{	systemq[0].procnum=0;	/*The queues start from 1 to 24 */
	expressq[0].procnum=0;  /*Queue's element 0 is the total number*/
	interacq[0].procnum=0;  /*of entries in that queue*/
	batchq[0].procnum=0;
}
/* Now let's begin the simulation */
  fp=fopen("sim.out","w");
  fprintf(fp,"---------------\n");
  for(mytime=0;mytime<500;mytime++)
  {	
/* Read arriving processes from eventlist and put them into queues */
	stuffqueue(mytime);
/* Decide process from which queue should be run at this time unit */
	runq=4;
	runq=decidequeue(runq);
/* Decided, now run the first process from that queue */
	myrun(runq);
/* Now write the output */ 
	if(mytime>0)
	{ if(eventlist[mytime-1].runproc!=eventlist[mytime].runproc)
	   fprintf(fp,"---------------\n");
	  else
	  { if(eventlist[mytime-1].finishproc>0)
		fprintf(fp,"---------------\n");
	    else
		if(runq==2&&interacq[1].tquantumleft==1)
		   fprintf(fp,"---------------\n");
	  }
	}
	if(eventlist[mytime].runproc>0)
	  fprintf(fp,"%2d:   %2d\n",mytime,eventlist[mytime].runproc);
	else
	  fprintf(fp,"%2d:    X\n",mytime);
  }
printf("Total process=%d\n",mytotal);
  i=0;
  while(i0)
	{	k=lookup(eventlist[mytime].procnum[j]);
/* Put into the correct queue */
		switch(mainlist[k].priority)
		{  case 0:	x=systemq[0].procnum;
				systemq[x+1].procnum=mainlist[k].procnum;
				systemq[x+1].cpubleft=mainlist[k].cpub;
				systemq[0].procnum=x+1;
				break;
		   case 1:	x=expressq[0].procnum;
				expressq[x+1].procnum=mainlist[k].procnum;
				expressq[x+1].cpubleft=mainlist[k].cpub;
				expressq[0].procnum=x+1;
				break;
		   case 2:	x=interacq[0].procnum;
				interacq[x+1].procnum=mainlist[k].procnum;
				interacq[x+1].cpubleft=mainlist[k].cpub;
				interacq[x+1].tquantumleft=2;
				interacq[0].procnum=x+1;
/* Reset timer if interactive process arrives with none exists before */
				if(x==0&&dedicated==3)	
				{	timer=0;
					dedicated=0;
				}
				break;
		   case 3:	x=batchq[0].procnum;
				batchq[x+1].procnum=mainlist[k].procnum;
				batchq[x+1].cpubleft=mainlist[k].cpub;
				batchq[0].procnum=x+1;
/* Reset timer if batch process arrives with none exists before */
				if(x==0&&dedicated==2)	
				{	timer=0;
					dedicated=0;
				}	
				break;

		}
		
		j++;
	}
}
/*** "decidequeue" decides process from which queue should be run
     at this time ***/
int decidequeue(int runq)
{  int k;
	if(systemq[0].procnum>0)
		runq=0;
	else
	{	if(batchq[0].procnum>0)
		{
			if(timer>19)
				runq=3;
			else
			{	if(interacq[0].procnum==0)
				{	timer=20;
					dedicated=3;
					runq=3;
				}
			}
		}
		if(interacq[0].procnum>0)
		{ 
			if(timer<20)
				runq=2;
			else
			{	if(batchq[0].procnum==0)
				{	timer=0;
					dedicated=2;
					runq=2;
				}
			}
		}
		if(expressq[0].procnum>0)
		{	if(mytime==0)	
				runq=1;
			else
			{	k=lookup(eventlist[mytime-1].runproc);
				if(runq==4)
					runq=1;
				if(runq==3)
				  if(mainlist[k].procnum!=batchq[1].procnum)
					runq=1;
				if(runq==2&&interacq[1].tquantumleft==2)
					runq=1;
			}
		}
	}
	return runq;
}
/*** "myrun" assume a process run, given the queue authorized to run*/
int myrun(int runq)
{ int tleft,mycount;
	switch(runq)
	{ case 0:	 
		timer=0;
		eventlist[mytime].runproc=systemq[1].procnum;
		systemq[1].cpubleft-=1;
/* The process is exiting */
		if(systemq[1].cpubleft==0)
		{	systemq[0].procnum-=1;
			eventlist[mytime].finishproc=systemq[1].procnum;
			mycount=1;
			while(mycount24)	timer=0;
		eventlist[mytime].runproc=batchq[1].procnum;
		batchq[1].cpubleft-=1;
/* The process is exiting */
		if(batchq[1].cpubleft==0)
		{	batchq[0].procnum-=1;
			eventlist[mytime].finishproc=batchq[1].procnum;
			mycount=1;
/* Shifting the queue */
			while(mycount<=batchq[0].procnum)
			{ batchq[mycount].procnum=batchq[mycount+1].procnum;
			  batchq[mycount].cpubleft=batchq[mycount+1].cpubleft;
			  mycount++;
			}
		}
		break;
	}
}

    Source: geocities.com/vienna/7079/src

               ( geocities.com/vienna/7079)                   ( geocities.com/vienna)