Пример #1
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 */

	/* no switch needed if current process priority higher than next*/
	optr = &proctab[currpid];
if(optr->pinh==0){

	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);
	}

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

	
	} else if(optr->pinh>0){
	//kprintf("\n In resched with %d  %d",currpid,optr->pinh);
	if ( ( (optr)->pstate == PRCURR) &&(lastkey(rdytail)<optr->pinh)) {
		return(OK);
	}
	
	if (optr->pstate == PRCURR) {
		optr->pstate = PRREADY;
		insert(currpid,rdyhead,optr->pinh);
	}

	
	
	}
	/* The OLD process returns here when resumed. */
	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);
	return OK;
}
Пример #2
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;
}
Пример #3
0
/* 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;
}
Пример #4
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 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;
	}
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
0
/*------------------------------------------------------------------------
 * lock  --  make current process wait on a lock 
 *------------------------------------------------------------------------
 */
int lock(int ldes1, int type, int priority)
{
	STATWORD ps;
	struct	lentry	*lptr;
	struct	pentry	*pptr;

	/* disable interupts */
	disable(ps);

	int lockid = getIndexForLockDescriptor(ldes1);
	/* check for a bad lock, free lock or invalid type */
	if (isbadlock(lockid) || (lptr= &locks[lockid])->lstate==LFREE
		|| (type != READ && type != WRITE)) {
		/* restore interupts */
		restore(ps);
		return SYSERR;
	}

	/* if this lock is acquired and being requested by a reader */
	if (lptr->llocked != UNLOCKED && type == READ) {
		/* if the lock is held by a reader and if the
		 * request priority is equal to or greater than the
 		 * highest priority writer on the queue, then this
 		 * process is allowed to continue */
		if (lptr->llocked == LOCKED_READ &&
		    priority >= lastkey(lptr->lwqtail)) {
			/* bump the number of readers */
			lptr->lnreaders++;
			/* set this processes locker flag to TRUE */
			lptr->llockers[currpid] = TRUE;
			/* restore interupts */
			return OK;
		}
		/* otherwise, since its priority is lower, it should
 		 * go on the reader queue */
		insert(currpid, lptr->lrqhead, priority);
		/* get the current process */ 
		(pptr = &proctab[currpid])->pstate = PRWAIT;
		/* update this locks max wait prio based on this new waiter */
		updateMaxWaitPrio(pptr, lptr);
		/* update the pentry for waiting */
		updateProcessForWaiting(pptr, ldes1);
		/* reschedule since this process is now blocked */
		/* a context switch should happen here */
		resched();
		/* the number of readers and locker flag will be set when
		 * releaselock(...) is called in releaseall.c */
		/* restore interupts */
		restore(ps);
		/* return the wait return value */
		return pptr->pwaitret;
	/* else if this lock is ackquired by a writer */
	} else if (lptr->llocked != UNLOCKED && type == WRITE) {
		/* this process must go on the queue because writing locks
 		 * are exclusive */
		insert(currpid, lptr->lwqhead, priority);
		/* get the current process */ 
		(pptr = &proctab[currpid])->pstate = PRWAIT;
		/* update the pentry for waiting */
		updateProcessForWaiting(pptr, ldes1);
		/* update this locks max wait prio based on this new waiter */
		updateMaxWaitPrio(pptr, lptr);
		/* reschedule since this process is now blocked */
		/* a context switch should happen here */
		resched();
		/* when we get here, this writer has the lock now, so: */
		/* set this processes locker flag to TRUE */
		lptr->llockers[currpid] = TRUE;
		/* restore interupts */
		restore(ps);
		return pptr->pwaitret;
	}

	/* otherwise, the lock is free, so acquire it and set
 	 * the flag and number of readers accordingly */
	if (type == READ) {
		lptr->llocked = LOCKED_READ;
		lptr->lnreaders = 1;
	} else {
		lptr->llocked = LOCKED_WRITE;
		lptr->lnreaders = 0;
	}
	/* set this processes locker flag to TRUE */
	lptr->llockers[currpid] = TRUE;

	/* restore interupts */
	restore(ps);
	return OK;
}
Пример #8
0
LOCAL int release(int lockid){
//first we check 
	//kprintf("\nin release with lockid %d", lockid);
	struct	lentry	*lptr;
	struct	pentry	*pptr;
	pptr = &proctab[currpid];
	lptr = &locktab[lockid];
	//let us first check weather this lock is held by this process or not.
	int flag = 1;
	int i=0;
	// for( i =0;i<NLOCKS;i++){
		// if((pptr->acqlocks[i] == READ || pptr->acqlocks[i]==WRITE) && i==lockid)
			// flag = 0;
	// }
	if((pptr->acqlocks[lockid] == READ || pptr->acqlocks[lockid]==WRITE))
			 flag = 0;
		//kprintf("\n value: %d %d  %d\n",pptr->acqlocks[lockid],lockid,currpid);
	//kprintf("\nFlag: %d",flag);
	if(flag==1)
		return flag;
	else{
		//kprintf("\nMatched the process.");
		//so now we have checked weather the lock is valid or not, now we release this lock.
		//we take one/other process  should be given the lock.
		
			pptr->acqlocks[lockid] = 0;
			//thus keeps track of the process and its type;
			lptr->processforlock[currpid]=0;//makes it 0, setting that this process is not executing.
			lptr->lockcnt--;
		if(isempty(lptr->lqhead))
		{
			//kprintf("\nqueue is empty");
			//if the queue is empty then we should make the entries of that process as null, as this process should release this lock.
			
			////we set it neither to read nor write.
			//it can also happen that the wait queue is empty but there are current ready process holding the lock
			if(lptr->lockcnt==0){
				
				lptr->currentlock = 0;
				return 0;
				}
			else{
			//kprintf("\nfirst %d",lptr->lockcnt);
				return 0;
				
			}
		}else{
		//kprintf("\nNOT empty");
			//if the queue is nonempty there is/ are other proces which want to have the lock, we schedule them and take them out of the queue.
			//2 cases in this scenario:
			//1. the current process was write, so we should give lock to other processes in the queue.
			//2. the current process was read, and there are other processes waiting in queue. implying this process is write., so we give lock to this write proces based on things.
			if(lptr->currentlock == READ||lptr->currentlock==WRITE){
				//then there is going to be either one writer and there might be processes whic are higher priories.
				//firstly are there equal priority processes, and if there are then how much.
				
				//lets check what is priority of our head.
				int maxpriority = lastkey(lptr->lqtail);//if this returns the process id
				int iterator=0;
				int j=0;
				int samepriorityprocess=0;
				int priorityarr[50];
				//now, we check how many process with this priority are in the queue.
				for(iterator=0;iterator<50;iterator++){
					if(iterator!=maxpriority){
						
						if(lptr->prioritytype[i]==lptr->prioritytype[maxpriority]){
							samepriorityprocess++;
								priorityarr[j] = i;
								j++;
							}
					
					}
				
				}
				int rcompare=0;
				int rtemp=0;
				int wcompare=0;
				int wtemp=0;
				int witerator=0;
				int riterator=0;
				//after this we know the number of processes with same priority.
				if(samepriorityprocess==0){
					//there are no process with this max prioroty, we start this process.
					//make this process ready and return OK, saying that the lock was released.
					/*We need to change a lot of things here.*/
					makeready(maxpriority,lockid,lptr->waittype[maxpriority]);
					return 0;
				} else if(samepriorityprocess>0){
					//we check the time of running. for all same priority process
					//We difrenciate between read and write or not?
					for(iterator=0;iterator<j;iterator++){
						pptr = &proctab[iterator];
						if(lptr->waittype[iterator]==READ){
							if((rtemp = ctr1000-(pptr->timeinqueue))>rcompare){
								rcompare = rtemp;
								riterator = iterator;
							}
						} else if(lptr->waittype[iterator]==WRITE){
							if((wtemp = ctr1000-(pptr->timeinqueue))>wcompare){
								wcompare = wtemp;
								witerator=iterator;
							}
						
						}
					}
					/*to implement this.*/
					//after this we have the max time the process has been in priority.
					if(wcompare-rcompare>=-1){
						//we give write process the right to run, with max priority.
						makeready(witerator,lockid,lptr->waittype[witerator]);
						return 0;
					}
					else if(wcompare-rcompare<-1){
						//as read process waited for more time than write, we ready all read process with max priority.
						for(iterator=0;iterator<j;iterator++){
							if(lptr->waittype[iterator]==READ){
								makeready(iterator,lockid,lptr->waittype[iterator]);
								
							}
						}
						return 0;
					} 
				
				}
				
				
			 }
		
		}
	
	
	
	
	}
}
Пример #9
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;
}
Пример #10
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;
}