Example #1
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[firstkey(sleepq)].qkey;
	}
	resched();
	return;
}
Example #2
0
interrupt clkhandler(void)
{
    /* Reset the timer to fire again */
    clkupdate(platform.clkfreq / CLKTICKS_PER_SEC);

    /* Another clock tick passes. */
    clkticks++;

    /* Update global second counter. */
    if (clkticks >= CLKTICKS_PER_SEC)
    {
        clktime++;
        clkticks = 0;
    }

    /* If sleepq is not empty, decrement first key.   */
    /* If key reaches zero, call wakeup.              */
    if (nonempty(sleepq) && (--firstkey(sleepq) <= 0))
    {
        wakeup(); // This no longer does a resched() call since we need to
                  // clear our interrupts before doing a resched()
    }

    #ifdef FLUKE_ARM
    /* Acknowledge and clear the interrupt */
    timer0->int_clr = 1;
    irq_handled();
    #endif

    resched();
}
Example #3
0
/**
 * Wakeup and ready all threads that have no more time to sleep
 */
void wakeup(void)
{
    while (nonempty(sleepq) && (firstkey(sleepq) <= 0))
    {
        ready(dequeue(sleepq), RESCHED_NO);
    }
}
Example #4
0
/**
 * Reschedule processor to highest priority ready thread.
 * Upon entry, thrcurrent gives current thread id.
 * Threadtab[thrcurrent].pstate gives correct NEXT state
 * for current thread if other than THRREADY.
 * @return OK when the thread is context switched back
 */
int resched(void)
{
    uchar asid;                 /* address space identifier */
    struct thrent *throld;      /* old thread entry */
    struct thrent *thrnew;      /* new thread entry */

    if (resdefer > 0)
    {                           /* if deferred, increase count & return */
        resdefer++;
        return (OK);
    }

    throld = &thrtab[thrcurrent];

    throld->intmask = disable();

    if (THRCURR == throld->state)
    {
        if (nonempty(readylist) && (throld->prio > firstkey(readylist)))
        {
            restore(throld->intmask);
            return OK;
        }
        throld->state = THRREADY;
        insert(thrcurrent, readylist, throld->prio);
    }

    /* get highest priority thread from ready list */
    thrcurrent = dequeue(readylist);
    thrnew = &thrtab[thrcurrent];
    thrnew->state = THRCURR;

    /* change address space identifier to thread id */
    asid = thrcurrent & 0xff;
#if 0
  // XXX Fix this later?
  asm("mtc0 %0, $10": :"r"(asid));
#endif

    restore(thrnew->intmask);
    ctxsw(&throld->stkptr, &thrnew->stkptr);

    /* old thread returns here when resumed */
    restore(throld->intmask);
    return OK;
}
Example #5
0
/*------------------------------------------------------------------------
 *  resched_lab1  -  Reschedule processor to highest priority eligible process
 *------------------------------------------------------------------------
 */
void	resched_lab1(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->prstate == PR_CURR) {  /* Process remains eligible */
		if (ptold->prprio > firstkey(readylist)) {
			return;
		}

		/* Old process will no longer remain current */

		ptold->prstate = PR_READY;
		insert(currpid, readylist, ptold->prprio);
	}

	/* Force context switch to highest priority ready process */

	currpid = dequeue(readylist);
	ptnew = &proctab[currpid];
	ptnew->prstate = PR_CURR;
	preempt = QUANTUM;		/* Reset time slice for process	*/
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	// LAB 4Q3: Invoke the handleCallback
	handleCallback();

	/* Old process returns here when resumed */

	return;
}
Example #6
0
interrupt clkhandler(void)
{
    //DEBUG
    //kprintf("Timer went off\n");

    /* Reset the timer to fire again */
    clkupdate(platform.clkfreq / CLKTICKS_PER_SEC);

    /* Another clock tick passes. */
    clkticks++;
    msclkticks++;

    /* Update global second counter. */
    if (clkticks >= CLKTICKS_PER_SEC)
    {
        clktime++;
        clkticks = 0;
    }

    /* Update global countdown for round robien reschedule */
    if (msclkticks >= (CLKTICKS_PER_SEC/1000))
    {
	rescheduleMSLeft -= 1;
	msclkticks = 0;
    }

    /* If sleepq is not empty, decrement first key.   */
    /* If key reaches zero, call wakeup.              */
    if (nonempty(sleepq) && (--firstkey(sleepq) <= 0))
    {
        wakeup(); // This no longer does a resched() call since we need to
                  // clear our interrupts before doing a resched()
    }

    /* Acknowledge and clear the interrupt */
    timer0->int_clr = 1;
    irq_handled();

    resched();
}
Example #7
0
/*------------------------------------------------------------------------
 *  resched_lab2  -  fair scheduler from lab2, need to set lab2flag according to specs
 *  				 given in lab2 documentation on 503 course website.
 *------------------------------------------------------------------------
 */
void resched_lab2(void)
{
	uint32 currTime = clktimemsec;
	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;
	}


	uint32 addToTotalTime =0;
	/* Point to process table entry for the current (old) process */
	ptold = &proctab[currpid];
	//Update the total processing time for context switched out process
	// Handle the case where the counter overflows then get the absolute value of difference
	addToTotalTime = (currTime)-(ptold->prctxswintime);

	// if the old process id is not of null user then update its total CPU time
	// else ignore this step because prcpumsec of null user is already set to max to
	// force it to only execute if no other process is ready
	if(currpid != 0)
		ptold->prcpumsec = ptold->prcpumsec +  addToTotalTime;

	// totest switches the key for the readylist queue to be tested based on the lab we are running.
	// For the lab3, its the priority of the process
	// and for lab 4 and 5 it's the prcpumsec, the cpu time given to the process
	int32 totest = ptold->prprio;


	// Here the totest will be set to the negation of prcpumsec
	// because we wan't to maintain using the insert function that
	// inserts elements in decreasing order. By this negation of prcpumsec would
	// cause the element with the least prcpumsec to be the first to be dequeud at the head.
	// Hence, we are followin the rules of the dynamic priority scheduling algorithm
	if(lab2flag == 4 || lab2flag == 5)
		totest =-(int32)ptold->prcpumsec;

	if (ptold->prstate == PR_CURR) {  /* Process remains eligible */
		if (totest > firstkey(readylist)) {
				ptold->prctxswintime = currTime;
				if(lab2flag ==5)
					reward_ready_waiting();
				return;
			}

			/* Old process will no longer remain current */


			if(lab2flag == 5)
				reward_ready_waiting();
			ptold->prstate = PR_READY;
			// The only other place an insert happens is at the ready method
			// even there we have chosen to implement a similar strategy of choosing the value
			// of key based on the lab that we are dealing with. That is, either to insert
			// based on priority or the negation of the prcpumsec spent.
			insert(currpid, readylist, totest);
			currpid = dequeue(readylist);
		}
	else
	{
		//even if the process is in sleep state and calling a reschedule
		// we must reward the other processes
		// of course, as soon as the process that is dequeued is removed its key value
		// would also
		if(lab2flag ==5)
			reward_ready_waiting();
		currpid = dequeue(readylist);
	}
	/* Force context switch to highest priority ready process */
	ptnew = &proctab[currpid];
	ptnew->prstate = PR_CURR;
	preempt = QUANTUM;		/* Reset time slice for process	*/
	//Update the context switch-in time for new process
	ptnew->prctxswintime = currTime;
	ctxsw(&ptold->prstkptr, &ptnew->prstkptr);

	// LAB 4Q3: Invoke the handleCallback
	handleCallback();
	/* Old process returns here when resumed */
	return;

}