int Xinu_Default_Scheduling() {

	register struct pentry *optr; /* pointer to old process entry */
	register struct pentry *nptr; /* pointer to new process entry */

	/* no switch needed if current process priority higher than next*/

	if (((optr = &proctab[currpid])->pstate == PRCURR) && (lastkey(rdytail) < optr->pprio)) {
		return (OK);
	}

	/* force context switch */

	if (optr->pstate == PRCURR) {
		optr->pstate = PRREADY;
		insert(currpid, rdyhead, optr->pprio);
	}

	/* remove highest priority process at end of ready list */

	nptr = &proctab[(currpid = getlast(rdytail))];
	nptr->pstate = PRCURR; /* mark it currently running	*/
#ifdef	RTCLOCK
	preempt = QUANTUM; /* reset preemption counter	*/
#endif

	ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);

	/* The OLD process returns here when resumed. */
	return OK;

}
Example #2
0
xexecl(void (*pf)(), int parm)
{
struct pentry *pptr;
char *saddr;
int *sp1;
int ps;
int dummy;

disable(ps);
pptr = &proctab[currpid];
pptr->phasmsg = 0;
sp1 = (int *)(pptr->pbase + pptr->plen);
pptr->pargs = 1;
*(--sp1) = parm;
*(--sp1) = (int) INITRET;
*(--sp1)= (int) pf;
--sp1;
*(--sp1) = INITF;
sp1 -= 2;
pptr->pregs = sp1;
pptr->paddr = pf;

ctxsw(&dummy, &pptr->pregs);

} /* xexecl */
Example #3
0
/*------------------------------------------------------------------------
 *  resched  --  reschedule processor to highest priority ready process
 *
 * Notes:	Upon entry, currpid gives current process id.
 *		Proctab[currpid].pstate gives correct NEXT state for
 *			current process if other than PRCURR.
 *------------------------------------------------------------------------
 */
int	resched()
{
	register struct	pentry	*optr;	/* pointer to old process entry */
	register struct	pentry	*nptr;	/* pointer to new process entry */
	register int pflag;
	char *oldStackPtr = NULL;
    proctab[currpid].time = proctab[currpid].time + tod
                            - proctab[currpid].oldtime;

    optr = &proctab[currpid];
    pflag = sys_pcxget();
    if ( optr->pstate == PRCURR ) {
		/* no switch needed if current prio. higher than next	*/
		/* or if rescheduling is disabled ( pflag == 0 )	*/
		if ( pflag == 0 || lastkey(rdytail) < optr->pprio )
			return;
		/* force context switch */
		optr->pstate = PRREADY;
		insert(currpid,rdyhead,optr->pprio);
	} else if ( pflag == 0 ) {
		kprintf("pid=%d state=%d name=%s",
			currpid,optr->pstate,optr->pname);
		panic("Reschedule impossible in this state");
	}

	/* remove highest priority process at end of ready list */

	nptr = &proctab[(currpid=getlast(rdytail))];
	nptr->pstate = PRCURR;		/* mark it currently running	*/
	preempt = QUANTUM;          /* reset preemption counter */
	_pglob = nptr->pglob;		/* retrieve global environment	*/

        proctab[currpid].oldtime=tod;
	if (!optr->pregs || !nptr->pregs)
	{
	    kprintf("Rescheduling failed: pregs = 0\n");
	    return;
	}
/*	if (!debug_log)
	    debug_log = xinu_open("resched.log", O_RDWR|O_CREAT|O_TRUNC);
	dprintf(1, "Old: %s, New: %s\n", optr->pname, nptr->pname);*/
	oldStackPtr = optr->pregs;
	ctxsw(&optr->pregs,&nptr->pregs);

	if (currpid != 0 && optr->pregs > optr->pbase + optr->plen)
		panic("stack overflow");
		
	if (optr->phastrap) {
		optr->phastrap = FALSE;	/* mark trap as serviced	*/
        if (optr->ptfn != NULL)
			(*optr->ptfn)(optr->ptarg);
	}

	/* The OLD process returns here when resumed. */
	return;
}
/* Aging Scheduler */
int aging_resched()
{
	register struct qent *oqptr; 	/* pointer to the currently running process in queue entry table 		*/
	register struct pentry *opptr;	/* pointer to the currently running process in process entry table 	*/

	register struct qent *nqptr; 	/* pointer to the newly selected process in queue entry table 		*/
	register struct pentry *npptr;	/* pointer to the newly selected process in process entry table 	*/
	
	int opid = currpid;

	/* no switch needed if current process priority higher than next*/
	
	oqptr = &q[opid];
	opptr = &proctab[opid];
	
	/* set the priority of current process to base priority */
	q[currpid].qkey = proctab[currpid].pprio;

	if ( ( opptr->pstate == PRCURR) && (lastkey(rdytail) < oqptr->qkey)  ) {		

        updprocprio();          /* update priorities of all the processes in ready queue */

#ifdef  RTCLOCK
	        	preempt = QUANTUM;              /* reset preemption counter     */
#endif
		return(OK);
	}	

	/* remove highest priority process at end of ready list */

	npptr = &proctab[ (currpid = getlast(rdytail)) ];
	npptr->pstate = PRCURR;		/* mark it currently running	*/

	updprocprio();		/* update priorities of all the processes in ready queue */

        /* put old process in ready queue if it is the current executing process */

        if (opptr->pstate == PRCURR) {
                opptr->pstate = PRREADY;
                insert(opid,rdyhead,opptr->pprio);

        }

#ifdef  RTCLOCK
        	preempt = QUANTUM;              /* reset preemption counter     */
#endif

	ctxsw((int)&opptr->pesp, (int)opptr->pirmask, (int)&npptr->pesp, (int)npptr->pirmask);
	
	/* The OLD process returns here when resumed. */
	return OK;
}
Example #5
0
/**
 * Reschedule processor to highest priority ready thread.
 * Upon entry, thrcurrent gives current thread id.
 * Threadtab[thrcurrent].pstate gives correct NEXT state
 * for current thread if other than THRREADY.
 * @return OK when the thread is context switched back
 */
int resched(void)
{
    uchar asid;                 /* address space identifier */
    struct thrent *throld;      /* old thread entry */
    struct thrent *thrnew;      /* new thread entry */

    if (resdefer > 0)
    {                           /* if deferred, increase count & return */
        resdefer++;
        return (OK);
    }

    throld = &thrtab[thrcurrent];

    throld->intmask = disable();

    if (THRCURR == throld->state)
    {
        if (nonempty(readylist) && (throld->prio > firstkey(readylist)))
        {
            restore(throld->intmask);
            return OK;
        }
        throld->state = THRREADY;
        insert(thrcurrent, readylist, throld->prio);
    }

    /* get highest priority thread from ready list */
    thrcurrent = dequeue(readylist);
    thrnew = &thrtab[thrcurrent];
    thrnew->state = THRCURR;

    /* change address space identifier to thread id */
    asid = thrcurrent & 0xff;
#if 0
  // XXX Fix this later?
  asm("mtc0 %0, $10": :"r"(asid));
#endif

    restore(thrnew->intmask);
    ctxsw(&throld->stkptr, &thrnew->stkptr);

    /* old thread returns here when resumed */
    restore(throld->intmask);
    return OK;
}
Example #6
0
/**
 * Reschedule processor to next ready process.
 * Upon entry, currpid gives current process id.  Proctab[currpid].pstate 
 * gives correct NEXT state for current process if other than PRREADY.
 * @return OK when the process is context switched back
 */
syscall resched(void)
{
	irqmask im;
	pcb *oldproc;   /* pointer to old process entry */
	pcb *newproc;   /* pointer to new process entry */
	short head, tail;

	im = disable();
	oldproc = &proctab[ currpid ];

	/* Aging implemented */
	if(AGING)
	{	
		head = queuehead(readylist);
		head = queuetab[head].next;
		tail = queuetail(readylist);
		while(head != tail)
		{
			queuetab[head].key++;
			head = queuetab[head].next;
		}
	}

	/* place current process at end of ready queue */
	if (PRCURR == oldproc->state) 
	{
		oldproc->state = PRREADY;
		prioritize(currpid, readylist, oldproc->priority);
	}

	/* remove first process in ready queue */
	currpid = dequeue(readylist);
	newproc = &proctab[ currpid ];
	newproc->state = PRCURR;	/* mark it currently running	*/

#if PREEMPT
	preempt = QUANTUM;          /* reset preemption counter     */
#endif
	ctxsw(&oldproc->stkptr, &newproc->stkptr);

	/* The OLD process returns here when resumed. */
	restore(im);
	return OK;
}
Example #7
0
/*------------------------------------------------------------------------
 *  resched_lab1  -  Reschedule processor to highest priority eligible process
 *------------------------------------------------------------------------
 */
void	resched_lab1(void)		/* Assumes interrupts are disabled	*/
{
	struct procent *ptold;	/* Ptr to table entry for old process	*/
	struct procent *ptnew;	/* Ptr to table entry for new process	*/

	/* If rescheduling is deferred, record attempt and return */

	if (Defer.ndefers > 0) {
		Defer.attempt = TRUE;
		return;
	}

	/* Point to process table entry for the current (old) process */

	ptold = &proctab[currpid];

	if (ptold->prstate == PR_CURR) {  /* Process remains eligible */
		if (ptold->prprio > firstkey(readylist)) {
			return;
		}

		/* Old process will no longer remain current */

		ptold->prstate = PR_READY;
		insert(currpid, readylist, ptold->prprio);
	}

	/* Force context switch to highest priority ready process */

	currpid = dequeue(readylist);
	ptnew = &proctab[currpid];
	ptnew->prstate = PR_CURR;
	preempt = QUANTUM;		/* Reset time slice for process	*/
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	// LAB 4Q3: Invoke the handleCallback
	handleCallback();

	/* Old process returns here when resumed */

	return;
}
/*
 * This function makes the current process block state.
 */
int dskresched() {
	register struct pentry *optr;
	register struct pentry *nptr;
	STATWORD ps;

	disable(ps);

	optr = &proctab[currpid];
	optr -> pstate = PRSUSP;
	nptr = &proctab[(currpid = getlast(rdytail))];
	nptr -> pstate = PRCURR;

#ifdef RTCLOCK
	preempt = QUANTUM;
#endif
	restore(ps);
	ctxsw((int)&optr -> pesp, (int)optr -> pirmask, (int)&nptr -> pesp, (int)nptr -> pirmask);

	return OK;
}
Example #9
0
void _resched_aging(struct pentry *optr, struct pentry *nptr)
{
	int oldpreempt = preempt;
	preempt = MAXINT;
	/* Loop through everything in the queue and increase each entries
	   priority by a factor of 1.2 */
	int next = q[rdyhead].qnext;
	while (q[next].qnext != EMPTY) {
		q[next].qkey = min(MAX_PRIORITY, ceil(q[next].qkey * 1.2));
		next = q[next].qnext;
	}

	/* Put the current process back into the queue with its base
           priority */
	if (optr->pstate == PRCURR) {
		optr->pstate = PRREADY;
		insert(currpid, rdyhead, optr->pprio);
	}
	/* Now get the item with the highest priority */
	int oldcurrpid = currpid;
	currpid = getlast(rdytail);

	/* If the process from the end of the list is the current process,
	   no context switch is necessary */
	if (currpid == oldcurrpid) {
		optr->pstate = PRCURR;
		preempt = oldpreempt;
		return;
	}

	/* Otherwise, switch contexts to the new current process */
	nptr = &proctab[currpid];
	nptr->pstate = PRCURR;
#ifdef 	RTCLOCK
	preempt = QUANTUM;		/* Reset preempt counter */
#endif

	ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);

	return;
}
Example #10
0
/**
 * Reschedule processor to next ready process.
 * Upon entry, currpid gives current process id.  Proctab[currpid].pstate
 * gives correct NEXT state for current process if other than PRREADY.
 * @return OK when the process is context switched back
 */
syscall resched(void)
{
    pcb *oldproc;   /* pointer to old process entry */
    pcb *newproc;   /* pointer to new process entry */

    oldproc = &proctab[ currpid ];

    /* place current process at end of ready queue */
    if (PRCURR == oldproc->state)
    {
        oldproc->state = PRREADY;
        enqueue(currpid, readylist);
    }

    /* remove first process in ready queue */
    currpid = dequeue(readylist);
    newproc = &proctab[ currpid ];
    newproc->state = PRCURR;	/* mark it currently running	*/

    ctxsw(&oldproc->stkptr, &newproc->stkptr);

    /* The OLD process returns here when resumed. */
    return OK;
}
int RealTimeProcess_Scheduling(int newEpoch, struct pentry *optr, struct pentry *nptr) {

	optr->quantumleft = preempt;
	if (optr->quantumleft <= 0)
		optr->quantumleft = 0;

	if (newEpoch == TRUE) {
		int i = 0;
		struct pentry *p;
		for (i = 0; i < NPROC; i++) {
			p = &proctab[i];
			if (p->pstate == PRFREE || p->real == FALSE)
				continue;
			else {
				p->quantum = 100;
				p->quantumleft = p->quantum;
			}
		}
	}

	if (optr->real == TRUE && optr->quantumleft > 0 && optr->pstate == PRCURR && ((newEpoch == FALSE) || isempty(realrdyhead))) {
		/*
		 * Current process has quantum left and wants to be in PCURR state
		 * Or
		 * It is a newEpoch, then as per Round-Robin, next process must be selected not optr again.
		 * But if this is the only process, then it has to be chosen.
		 * Also, if it is newEpoch it definitely means current process does not want to return.
		 */
		preempt = optr->quantumleft;
		return OK;
	} else if (optr->pstate != PRCURR || optr->quantumleft <= 0 || optr->real == FALSE || (!isempty(realrdyhead) && newEpoch == TRUE && optr->quantumleft > 0 && optr->pstate == PRCURR)) {
		/*
		 * Currpid does not want to be PRCURR state any more or its quantum exhausted for this epoch.
		 * Also, currpid want to execute but RoundRobin-wise next process is to be selected
		 */
		if (isempty(realrdyhead))
			return NEWEPOCH;
		else {
			/*
			 * Choosing next process with quantumleft > 0
			 */
			int newprocPID = 0;
			int k = 0;
			for (k = q[realrdytail].qprev; k != realrdyhead; k = q[k].qprev) {
				if (proctab[k].quantumleft > 0) {
					newprocPID = k;
					break;
				}
			}
			if (newprocPID != realrdyhead) {
				if (optr->real == TRUE && optr->pstate == PRCURR) { //Just like in Xinu Scheduling
					optr->pstate = PRREADY;
					insert(currpid, realrdyhead, 1);
				} else if (optr->real == FALSE && optr->pstate == PRCURR) {
					optr->pstate = PRREADY;
					insert(currpid, rdyhead, optr->pprio);
				}
				nptr = &proctab[newprocPID];
				nptr->pstate = PRCURR;
				dequeue(newprocPID);
				currpid = newprocPID;
				preempt = nptr->quantumleft;
				ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);
				return OK;
			} else
				return NEWEPOCH;
		}
	}
	return SYSERR;
}
int Linux_22_Scheduling() {
	/*
	 * preempt = no. of clock ticks remaining
	 */
	register struct pentry *optr; /* pointer to old process entry */
	register struct pentry *nptr; /* pointer to new process entry */
	int newEpoch = FALSE;
	choose: optr = &proctab[currpid];
	int optrOldPrio = optr->goodness - optr->quantumleft; //Even If optr's prio has been changed, difference gives old priority
	optr->goodness = optrOldPrio + preempt;
	optr->quantumleft = preempt;

	if (optr->quantumleft <= 0 || currpid == NULLPROC) {
		optr->quantumleft = 0; //No more CPU time left
		optr->goodness = 0; //Exhausted allocated CPU time
	}
	//Find, of all runnable processes which has highest goodness
	int maxGoodness = 0;
	int k = 0;
	int newprocPID = 0;
	for (k = q[rdytail].qprev; k != rdyhead; k = q[k].qprev) {
		if (proctab[k].goodness > maxGoodness) {
			newprocPID = k;
			maxGoodness = proctab[k].goodness;
		}
	}

	if (maxGoodness == 0 && (optr->pstate != PRCURR || optr->quantumleft == 0)) {
		/*
		 * NEW EPOCH
		 * MaxGoodness is zero, it means runnable processes are other old process
		 * have exhausted CPU and new epoch has to begin
		 * For Current old process, if counter = 0, exhausted CPU, forced to next epoch
		 * If it does not want to stay PRCURR despite CPU time, next epoch
		 */
		if (newEpoch == FALSE) {
			newEpoch = TRUE;
			int i;
			struct pentry *p;
			for (i = 0; i < NPROC; i++) {
				p = &proctab[i];
				if (p->pstate == PRFREE)
					continue;
				else if (p->quantumleft == 0 || p->quantumleft == p->quantum) { //Process either exhausted or not run at all;
					p->quantum = p->pprio;
				} else {
					p->quantum = (p->quantumleft) / 2 + p->pprio;
				}
				p->quantumleft = p->quantum;
				p->goodness = p->quantumleft + p->pprio;
			}

			preempt = optr->quantumleft;
			goto choose;
		}
		/*
		 * Now that quantum, counter and goodness are set, choose process with best goodness.
		 * Since optr is still current process, preempt is set to optr->counter
		 */
		if (maxGoodness == 0) {
			if (currpid == NULLPROC) {
				return OK;
			} else {
				newprocPID = NULLPROC;
				if (optr->pstate == PRCURR) { //Just like in Xinu Scheduling
					optr->pstate = PRREADY;
					insert(currpid, rdyhead, optr->pprio);
				}
				nptr = &proctab[newprocPID];
				nptr->pstate = PRCURR;
				dequeue(newprocPID);
				currpid = newprocPID;
#ifdef	RTCLOCK
				preempt = QUANTUM;
#endif
				ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);
				return OK;
			}
		}
	} else if (optr->goodness >= maxGoodness && optr->goodness > 0 && optr->pstate == PRCURR) {
		/*
		 * Current process has maximum goodness,
		 * Its goodness is greater than 0.
		 * If goodness is 0, then all runnable processes have same goodness and they have to
		 * chosen in Round-Robin manner. Goodness being 0 also means exhausted CPU time.
		 * So, no need to run it again in this epoch.
		 * Currpid wants to be CURR state.
		 * In the same epoch, execute till its counter exhausts i.e, reduces to 0.
		 */
		preempt = optr->quantumleft;
		return OK;
	}
	/*
	 * There can be multiple processes with non-zero maxGoodness, in that case
	 * while iterating readyList from head to tail, we will get the last one and execute it
	 * Then next from the last with same maxGoodness. Meanwhile if any process enter readyList
	 * it will not be executed till next epoch as its goodness stays 0.
	 */
	else if (maxGoodness > 0 && (optr->pstate != PRCURR || optr->quantumleft == 0 || optr->goodness < maxGoodness)) {
		/*
		 * Currpid does not want to be PRCURR state any more even though it has more goodness and CPU time
		 * Exhausted allocated CPU time, but wants to be PRCURR and has maxGoodness
		 * Its goodness is less than maxGoodness, and has CPU time and wants to be PRCURR
		 * Process must be rescheduled and next process must begin.
		 */
		if (optr->pstate == PRCURR) { //Just like in Xinu Scheduling
			optr->pstate = PRREADY;
			insert(currpid, rdyhead, optr->pprio);
		}
		nptr = &proctab[newprocPID];
		nptr->pstate = PRCURR;
		dequeue(newprocPID);
		currpid = newprocPID;
		preempt = nptr->quantumleft;
		ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);
		return OK;
	} else
		return SYSERR;
}
int NormalQueue_Scheduling(int newEpoch, struct pentry *optr, struct pentry *nptr) {

	if (newEpoch) {
		int i = 0;
		struct pentry *p;
		for (i = 0; i < NPROC; i++) {
			p = &proctab[i];
			if (p->pstate == PRFREE || p->real == TRUE)
				continue;
			else if (p->quantumleft == 0 || p->quantumleft == p->quantum) { //Process either exhausted or not run at all;
				p->quantum = p->pprio;
			} else {
				p->quantum = (p->quantumleft) / 2 + p->pprio;
			}
			p->quantumleft = p->quantum;
			p->goodness = p->quantumleft + p->pprio;
		}
		preempt = optr->quantumleft;
	}
	int optrOldPrio = optr->goodness - optr->quantumleft; //Even If optr's prio has been changed, difference gives old priority
	optr->goodness = optrOldPrio + preempt;
	optr->quantumleft = preempt;

	if (optr->quantumleft <= 0) {
		optr->quantumleft = 0; //No more CPU time left
		optr->goodness = 0; //Exhausted allocated CPU time
	}

	if (optr->real == TRUE)
		optr->goodness = 0;
	//Find, of all runnable processes which has highest goodness
	int maxGoodness = 0;
	int k = 0;
	int newprocPID = 0;
	for (k = q[rdyhead].qnext; k != rdytail; k = q[k].qnext) {
		if (proctab[k].goodness > maxGoodness) {
			newprocPID = k;
			maxGoodness = proctab[k].goodness;
		}
	}

	if (maxGoodness == 0 && (optr->pstate != PRCURR || optr->quantumleft == 0)) {
		/* NEW EPOCH
		 * MaxGoodness is zero, it means processes in readylist
		 * have exhausted CPU and new epoch has to begin
		 * For Current process, if counter = 0, exhausted CPU, forced to next epoch
		 * If it does not want to stay PRCURR despite CPU time, next epoch*/
		if (newEpoch == TRUE && isempty(realrdyhead)) {
			if (optr->real == TRUE && (optr->pstate == PRCURR || optr->pstate == PRREADY)) {
				return NEWEPOCH;
			} else if (currpid == NULLPROC) {
//				kprintf("\tNUM OF USER PROCESSES : %d \n", numproc);
				return OK;
			} else {
				newprocPID = NULLPROC;
				if (optr->real == FALSE && optr->pstate == PRCURR) {
					optr->pstate = PRREADY;
					insert(currpid, rdyhead, optr->pprio);
				} else if (optr->real == TRUE && optr->pstate == PRCURR) {
					optr->pstate = PRREADY;
					insert(currpid, realrdyhead, 1);
				}
				//kprintf("\t switched to Null process\t");
				nptr = &proctab[newprocPID];
				nptr->pstate = PRCURR;
				dequeue(newprocPID);
				currpid = newprocPID;
#ifdef	RTCLOCK
				preempt = QUANTUM; //reset preemption counter
#endif
				ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);
				return OK;
			}
		} else
			return NEWEPOCH;
	} else if (optr->real == FALSE && optr->goodness >= maxGoodness && optr->goodness > 0 && optr->pstate == PRCURR) {

		/*
		 * Current process has maximum goodness,
		 * Its goodness is greater than 0.
		 * Currpid wants to be CURR state.
		 * In the same epoch, execute till its quantumleft exhausts i.e, reduces to 0.
		 */
		preempt = optr->quantumleft;
		return OK;
	} else if (maxGoodness > 0 && (optr->pstate != PRCURR || optr->quantumleft == 0 || optr->goodness < maxGoodness)) {
		/*
		 * Currpid does not want to be PRCURR state any more even though it has more goodness and CPU time
		 * OR, Exhausted allocated CPU time, but wants to be PRCURR and has maxGoodness
		 * OR, Its goodness is less than maxGoodness, and has CPU time and wants to be PRCURR
		 * Process must be rescheduled and next process must begin.
		 */
		if (optr->real == FALSE && optr->pstate == PRCURR) { //Just like in Xinu Scheduling
			optr->pstate = PRREADY;
			insert(currpid, rdyhead, optr->pprio);
		} else if (optr->real == TRUE && optr->pstate == PRCURR) { //Just like in Xinu Scheduling
			optr->pstate = PRREADY;
			insert(currpid, realrdyhead, 1);
		}
		nptr = &proctab[newprocPID];
		nptr->pstate = PRCURR;
		dequeue(newprocPID);
		currpid = newprocPID;
		preempt = nptr->quantumleft;
		ctxsw((int) &optr->pesp, (int) optr->pirmask, (int) &nptr->pesp, (int) nptr->pirmask);
		return OK;
	} else
		return SYSERR;
}
/*-----------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:	Upon entry, currpid gives current process id.
 *		Proctab[currpid].pstate gives correct NEXT state for
 *			current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
	register struct	pentry	*optr;	/* pointer to old process entry */
	register struct	pentry	*nptr;	/* pointer to new process entry */
	int itemA, itemB, itemC,proc;
	int num, i;
	//STATWORD ps;
	optr = &proctab[currpid];
	
	if(sched_type==RANDOMSCHED)
	{
		/*if(count_random==0)
		{
			count_random++;
			enqueue(dequeue(0),queueC_tail);
		}*/
		
		if((!nonempty(queueC_head)) && (!nonempty(queueC_head)) && (!nonempty(queueC_head)))
		{
			return OK;
		}
		
		proctab[currpid].quantumLeft = preempt;	//quantum used in last execution
		if(switched_to_randomsched==1)
		{
			switched_to_randomsched=0;
			proctab[currpid].procCpuTicks += (proctab[currpid].assignedQuantum - preempt);
		}
		else
		{
			proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		}
		//proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		
		/*Make current process as ready*/
		if (optr->pstate == PRCURR) 
		{
			//kprintf("\nen inside ");

			optr->pstate = PRREADY;
			if(((optr->pprio)>=66) && ((optr->pprio)<=99))
			{
				//kprintf("\nReady Queue A, %s", optr->pname);
				enqueue(currpid, queueA_tail);
			}
		
			else if(optr->pprio>=33 && optr->pprio<=65)
			{
				//kprintf("\nReady Queue b, %s", optr->pname);
				enqueue(currpid, queueB_tail);
			}
		
			else if(optr->pprio>=0 && optr->pprio<=32)
			{
				//kprintf("\nReady Queue c, %s", optr->pname);
				enqueue(currpid, queueC_tail);
				//enqueue(0,queueC_tail);
			}
		}
		
		//srand(1);
		generate_random:
			num = rand();
			//kprintf("\n rand 1: %d", num);
			num = (num%97);
			//kprintf("\n normalized rand 1: %d", num);
		
		
		if(num>=50)
		{
		
			if(nonempty(queueA_head))
			{	
				itemA = getfirst(queueA_head);
				//kprintf("\nresched Queue A, %d",itemA);

				nptr = &proctab[ (currpid = itemA)];//getfirst(queueA_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
		
		else if(num>20 && num <50)
		{
		
			if(nonempty(queueB_head))
			{
				itemB = getfirst(queueB_head);
				//kprintf("\nresched Queue B, %d, %s",itemB, proctab[itemB].pname);

				nptr = &proctab[ (currpid = itemB)];//getfirst(queueB_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
		
		else if(num<=20)
		{
			
			if(nonempty(queueC_head))
			{
				itemC = getfirst(queueC_head);
				//kprintf("\nresched Queue C, %d, %s",itemC, proctab[itemC].pname);

				nptr = &proctab[ (currpid = itemC)];//getfirst(queueC_head)) ];
				nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
		
				ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
				/* The OLD process returns here when resumed. */
				return OK;

			}
			else
				goto generate_random;//resched();
		}
	}



	
	
	else if(sched_type == LINUXSCHED)
	{
		//int usedPreempt = preempt;
		int highProc;
		int oldPriority = proctab[currpid].pprio;	//save the current process' priority so that the effect of chprio() or change in priority to the quantum
													// or goodness is reflected in new epoch
		//int procGoodness = 0;
		int startNewEpoch = 1;
		//disable(ps);
		proctab[currpid].quantumLeft = preempt;
		if(switched_to_linuxsched==1)
		{
			proctab[currpid].runnableProc = 1;
			switched_to_linuxsched=0;
			proctab[currpid].procCpuTicks += (QUANTUM - preempt);
			proctab[currpid].assignedQuantum = proctab[currpid].assignedQuantum -(QUANTUM - preempt);
		}
		else
		{
			proctab[currpid].procCpuTicks += (proctab[currpid].assignedQuantum - preempt);
			proctab[currpid].assignedQuantum = proctab[currpid].quantumLeft;
		}
		
		
		if(optr->pstate == PRCURR)
		{
			optr->pstate = PRREADY;
			insert(currpid, rdyhead, proctab[currpid].procGoodness);
		}
		
		
			highProc = rdytail;

			while(q[highProc].qprev!=rdyhead  && q[highProc].qprev>=0 && q[highProc].qprev<NPROC)				//q[temp].qnext!=rdytail && q[temp].qnext>=0 && q[temp].qnext<NPROC
			{
				//kprintf("\t pbdsf%s",proctab[q[highProc].qprev].pname);
				
				
				if((proctab[q[highProc].qprev].runnableProc == 1) && (proctab[q[highProc].qprev].assignedQuantum > 0 ) )	//q[highProc].qnext!=0 && 
				{
					//kprintf("\n bacha hai : %d, %s",q[highProc].qprev, proctab[q[highProc].qprev].pname);
					startNewEpoch = 0;
					break;
				}
						
				highProc = q[highProc].qprev;
			}

		
		
		if(startNewEpoch == 1)
		{
			//kprintf("\nNew Epoch started---*******");
			for(i=0; i<NPROC; i++)
			{
				if(proctab[i].pstate != PRFREE)
				{
					oldPriority = proctab[i].pprio;	//prevent priority change effect in calculation of quantum
					//proctab[i].runnableProc = 1;
					
					//calculate quantum of each process either sleeping/waiting or ready
					if(proctab[i].runnableProc == 1)
					{
						if(proctab[i].assignedQuantum > 0)
						{
							proctab[i].assignedQuantum = (oldPriority + (proctab[i].assignedQuantum /2));
							
							proctab[i].procGoodness = (oldPriority + proctab[i].quantumLeft);
							//kprintf("\nNew quantum and goodness %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
						}
						else
						{
							proctab[i].assignedQuantum = oldPriority;
							
							proctab[i].procGoodness = 0;//(oldPriority);
							//kprintf("\nused up quantum %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
						}
					}
					proctab[i].runnableProc = 1;
					//kprintf("\nFinal values of quantum and goodness %d, %d, %s",proctab[i].assignedQuantum, proctab[i].procGoodness, proctab[i].pname);
					
					dequeue(i);
					insert(i, rdyhead, proctab[i].procGoodness);
					
					
				}
			}
			
			
		}
		
		//goodness is to be calculated for process in same epoch also ? -> no
	
		highProc = rdytail;
		
		
		while(q[highProc].qprev!=rdyhead && q[highProc].qprev>=0 && q[highProc].qprev<NPROC)
		{
			
			/*kprintf("\n Highest proc based on goodness %d, %d, %d", q[highProc].qprev, proctab[q[highProc].qprev].procGoodness, proctab[q[highProc].qprev].assignedQuantum);
			if(proctab[q[highProc].qprev].pstate == PRREADY)
			{
				kprintf("\nstate: PRREADY, %d", proctab[q[highProc].qprev].runnableProc);
				
			}*/
			if( (proctab[q[highProc].qprev].runnableProc == 1) && (proctab[q[highProc].qprev].assignedQuantum > 0 ) )//&& (proctab[q[highProc].qprev].pstate==PRREADY) && q[highProc].qprev!=0 )
			{
				//kprintf(" \ninside----------- %d", currpid);
				currpid = dequeue(q[highProc].qprev);
				//kprintf(" \nnew pid----------- %d", currpid);
				//if(currpid != 0)
				//{
					nptr = &proctab[currpid];
					nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = nptr->assignedQuantum;		/* reset preemption counter	*/
				#endif
	
					ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
					/* The OLD process returns here when resumed. */
					return ;// OK;
					break;
				}
			
			else if( (q[rdyhead].qnext == 0) && (q[rdytail].qprev== 0))
				{
					//proctab[currpid].assignedQuantum = QUANTUM;
			//	kprintf(" \ninside----------- %d", currpid);
					nptr = &proctab[(currpid=0)];
					nptr->pstate = PRCURR;		/* mark it currently running	*/
				#ifdef	RTCLOCK
					preempt = QUANTUM;		/* reset preemption counter	*/
				#endif
					ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
		
					/* The OLD process returns here when resumed. */
					return;// OK;
					break;
				}
				highProc = q[highProc].qprev;
			}
	
	}

	
	
	

	else if(sched_type!=RANDOMSCHED && sched_type!=LINUXSCHED)
	{

		/* no switch needed if current process priority higher than next*/
	
	
		if ( ( optr->pstate == PRCURR) && (lastkey(rdytail)<optr->pprio)) 
		{
			return(OK);
		}
	
		/* force context switch */

		if (optr->pstate == PRCURR) {
			optr->pstate = PRREADY;
			insert(currpid,rdyhead,optr->pprio);
		}

		proctab[currpid].quantumLeft = preempt;
		proctab[currpid].procCpuTicks += (QUANTUM - preempt);
		/* remove highest priority process at end of ready list */

		nptr = &proctab[ (currpid = getlast(rdytail)) ];
		nptr->pstate = PRCURR;		/* mark it currently running	*/
	#ifdef	RTCLOCK
		preempt = QUANTUM;		/* reset preemption counter	*/
	#endif
	
		ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
	
		/* The OLD process returns here when resumed. */
		return OK;
	}
}
/*------------------------------------------------------------------------
 *  resched  -  Reschedule processor to highest priority eligible process
 *------------------------------------------------------------------------
 */
void	resched(void)		/* Assumes interrupts are disabled	*/
{
	struct procent *ptold;	/* Ptr to table entry for old process	*/
	struct procent *ptnew;	/* Ptr to table entry for new process	*/

	/* If rescheduling is deferred, record attempt and return */

	if (Defer.ndefers > 0) {
		Defer.attempt = TRUE;
		return;
	}

	/* Point to process table entry for the current (old) process */

	ptold = &proctab[currpid];

	if(ptold->is_real_proc==1)
	{
	 if(ptold->prstate == PR_CURR){
	    if(ptold->real_prio > queuetab[firstid(60)].real_qkey)
	    {
	     return;
	     }

	     ptold->prstate = PR_READY;
	     insert_real(currpid, readylist[60], (double)(ptold->real_prio));
	     }
	     }

        //if the process is currently executing i.e it is executing currently, then it is considered as CPU bound process
	else{
	if (ptold->prstate == PR_CURR) {  /* Process remains eligible */
		/*if (ptold->prprio > firstkey(readylist)) {
			return;
		}*/
		
                  /* Old process will no longer remain current */
	       if(currpid!=NULLPROC){
                ptold->prprio = tstab[ptold->prprio].ts_tqexp;
		}
		ptold->prstate = PR_READY;
		enqueue(currpid, readylist[ptold->prprio]); 


	}
        //if the process is in sleep state, it is considered to be as an I/O bound process
    	else if(ptold->prstate == PR_SLEEP){
	       ptold->prprio = tstab[ptold->prprio].ts_slpret;
	       }
        }

      /* Force context switch to highest priority ready process */
      //Now find the Process with the highest Priority from the ready list and then assign it as the currpid
        int i;
	for(i=60;i>=0;i--){
	      
	      if(!isempty(readylist[i]))
	      {
	       //enqueue(currpid, readylist[ptold->prprio]);
	       currpid = dequeue(readylist[i]);
	       if(currpid ==NULLPROC)
	       {
	        if(!isempty(readylist[i]))
	          {
		  enqueue(currpid, readylist[i]);
		  currpid = dequeue(readylist[i]);
		  }
		  }
		 break;
		  }
	       }
	       
	       
	
                 
	
	ptnew = &proctab[currpid];
	if(ptnew->is_real_proc==1)
	{
	  preempt = 70;
	}
	else
	{
	
	preempt = tstab[ptnew->prprio].ts_quantum;		/* Reset time slice for process	*/
	}
	ptnew->prstate = PR_CURR;
			
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	//run the call back function
	
	ptnew = &proctab[currpid];
	
	if(ptnew->asigcb == 0){
	if(proctab[currpid].func!=NULL && proctab[currpid].prhasmsg==TRUE)
	{
	  *(proctab[currpid].abuf)= proctab[currpid].prmsg;
	    
	    proctab[currpid].prhasmsg = FALSE;
	  
	  (*proctab[currpid].func)();
	  //  proctab[currpid].prhasmsg = FALSE;
         }
	 }


	 if(ptnew->asigcb ==1) {
            if(ptnew->optarg == 0)
	    {
	     if(ptnew->arecvfunc!=NULL && ptnew->prhasmsg==TRUE)
	     {
	        (*ptnew->arecvfunc)();   
	         // ptnew->prhasmsg = FALSE;
	     }
	     }
	    
	    
	  //  if(ptnew->optarg>0)
	    // {
	    //  if(ptnew->alarmfunc!=NULL && ptnew->prhasmsg==TRUE)
	     // {
	     if(ptnew->alarm_time>0)
	     {
	       if(myglobalclock >= ptnew->alarm_time)
	       {
	        
                
		 
		ptnew->alarm_time = -1;
                
	        (*ptnew->alarmfunc)();
                }
	}

    
	       // ptnew->prhasmsg = FALSE;
	      
	    // }
	   // }
         // }
}



	/* Old process returns here when resumed */

	return;
}
Example #16
0
void _resched_linux(struct pentry *optr, struct pentry *nptr)
{
	int oldpreempt = preempt;
	preempt = MAXINT;
	
	/* Copy over however much counter the current process had left */
	int counter_diff = proctab[currpid].pcounter - oldpreempt;
	proctab[currpid].pcounter -= counter_diff;

	/* Check to see if there are any processes on the ready queue
 	   which are able to run and have quantum left */
	int done_with_epoch = 1;
	int item = q[rdytail].qprev;
	/* Loop over backwards, looking for can_run, pstate == PRREADY and
 	   counter > 0 */
	while (q[item].qprev != EMPTY) {
		/* If we find an eligible process, flag the epoch as not done */
		if (proctab[item].pcan_run && (proctab[item].pstate == PRREADY ||
		    proctab[item].pstate == PRCURR) && proctab[item].pcounter > 0) {
			done_with_epoch = 0;
			break;
		}
		/* Move on to the previous item */
		item = q[item].qprev;
	}

	/* If the epoch is over or we have no proceses eligible to execute for this epoch */
	if (done_with_epoch) {
		/* Make sure the null proc has a counter of 0 */
		proctab[NULLPROC].pcounter = 0;

		/* Loop over each process */
		int pid;
		for (pid=1; pid<NPROC; pid++) {
			if (proctab[pid].pstate == PRFREE)
				continue;

			/* Set this process as runnable, since we're starting a new epoch */
			proctab[pid].pcan_run = 1;
			/* Copy the priority over to the field to use during epochs, since
			   priority cannot change during runtime */
			proctab[pid].pprio2 = proctab[pid].pprio;
			/* If this process has quantum left over the threshold, factor that in */
			if (proctab[pid].pcounter >= rollover_threshold) {
				proctab[pid].pquantum = floor(proctab[pid].pcounter/2) + proctab[pid].pprio2;
				proctab[pid].pcounter = proctab[pid].pquantum;
			}
			/* Otherwise, set it's quantum counter to it's priority */
			else {
				proctab[pid].pquantum = proctab[pid].pcounter = proctab[pid].pprio2;
			}
			
			/* If this process is on the ready queue, make sure it's in the right
 			   spot since it's key may have changed */	
			if (proctab[pid].pstate == PRREADY) {
				int new_goodness = proctab[pid].pcounter + proctab[pid].pprio2;
				/* If the new value is between the processes before and after
 				   this one, then it's safe to just change the value */
				if (new_goodness >= q[q[pid].qprev].qkey &&
				    new_goodness <= q[q[pid].qnext].qkey) {
					q[pid].qkey = new_goodness;
				}
				/* If it's not though, we need to dequeue the process and
 				   insert it back in with the new goodness value */
				else {
					dequeue(pid);
					insert(pid, rdyhead, new_goodness);
				}
			}
		}
		
		/* Then put the current process back into the ready queue, if it wants to */
		if (optr->pstate == PRCURR) {
			optr->pstate = PRREADY;
			insert(currpid, rdyhead, proctab[currpid].pcounter + proctab[currpid].pprio2);
		}
	}
	/* Put the current process back into the ready queue */
	else if (optr->pstate == PRCURR) {
		int new_goodness = optr->pcounter > 0 ? optr->pcounter + optr->pprio2 : 0;
		if (new_goodness > lastkey(rdytail)) {
			if (currpid != 0)
				preempt = optr->pcounter;
			else
				preempt = QUANTUM;
			return;
		}
		optr->pstate = PRREADY;
		insert(currpid, rdyhead, new_goodness);
	}

	/* Get the item with the highest 'goodness' */
	currpid = getlast(rdytail);

	/* Otherwise, switch contexts to the new current process */
	nptr = &proctab[currpid];
	nptr->pstate = PRCURR;
#ifdef	RTCLOCK
	if (currpid != 0)
		preempt = nptr->pcounter;
	else
		preempt = QUANTUM;
#endif

	ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);

	return;
}
Example #17
0
/*------------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:	Upon entry, currpid gives current process id.
 *		Proctab[currpid].pstate gives correct NEXT state for
 *			current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int	resched()
{
	STATWORD		PS;
	register struct	pentry	*optr;	/* pointer to old process entry */
	register struct	pentry	*nptr;	/* pointer to new process entry */
	register int i;

	disable(PS);
	/* no switch needed if current process priority higher than next*/

	if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
	   (lastkey(rdytail)<optr->pprio)) {
		restore(PS);
		return(OK);
	}
	
#ifdef STKCHK
	/* make sure current stack has room for ctsw */
	asm("movl	%esp, currSP");
	if (currSP - optr->plimit < 48) {
		kprintf("Bad SP current process, pid=%d (%s), lim=0x%lx, currently 0x%lx\n",
			currpid, optr->pname,
			(unsigned long) optr->plimit,
			(unsigned long) currSP);
		panic("current process stack overflow");
	}
#endif	

	/* force context switch */

	if (optr->pstate == PRCURR) {
		optr->pstate = PRREADY;
		insert(currpid,rdyhead,optr->pprio);
	}

	/* remove highest priority process at end of ready list */

	nptr = &proctab[ (currpid = getlast(rdytail)) ];
	nptr->pstate = PRCURR;		/* mark it currently running	*/
#ifdef notdef
#ifdef	STKCHK
	if ( *( (int *)nptr->pbase  ) != MAGIC ) {
		kprintf("Bad magic pid=%d value=0x%lx, at 0x%lx\n",
			currpid,
			(unsigned long) *( (int *)nptr->pbase ),
			(unsigned long) nptr->pbase);
		panic("stack corrupted");
	}
	/*
	 * need ~16 longs of stack space below, so include that in check
	 *	below.
	 */
	if (nptr->pesp - nptr->plimit < 48) {
		kprintf("Bad SP pid=%d (%s), lim=0x%lx will be 0x%lx\n",
			currpid, nptr->pname,
			(unsigned long) nptr->plimit,
			(unsigned long) nptr->pesp);
		panic("stack overflow");
	}
#endif	/* STKCHK */
#endif	/* notdef */
#ifdef	RTCLOCK
	preempt = QUANTUM;		/* reset preemption counter	*/
#endif
#ifdef	DEBUG
	PrintSaved(nptr);
#endif

	//OS proj 3 modify
	write_cr3(nptr->pdbr);
	
	ctxsw(&optr->pesp, optr->pirmask, &nptr->pesp, nptr->pirmask);

#ifdef	DEBUG
	PrintSaved(nptr);
#endif
	
	/* The OLD process returns here when resumed. */
	restore(PS);
	return OK;
}
Example #18
0
/*------------------------------------------------------------------------
 *  resched_lab2  -  fair scheduler from lab2, need to set lab2flag according to specs
 *  				 given in lab2 documentation on 503 course website.
 *------------------------------------------------------------------------
 */
void resched_lab2(void)
{
	uint32 currTime = clktimemsec;
	struct procent *ptold;	/* Ptr to table entry for old process	*/
	struct procent *ptnew;	/* Ptr to table entry for new process	*/
	/* If rescheduling is deferred, record attempt and return */

	if (Defer.ndefers > 0) {
		Defer.attempt = TRUE;
		return;
	}


	uint32 addToTotalTime =0;
	/* Point to process table entry for the current (old) process */
	ptold = &proctab[currpid];
	//Update the total processing time for context switched out process
	// Handle the case where the counter overflows then get the absolute value of difference
	addToTotalTime = (currTime)-(ptold->prctxswintime);

	// if the old process id is not of null user then update its total CPU time
	// else ignore this step because prcpumsec of null user is already set to max to
	// force it to only execute if no other process is ready
	if(currpid != 0)
		ptold->prcpumsec = ptold->prcpumsec +  addToTotalTime;

	// totest switches the key for the readylist queue to be tested based on the lab we are running.
	// For the lab3, its the priority of the process
	// and for lab 4 and 5 it's the prcpumsec, the cpu time given to the process
	int32 totest = ptold->prprio;


	// Here the totest will be set to the negation of prcpumsec
	// because we wan't to maintain using the insert function that
	// inserts elements in decreasing order. By this negation of prcpumsec would
	// cause the element with the least prcpumsec to be the first to be dequeud at the head.
	// Hence, we are followin the rules of the dynamic priority scheduling algorithm
	if(lab2flag == 4 || lab2flag == 5)
		totest =-(int32)ptold->prcpumsec;

	if (ptold->prstate == PR_CURR) {  /* Process remains eligible */
		if (totest > firstkey(readylist)) {
				ptold->prctxswintime = currTime;
				if(lab2flag ==5)
					reward_ready_waiting();
				return;
			}

			/* Old process will no longer remain current */


			if(lab2flag == 5)
				reward_ready_waiting();
			ptold->prstate = PR_READY;
			// The only other place an insert happens is at the ready method
			// even there we have chosen to implement a similar strategy of choosing the value
			// of key based on the lab that we are dealing with. That is, either to insert
			// based on priority or the negation of the prcpumsec spent.
			insert(currpid, readylist, totest);
			currpid = dequeue(readylist);
		}
	else
	{
		//even if the process is in sleep state and calling a reschedule
		// we must reward the other processes
		// of course, as soon as the process that is dequeued is removed its key value
		// would also
		if(lab2flag ==5)
			reward_ready_waiting();
		currpid = dequeue(readylist);
	}
	/* Force context switch to highest priority ready process */
	ptnew = &proctab[currpid];
	ptnew->prstate = PR_CURR;
	preempt = QUANTUM;		/* Reset time slice for process	*/
	//Update the context switch-in time for new process
	ptnew->prctxswintime = currTime;
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	// LAB 4Q3: Invoke the handleCallback
	handleCallback();
	/* Old process returns here when resumed */
	return;

}
Example #19
0
/*------------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:   Upon entry, currpid gives current process id.
 *      Proctab[currpid].pstate gives correct NEXT state for
 *          current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
    STATWORD        PS;
    register struct pentry  *optr;  /* pointer to old process entry */
    register struct pentry  *nptr;  /* pointer to new process entry */

    disable(PS);
    /* no switch needed if current process priority higher than next*/

    if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
       (lastkey(rdytail)<optr->pprio)) {
        restore(PS);
        return(OK);
    }
    
#ifdef STKCHK
    /* make sure current stack has room for ctsw */
    asm("movl   %esp, currSP");
    if (currSP - optr->plimit < 48) {
        kprintf("Bad SP current process, pid=%d (%s), lim=0x%lx, currently 0x%lx\n",
            currpid, optr->pname,
            (unsigned long) optr->plimit,
            (unsigned long) currSP);
        panic("current process stack overflow");
    }
#endif  

    /* force context switch */

    if (optr->pstate == PRCURR) {
        optr->pstate = PRREADY;
        insert(currpid,rdyhead,optr->pprio);
    }

    /* remove highest priority process at end of ready list */

    nptr = &proctab[ (currpid = getlast(rdytail)) ];
    nptr->pstate = PRCURR;      /* mark it currently running    */
#ifdef notdef
#ifdef  STKCHK
    if ( *( (int *)nptr->pbase  ) != MAGIC ) {
        kprintf("Bad magic pid=%d value=0x%lx, at 0x%lx\n",
            currpid,
            (unsigned long) *( (int *)nptr->pbase ),
            (unsigned long) nptr->pbase);
        panic("stack corrupted");
    }
    /*
     * need ~16 longs of stack space below, so include that in check
     *  below.
     */
    if (nptr->pesp - nptr->plimit < 48) {
        kprintf("Bad SP pid=%d (%s), lim=0x%lx will be 0x%lx\n",
            currpid, nptr->pname,
            (unsigned long) nptr->plimit,
            (unsigned long) nptr->pesp);
        panic("stack overflow");
    }
#endif  /* STKCHK */
#endif  /* notdef */
#ifdef  RTCLOCK
    preempt = QUANTUM;      /* reset preemption counter */
#endif
#ifdef  DEBUG
    PrintSaved(nptr);
#endif

    // When performing a context switch between processes we must also
    // switch between memory spaces. This is accomplished by adjusting
    // the PDBR register with every context switch. 
    //
    // 5 - Context switch
    //      - every process has separate page directory
    //      - before ctxsw() load CR3 with the process' PDBR
    set_PDBR(VA2VPNO(nptr->pd));
#if DUSTYDEBUG
    kprintf("switching to process %d\n", (nptr - proctab));
#endif

    ctxsw(&optr->pesp, optr->pirmask, &nptr->pesp, nptr->pirmask);

#ifdef  DEBUG
    PrintSaved(nptr);
#endif
    
    /* The OLD process returns here when resumed. */
    restore(PS);
    return OK;
}
Example #20
0
/* ------------------------------------------------------------------------
 * resched_lab3 -  Multi-feedback queue will now be the default scheduler going forward
 *				   This is the scheduler from lab3 that achieves constant time dequeue
 *				   since the size of the levels in the dispatch table is a fixed number
 *-------------------------------------------------------------------------
 */
void resched_lab3(void)
{
	uint32 currTime = clktimemsec;
	struct procent *ptold;	/* Ptr to table entry for old process	*/
	struct procent *ptnew;	/* Ptr to table entry for new process	*/

	/* If rescheduling is deferred, record attempt and return */

	if (Defer.ndefers > 0) {
		Defer.attempt = TRUE;
		return;
	}

	/* Point to process table entry for the current (old) process */
	uint32 addToTotalTime =0;
	/* Point to process table entry for the current (old) process */
	ptold = &proctab[currpid];
	//Update the total processing time for context switched out process
	// Handle the case where the counter overflows then get the absolute value of difference
	addToTotalTime = (currTime)-(ptold->prctxswintime);


	ptold->prcpumsec = ptold->prcpumsec +  addToTotalTime;

	ptold = &proctab[currpid];

	pri16 oldprio = ptold->prprio;

	if (ptold->prstate == PR_CURR) {

		// update the priority based on TS dispatch table values for active process's time quantum expiration scenario
		pri16 oldprio = ptold->prprio;
		int timegiven = tsdtab[oldprio].ts_quantum;
		if(currpid != 0)
		{
				ptold->prprio = tsdtab[oldprio].ts_tqexp;

		}
		// cpu- intensive process
		if(currproc_eligible()) // check eligibility of current process to get another quantum
			{
				ptold->prctxswintime = currTime;
				return;
			}
		else
		{
			// current process will be switched out
			// enqueu at correct location for when next time it may be selected
			// by scheduler it will be at correct level on multi-level feedback queue.
			ptold->prstate = PR_READY;
			enqueue(currpid, queueArr[ptold->prprio]);
		}

	}
	else if (ptold->prstate == PR_SLEEP)
	{
		// io- intensive process

		// update the priority based on TS dispatch table values for sleep return
		if(currpid != 0)
			ptold->prprio = tsdtab[ptold->prprio].ts_slpret;

	}

	/* Force context switch to highest priority ready process */

	currpid = multifeedbackDQ();
	ptnew = &proctab[currpid];
	ptnew->prstate = PR_CURR;
	ptnew->prctxswintime = currTime;
	preempt = tsdtab[ptnew->prprio].ts_quantum;		/* Reset time slice for process	*/
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	// LAB 4Q3: Invoke the handleCallback
	handleCallback();

	/* Old process returns here when resumed */

	return;
}
Example #21
0
/*-----------------------------------------------------------------------
 * resched  --  reschedule processor to highest priority ready process
 *
 * Notes:	Upon entry, currpid gives current process id.
 *		Proctab[currpid].pstate gives correct NEXT state for
 *			current process if other than PRREADY.
 *------------------------------------------------------------------------
 */
int resched()
{
	register struct	pentry	*optr;	/* pointer to old process entry */
	register struct	pentry	*nptr;	/* pointer to new process entry */
	int rand_num,temp_currpid,i;
	/* no switch needed if current process priority higher than next*/

        if(used_scheduler == RANDOMSCHED)
        {
		optr= &proctab[currpid];
	}
        else if(used_scheduler == LINUXSCHED)
        {
		optr= &proctab[currpid];
	}
	else
	{

		if ( ( (optr= &proctab[currpid])->pstate == PRCURR) &&
	   (lastkey(rdytail)<optr->pprio)) 
		{
			return(OK);
		}
	}
	
	/* force context switch */

	if (optr->pstate == PRCURR) 
	{
		optr->pstate = PRREADY;
		optr->arrival_time = ctr1000;
		if(preempt >= 0)
			optr->quantum_left = preempt;
		insert(currpid,rdyhead,optr->pprio);
	}

	/* remove highest priority process at end of ready list */
	if(used_scheduler != LINUXSCHED)
        {
		execution_time[currpid]+=(QUANTUM-preempt);
	}
	else
		execution_time[currpid]+= (proctab[currpid].quantum_left -preempt);
	//kprintf("\nPreempt: %d",preempt);
	

        if(used_scheduler == RANDOMSCHED)
        {
		if(q[rdyhead].qnext == rdytail)
			return(OK);
		do
		{
			rand_num = rand()%100;
		//	kprintf("Random Number: %d",rand_num);
			if(rand_num >=80)
				 temp_currpid = random_getpid(1);
			else if(rand_num <80 && rand_num >=50)
                                 temp_currpid = random_getpid(2);			
			else	
                                 temp_currpid = random_getpid(3);

		}while(temp_currpid == -1);
		currpid = temp_currpid;
		nptr = &proctab[currpid];
		dequeue(currpid);
		//kprintf("\n Current PID : %d",currpid);
	
        }
	else if(used_scheduler == LINUXSCHED)
        {
		temp_currpid = linux_getpid();
		if(temp_currpid == -1)
		{
			 new_epoch();
                         temp_currpid = linux_getpid();
			 if(temp_currpid == -1)
        		 {
				temp_currpid=0;;
			 }	
			
		}
                currpid = temp_currpid;
                nptr = &proctab[currpid];
                dequeue(currpid);		
	}
	else
	{
		nptr = &proctab[ (currpid = getlast(rdytail)) ];
	}
	nptr->pstate = PRCURR;		/* mark it currently running	*/
#ifdef	RTCLOCK
	if(used_scheduler != LINUXSCHED)
		preempt = QUANTUM;		/* reset preemption counter	*/
	else
	{		preempt = proctab[currpid].quantum_left;
	}
#endif
	
	ctxsw((int)&optr->pesp, (int)optr->pirmask, (int)&nptr->pesp, (int)nptr->pirmask);
	
	/* The OLD process returns here when resumed. */
	return OK;
}