/*------------------------------------------------------------------------ * ldelete -- delete a lock by releasing its table entry *------------------------------------------------------------------------ */ int ldelete (int lockdescriptor) { STATWORD ps; int pid; int temp,temp1; struct lentry *lptr; disable(ps); if (isbadlock(lockdescriptor) || locks[lockdescriptor].lstate==DELETED || locks[lockdescriptor].lstate==LFREE) { restore(ps); return(SYSERR); } lptr = &locks[lockdescriptor]; lptr->lstate = DELETED; lptr->ltype = NONE; lptr->lreaders= 0; if (nonempty(lptr->lqhead)) { while( (pid=getfirst(lptr->lqhead)) != EMPTY) { proctab[pid].plockwaitret = DELETED; proctab[pid].locktype[lockdescriptor] = DELETED; dequeue(pid); ready(pid,RESCHNO); //kprintf("\n\t\t[LDELETE.C: 37] Proc '%s' deleted from waitqueue of Lock %d\n",proctab[pid].pname,lockdescriptor); } resched(); } for(pid=1;pid<NPROC;pid++) { if(locks[lockdescriptor].lprocs[pid] == READ || locks[lockdescriptor].lprocs[pid] == WRITE) { locks[lockdescriptor].lprocs[pid] = DELETED; } } restore(ps); return(OK); }
int ldelete(int ldes) { STATWORD ps; struct lentry *lptr; int pid, lockID; disable(ps); lockID = getLockID(ldes); if( isbadlock(lockID) || (lptr=&locktab[lockID])->lstate == LOCKFREE ) { restore(ps); return(SYSERR); } //lptr = &locktab[ldes]; lptr->lstate = LOCKFREE; lptr->locked = 0; lptr->acquiredby[currpid]=-1; lptr->lockType = DELETED; lptr->lprio=-1; if( nonempty(lptr->lhead) ) { while( (pid=getlast(lptr->lhead)) != EMPTY ) { proctab[pid].waitPriority = -1; proctab[pid].lockID = -1; proctab[pid].procLockType[lockID] = DELETED; proctab[pid].pwaitret = DELETED; ready(pid, RESCHNO); } resched(); } restore(ps); return(OK); }
int ldelete (int lockdescriptor) { STATWORD ps; int pid; struct lentry *lptr; disable(ps); if (isbadlock(lockdescriptor%100) || lockarr[lockdescriptor%100].lstate==LFREE) { restore(ps); return(SYSERR); } lptr = &lockarr[lockdescriptor%100]; lptr->lstate = LFREE; if (nonempty(lptr->lqhead)) { while( (pid=getfirst(lptr->lqhead)) != EMPTY) { proctab[pid].pwaitret = DELETED; ready(pid,RESCHNO); } resched(); } restore(ps); return(OK); }
int lock(int ldes, int type, int priority) //priority here = process wait priority { STATWORD ps; struct lentry *lptr; struct pentry *pptr; int lockNotGivenToRead = 0; int temp = -1; int lockID; disable(ps); pptr = &proctab[currpid]; lockID = getLockID(ldes); //kprintf("\n IN lock: %d...lock des..%d", lockID, ldes); if( isbadlock(lockID) || (lptr=&locktab[lockID])->lstate == LOCKFREE || type == DELETED) { restore(ps); return(SYSERR); } if( lptr->locked == 0 ) { lptr->lstate = LOCKUSED; lptr->locked = 1; //indicates someone has acquired lockID lptr->acquiredby[currpid] = 1; //stores the PID of process which has acquired lockID lptr->lockType = type; lptr->lprio = pptr->pprio; pptr->procLockType[lockID] = type; //indicates type of locking (WRITE or READ) for a process pptr->waitPriority = priority; //sets wait priority of process pptr->lockID = -1; //process not in wait queue so its lock id is -1; restore(ps); return(OK); } else if( lptr->locked != 0 ) { if(lptr->lockType == WRITE) { pptr->pstate = PRWAIT; pptr->lockID = ldes; pptr->procLockType[lockID] = type; //indicates type of locking (WRITE or READ) for a process pptr->waitPriority = priority; //sets wait priority of process pptr->timeInWaiting = ctr1000; rampUpPriority(lockID, pptr->pprio); insert(currpid, lptr->lhead, priority); //pptr->pwaitret = OK; resched(); restore(ps); return(OK); } else if(lptr->lockType == READ ) { if( type == READ ) { //check if incoming process is reader and has wait priority larger than any waiting writer process wait priority temp = lptr->lhead; while( q[temp].qnext != lptr->ltail ) { if( (proctab[q[temp].qnext].procLockType[lockID] == WRITE) && (priority < proctab[q[temp].qnext].waitPriority) ) { lockNotGivenToRead = 1; //1 value indicates the lock should not be given because a writer with larger wait prio than this read is waiting } temp = q[temp].qnext; } if(lockNotGivenToRead == 1) { pptr->pstate = PRWAIT; pptr->lockID = ldes; pptr->procLockType[lockID] = type; //indicates type of locking (WRITE or READ) for a process pptr->waitPriority = priority; //sets wait priority of process rampUpPriority(lockID, pptr->pprio); pptr->timeInWaiting = ctr1000; insert(currpid, lptr->lhead, priority); //pptr->pwaitret = OK; resched(); restore(ps); return(OK); } else if(lockNotGivenToRead != 1) //READER can be given lockID as no writer with wait prio greater than currpid wait prio is there { if( lptr->lprio < pptr->pprio ) { lptr->lprio = pptr->pprio; } lptr->acquiredby[currpid] = 1; pptr->procLockType[lockID] = type; //indicates type of locking (WRITE or READ) for a process pptr->waitPriority = priority; pptr->lockID = -1; restore(ps); return(OK); } } else if( type == WRITE ) { pptr->pstate = PRWAIT; pptr->lockID = ldes; pptr->procLockType[lockID] = type; //indicates type of locking (WRITE or READ) for a process pptr->waitPriority = priority; //sets wait priority of process rampUpPriority(lockID, pptr->pprio); pptr->timeInWaiting = ctr1000; insert(currpid, lptr->lhead, priority); //pptr->pwaitret = OK; resched(); restore(ps); return(OK); } } } 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; }
SYSCALL kill(int pid) { STATWORD ps; struct pentry *pptr; /* points to proc. table for pid*/ int dev, i, callResched, lockID; callResched = RESCHNO; disable(ps); if (isbadpid(pid) || (pptr= &proctab[pid])->pstate==PRFREE) { restore(ps); return(SYSERR); } if (--numproc == 0) xdone(); dev = pptr->pdevs[0]; if (! isbaddev(dev) ) close(dev); dev = pptr->pdevs[1]; if (! isbaddev(dev) ) close(dev); dev = pptr->ppagedev; if (! isbaddev(dev) ) close(dev); for( i=0; i<NLOCKS; i++) { if( locktab[i].acquiredby[pid] == 1) //this process has acquired some lock and holding it, so release it and resched { //kprintf("\n Kill is holding lock %s", proctab[pid].pname); callResched = RESCHYES; relLock(pid, i, 0); } } send(pptr->pnxtkin, pid); freestk(pptr->pbase, pptr->pstklen); switch (pptr->pstate) { case PRCURR: pptr->pstate = PRFREE; /* suicide */ resched(); case PRWAIT: semaph[pptr->psem].semcnt++; //if this proc is in wait queue of any lock i, remove it ... a proc can be in waiting q of any one lock only /* for( i=0; i<NLOCKS; i++) { if( (proctab[pid].procLockType[i]!=DELETED) && (locktab[i].acquiredby[pid]!=1) ) { kprintf("Killed Process %d waiting on lock %d", pid, i); locktab[j].effectOfPriorityInheritance = 1; rampUpPriority(j, proctab[i].pprio); } } */ lockID = getLockID(pptr->lockID); if( !isbadlock(lockID) || locktab[lockID].lstate != LOCKFREE ) { //dequeue(pid); //kprintf("\nKill proc getting called in PRWAIT, releasing wait lock %d..%d", lockID, pid); proctab[pid].pprio = -1; proctab[pid].mainPrio = -1; relLock(pid, lockID, 1); //dequeue(pid); } case PRREADY: dequeue(pid); pptr->pstate = PRFREE; break; case PRSLEEP: case PRTRECV: unsleep(pid); /* fall through */ default: pptr->pstate = PRFREE; } if(callResched) { //kprintf("\n About to call resched"); //indicates that this proc was holding lock and is deleted //in between so now it should release lock and call resched resched(); } restore(ps); return(OK); }
int release(int ldes1, int pid) { register struct sentry *sptr; struct pentry *pptr; STATWORD ps; //unsigned long ctime; int tail,prev,ldes,ver; #ifdef DEBUGF kprintf("\nInside release\n"); #endif disable (ps); ldes=GET_LOCK(ldes1); ver=GET_VER(ldes1); #ifdef DEBUGF kprintf("\nLDES:%04x, VER:%d, LOCK:%d\n",ldes1,ver,ldes); #endif if (isbadlock(ldes) || (sptr= &semaph[ldes])->sstate==SFREE) { #ifdef DEBUGF kprintf("\npid %d has found an error, ldes=%d, sptr->sstate= %d\n",pid,ldes,sptr->sstate); #endif restore(ps); return(SYSERR); } if (ver!=sptr->lversion) { #ifdef DEBUGF kprintf("\nVersion error\n"); #endif restore(ps); return(SYSERR); } if (fpidinlock(pid,ldes)==0) { restore(ps); return(SYSERR); } #ifdef DEBUGF kprintf("\nPast error check sptr->semcnt:%d\n",sptr->semcnt); #endif proctab[pid].lnosheld--; if ((sptr->semcnt++) < 0) { #ifdef DEBUGD kprintf("\nInside if,sptr->lstate:%d, sptr->nordu:%d \n",sptr->lstate,sptr->nordu); #endif if ( ((sptr->lstate==READ) && (--sptr->nordu==0)) || (sptr->lstate==WRITE)) { #ifdef DEBUGC kprintf("\nInside second if sptr->hprd:%d sptr->hpwrt:%d\n",sptr->hprd,sptr->hpwrt); #endif if (sptr->hprd>sptr->hpwrt) { //release all readers with hprd #ifdef DEBUGC kprintf("\nReleasing readers\n"); #endif tail=sptr->sqtail; prev=q[tail].qprev; while (q[prev].qkey==sptr->hprd) { pptr=&proctab[prev]; if (pptr->lstate==READ) { dequeue(prev); ready(prev,RESCHNO); lreschedyes=1; } prev=q[prev].qprev; } sptr->hprd=hpp(ldes,READ); //resched(); restore(ps); return (OK); } if (sptr->hpwrt>sptr->hprd) { #ifdef DEBUGD kprintf("\nReleasing writer\n"); #endif //release hpwrt tail=sptr->sqtail; prev=q[tail].qprev; while (q[prev].qkey==sptr->hpwrt) { pptr=&proctab[prev]; if (pptr->lstate==WRITE) { dequeue(prev); sptr->hpwrt=hpp(ldes,WRITE); #ifdef DEBUGD kprintf("\nReleasing writer pid%d for lock %d, new hpwrt= %d\n",prev,ldes,sptr->hpwrt); #endif ready(prev,RESCHNO); lreschedyes=1; restore(ps); return (OK); } prev=q[prev].qprev; } } if (sptr->hprd==sptr->hpwrt) { if (sptr->wtime-sptr->rtime>1000) { #ifdef DEBUGC kprintf("\nReleasing readers priority equal\n"); #endif //release all readers with hprd tail=sptr->sqtail; prev=q[tail].qprev; while (q[prev].qkey==sptr->hprd) { pptr=&proctab[prev]; if (pptr->lstate==READ) { dequeue(prev); ready(prev,RESCHNO); lreschedyes=1; } prev=q[prev].qprev; } sptr->hprd=hpp(ldes,READ); //resched(); restore(ps); return (OK); } else { //release hpwrt tail=sptr->sqtail; prev=q[tail].qprev; while (q[prev].qkey==sptr->hprd) { pptr=&proctab[prev]; if (pptr->lstate==WRITE) { dequeue(prev); sptr->hpwrt=hpp(ldes,WRITE); ready(prev,RESCHNO); lreschedyes=1; restore(ps); return (OK); } prev=q[prev].qprev; } } } } } restore(ps); return OK; }
int release(int numlocks,int ldes1) { struct lentry *lptr; struct pentry *pptr; int i; pptr=&proctab[currpid]; if (pptr->deleted[ldes1]==1) //check if the locks has been deleted { pptr->deleted[ldes1]==0; pptr->pwaitret=OK; //continue; return (SYSERR); } //if bad lock if(isbadlock(ldes1) || (lptr=&lockarr[ldes1])->lstate==LFREE ||pptr->pwaitret==DELETED) { pptr->pwaitret=OK; return (SYSERR); } if (pptr->pinh != 0) { pptr->pinh=0; //chprio(currpid,pptr->prioh); } if (lptr->lstate==READ) { lptr->holder[currpid]=-1; pptr->lockdesc[ldes1]=-1; if (lptr->r_count>0) //if more readers present in the waiting queue { lptr->r_count--; if (lptr->r_count ==0 && !isEmpty(lptr->lhead)) { } else return OK; } } else //change the holder of the process and of the locks { lptr->holder[currpid]=-1; pptr->lockdesc[ldes1]=-1; } pptr->pinh=0; //check for the inverted priority for(i=0;i<50;i++) { if (pptr->lockdesc[i]==1) { changePriority(i,getlast((&lockarr[i])->ltail)); } } pop_3(lptr->lhead,lptr->ltail,ldes1); //continue; return OK; }