/*----------------------------------------------------------------------- * 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; }
/*------------------------------------------------------------------------ * 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; }
/*----------------------------------------------------------------------- * 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 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; }
/*------------------------------------------------------------------------ * 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; }
/*------------------------------------------------------------------------ * 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; }
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; } } } } } }
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; }
/*----------------------------------------------------------------------- * 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; }