Beispiel #1
0
/*------------------------------------------------------------------------
 * 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);
}
Beispiel #3
0
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);
}
Beispiel #5
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;
}
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;
}