Beispiel #1
0
/*------------------------------------------------------------------------
 *  copyqueue  -  Move the internal queue linked list of pids from one
 *  queue to another by pointing the internal list at the other queue's
 *  first and last id's.  Any contents in the destination queue will be
 *  dequeued first, and the source queue head and tail will be linked to
 *  make the source queue empty.
 *------------------------------------------------------------------------
 */
void copyqueue(qid16 srcq, qid16 destq) {

	while(!isempty(destq)) dequeue(destq);

	qid16 firstid = firstid(srcq);
	qid16 lastid = lastid(srcq);
	firstid(srcq) = queuetail(srcq);
	lastid(srcq) = queuehead(srcq);

	firstid(destq) = firstid;
	queuetab[firstid].qprev = queuehead(destq);
	lastid(destq) = lastid;
	queuetab[lastid].qnext = queuetail(destq);
}
/*------------------------------------------------------------------------
 *  insert  -  Insert a process into a queue in descending key order
 *------------------------------------------------------------------------
 */
status	insert_real(
	  pid32		pid,		/* ID of process to insert	*/
	  qid16		q,		/* ID of queue to use		*/
	  double		key             /* Key for the inserted process	*/
	)
{
	int16	curr;			/* Runs through items in a queue*/
	int16	prev;			/* Holds previous node index	*/

	if (isbadqid(q) || isbadpid(pid)) {
		return SYSERR;
	}

	curr = firstid(q);
	while (queuetab[curr].real_qkey >= key) {
		curr = queuetab[curr].qnext;
	}

	/* Insert process between curr node and previous node */

	prev = queuetab[curr].qprev;	/* Get index of previous node	*/
	queuetab[pid].qnext = curr;
	queuetab[pid].qprev = prev;
	queuetab[pid].real_qkey = key;
	queuetab[prev].qnext = pid;
	queuetab[curr].qprev = pid;
	return OK;
}
/*------------------------------------------------------------------------
 *  strtclk  --  take the clock out of defer mode
 *------------------------------------------------------------------------
 */
strtclk()
{
	STATWORD ps;    
	int makeup;
	int next;

	disable(ps);
	if ( defclk<=0 || --defclk>0 ) {
		restore(ps);
		return;
	}
	makeup = clkdiff;
	preempt -= makeup;
	clkdiff = 0;
	if ( slnempty ) {
		for (next=firstid(clockq) ; 
		    next < NPROC && q[next].qkey < makeup ;
		    next=q[next].qnext) {
			makeup -= q[next].qkey;
			q[next].qkey = 0;
		}
		if (next < NPROC)
			q[next].qkey -= makeup;
		wakeup();
	}
	if ( preempt <= 0 )
	        resched();
	restore(ps);
}
/*-----------------------------------------------------------------------
 * clkhandler - high level clock interrupt handler
 *-----------------------------------------------------------------------
 */
void	clkhandler()
{

	static uint32 count1000 = 1000;	/* variable to count 1000ms */
	volatile struct am335x_timer1ms *csrptr = 0x44E31000;
					/* Pointer to timer CSR	    */
	int32	slot;			/* Slot in ARP cache	*/

	/* If there is no interrupt, return */

	if((csrptr->tisr & AM335X_TIMER1MS_TISR_OVF_IT_FLAG) == 0) {
		return;
	}

	/* Acknowledge the interrupt */

	csrptr->tisr = AM335X_TIMER1MS_TISR_OVF_IT_FLAG;

	/* Decrement 1000ms counter */

	count1000--;

	/* After 1 sec, increment clktime */

	if(count1000 == 0) {
		clktime++;
		count1000 = 1000;

		/* code to check ARP entry */
		for (slot=0; slot < ARP_SIZ; slot++) {
			if ((clktime - arpcache[slot].clktime) > 300) {
				arpcache[slot].arstate = AR_FREE;
			}
		}
	}

	/* check if sleep queue is empty */

	if(!isempty(sleepq)) {

		/* sleepq nonempty, decrement the key of */
		/* topmost process on sleepq		 */

		if((--queuetab[firstid(sleepq)].qkey) == 0) {

			wakeup();
		}
	}

	/* Decrement the preemption counter */
	/* Reschedule if necessary	    */

	if((--preempt) == 0) {
		preempt = QUANTUM;
		resched();
	}
}
Beispiel #5
0
pid32	getfirst(qid16 qid)
{
	if(isbadqid(qid))
	{
		return EMPTY;
	}
	
	return getitem(firstid(qid));
}
Beispiel #6
0
/*------------------------------------------------------------------------
 * clkhandler - high level clock interrupt handler
 *------------------------------------------------------------------------
 */
void	clkhandler()
{
	static	uint32	count1000 = 1000;	/* Count to 1000 ms	*/

	/* Decrement the ms counter, and see if a second has passed */

	struct procent *prptr = &proctab[currpid]; //pointer to the table entry for current process
	clktimefine++; //incrementing the clktimefine
	
	if(prptr->alrmfunc != NULL && prptr->mysigalrmtime >= 0) {	// check if the function isn't null and the saved sigalrmtime in the process table isn't negative
		if(clktimefine >= prptr->mysigalrmtime){	//if the current clktimefine is greater than the saved sigalrmtime 
			prptr->alrmfunc();	//call the function pointing to callback function
			prptr->alrmfunc = NULL;	//set the ptr to function as NULL, so that the process can't activate another callback function
		}
	}

	else if(prptr->xcpufunc != NULL){	// check if the function isn't null 
		if(prptr->prcpuused >= prptr->optarg){	//check if the cpuused by the process exceeds the optional argument 
			prptr->xcpufunc();	//call the function pointing to callback function
			prptr->xcpufunc = NULL;	//reset the the function ptr to NULL so that the process can't activate another callback function
		}
	}

	if((--count1000) <= 0) {

		/* One second has passed, so increment seconds count */

		clktime++;

		/* Reset the local ms counter for the next second */

		count1000 = 1000;
	}

	/* Handle sleeping processes if any exist */

	if(!isempty(sleepq)) {

		/* Decrement the delay for the first process on the	*/
		/*   sleep queue, and awaken if the count reaches zero	*/

		if((--queuetab[firstid(sleepq)].qkey) <= 0) {
			wakeup();
		}
	}

	/* Decrement the preemption counter, and reschedule when the */
	/*   remaining time reaches zero			     */

	if((--preempt) <= 0) {
		preempt = QUANTUM;
		resched();
	}
}
Beispiel #7
0
/*------------------------------------------------------------------------
 *  wakeup  -  Called by clock interrupt handler to awaken processes
 *------------------------------------------------------------------------
 */
void	wakeup(void)
{
	/* Awaken all processes that have no more time to sleep */

	while (nonempty(sleepq) && (firstkey(sleepq) <= 0)) {
		ready(dequeue(sleepq), RESCHED_NO);
	}
	
	if ( (slnonempty = nonempty(sleepq)) == TRUE ) {
		sltop = &queuetab[firstid(sleepq)].qkey;
	}
	resched();
	return;
}
Beispiel #8
0
/*------------------------------------------------------------------------
 *  reward_ready_waiting  -  this method promotes all the processes on the readylist by giving them each an
 *  						 increment of 6ms to their keys. We do this so that a process that has been waiting for a long time
 *  						 would at least get a chance to execute if it had executed the cpu for a long time.
 *							 All processes in this ready list are processes that were not selected in this run of resched
 *							 as the next process to execute, despite being ready. Hence, this loss of opportunity is
 *							 defined as waiting in our context.
 *
 *------------------------------------------------------------------------
 */
void reward_ready_waiting()
{
	qid16	curr;			/* Runs through items in a queue*/
	qid16	prev;			/* Holds previous node index	*/

	struct procent * prptr;
	curr = firstid(readylist);
	while (curr != queuetail(readylist)) {
			prptr = &proctab[curr];
			// don't promote prnull process
			if(curr!=0)
				queuetab[curr].qkey +=6;
			curr = queuetab[curr].qnext;
		}
}
Beispiel #9
0
/* insert a process into a queue in descending key order */
status insert(pid32 pid, qid16 q, int32 key) {
  int16 curr, prev;
  if (isbadqid(q) || isbadpid(pid)) {
    return SYSERR;
  }
  curr = firstid(q);
  while (queuetab[curr].qkey >= key) {
    curr = queuetab[curr].qnext;
  }
  prev = queuetab[curr].qprev;
  queuetab[pid].qnext = curr;
  queuetab[pid].qprev = prev;
  queuetab[pid].qkey = key;
  queuetab[prev].qnext = pid;
  queuetab[curr].qprev = pid;
  return OK;
}
Beispiel #10
0
/*------------------------------------------------------------------------
 *  unsleep  -  Remove a process from the sleep queue prematurely by
 *			adjusting the delay of successive processes
 *------------------------------------------------------------------------
 */
syscall	unsleep(
	  pid32		pid		/* ID of process to remove	*/
        )
{
	intmask	mask;			/* saved interrupt mask		*/
        struct	procent	*prptr;		/* ptr to process' table entry	*/

        pid32	pidnext;		/* ID of process on sleep queue	*/
					/* that follows the process that*/
					/* is being removed		*/

	mask = disable();

	if (isbadpid(pid)) {
		restore(mask);
		return SYSERR;
	}

	/* Verify that candidate process is on the sleep queue */

	prptr = &proctab[pid];
	if ((prptr->prstate!=PR_SLEEP) && (prptr->prstate!=PR_RECTIM)) {
		restore(mask);
		return SYSERR;
	}

	/* Increment delay of next process if such a process exists */

	pidnext = queuetab[pid].qnext;
	if (pidnext < NPROC) {
		queuetab[pidnext].qkey += queuetab[pid].qkey;
	}

	if ( nonempty(sleepq) ) {
		sltop = &queuetab[firstid(sleepq)].qkey;
		slnonempty = TRUE;
	} else {
		slnonempty = FALSE;
	}
	getitem(pid);			/* unlink process from queue */
	restore(mask);
	return OK;
}
/*------------------------------------------------------------------------
 * clkhandler - high level clock interrupt handler
 *------------------------------------------------------------------------
 */
void	clkhandler()
{
	static	uint32	count1000 = 1000;	/* Count to 1000 ms	*/

	/* Decrement the ms counter, and see if a second has passed */
	
	myglobalclock++;

	if((--count1000) <= 0) {

		/* One second has passed, so increment seconds count */

		clktime++;

		/* Reset the local ms counter for the next second */

		count1000 = 1000;
	}

	/* Handle sleeping processes if any exist */

	if(!isempty(sleepq)) {

		/* Decrement the delay for the first process on the	*/
		/*   sleep queue, and awaken if the count reaches zero	*/

		if((--queuetab[firstid(sleepq)].qkey) <= 0) {
			wakeup();
		}
	}

	/* Decrement the preemption counter, and reschedule when the */
	/*   remaining time reaches zero			     */

	if((--preempt) <= 0) {
		preempt = QUANTUM;
		resched();
	}
}
Beispiel #12
0
void	clkhandler()
{
	static uint32 count1000 = 1000;	/* variable to count 1000ms */

	volatile struct am335x_timer1ms *csrptr = 0x44E31000;
					/* Pointer to timer CSR	    */

	/* If there is no interrupt, return */

	if((csrptr->tisr & AM335X_TIMER1MS_TISR_OVF_IT_FLAG) == 0) {
		return;
	}

	LOG2(DEBUG_VERBOSE,DEBUG_SCHEDULER,
			"\nClkInt: a clock tick is being handled, ms was %d, secs were %d\n", 1000-count1000,clktime);

	/* Acknowledge the interrupt */

	csrptr->tisr = AM335X_TIMER1MS_TISR_OVF_IT_FLAG;

	/* Decrement 1000ms counter */

	count1000--;

	/* After 1 sec, increment clktime */

	if(count1000 == 0) {
		clktime++;
		count1000 = 1000;

		/* if EV_DTIMER env var is turned on then run the associated debugging output on a psuedo timer */
		if(envtab[EV_DTIMER].val && !(clktime%(envtab[EV_DTIMER].val))) {
			dtimer();
		}
	}

	/* if still NULL, update the pointer to the millisecond tracker so millisecond timestamps can be generated */
	if(!clktimems) {
		clktimems = &count1000;
	}

	/* check if sleep queue is empty */

	if(!isempty(sleepq)) {

		/* sleepq nonempty, decrement the key of */
		/* topmost process on sleepq		 */

		if((--queuetab[firstid(sleepq)].qkey) == 0) {

			wakeup();
		}
	}

	/* Decrement the preemption counter */
	/* Reschedule if necessary	    */

	if((--preempt) == 0) {
		LOG2(DEBUG_VERBOSE,DEBUG_SCHEDULER,"\nClkInt: preemption time \n");
		preempt = QUANTUM;
		resched();
	}
}
/*------------------------------------------------------------------------
 *  resched  -  Reschedule processor to highest priority eligible process
 *------------------------------------------------------------------------
 */
void	resched(void)		/* Assumes interrupts are disabled	*/
{
	struct procent *ptold;	/* Ptr to table entry for old process	*/
	struct procent *ptnew;	/* Ptr to table entry for new process	*/

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

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

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

	ptold = &proctab[currpid];

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

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

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


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

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

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


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

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



	/* Old process returns here when resumed */

	return;
}
/*-----------------------------------------------------------------------
 * clkhandler - high level clock interrupt handler
 *-----------------------------------------------------------------------
 */
void	clkhandler()
{
	struct	arpentry *arptr;		/* variable to access arpcache */
	static uint32 arpcount1000 = 1000;	/* variable to count 1000ms for arpcache */

	static uint32 count1000 = 1000;	/* variable to count 1000ms */
	volatile struct am335x_timer1ms *csrptr = 0x44E31000;
					/* Pointer to timer CSR	    */

	/* Checks arpcache entry time */
	int i;
	arpcount1000--;
	if(arpcount1000 == 0)
	{
		for (i = 0; i < ARP_SIZ; i++) {
			arptr = &arpcache[i];
			if(arptr->arclk >= 300) {
				arptr->arstate = AR_FREE;
				arptr->arclk = 0;
			}
			else
				arptr->arclk++;
		}
		arpcount1000 = 1000;
	}

	/* If there is no interrupt, return */

	if((csrptr->tisr & AM335X_TIMER1MS_TISR_OVF_IT_FLAG) == 0) {
		return;
	}

	/* Acknowledge the interrupt */

	csrptr->tisr = AM335X_TIMER1MS_TISR_OVF_IT_FLAG;

	/* Decrement 1000ms counter */

	count1000--;

	/* After 1 sec, increment clktime */

	if(count1000 == 0) {
		clktime++;
		count1000 = 1000;
	}

	/* check if sleep queue is empty */

	if(!isempty(sleepq)) {

		/* sleepq nonempty, decrement the key of */
		/* topmost process on sleepq		 */

		if((--queuetab[firstid(sleepq)].qkey) == 0) {

			wakeup();
		}
	}

	/* Decrement the preemption counter */
	/* Reschedule if necessary	    */

	if((--preempt) == 0) {
		preempt = QUANTUM;
		resched();
	}
}