Пример #1
0
/*
 * Since we are modifying the run queue, we _MUST_ set the IPL to high
 * so that no interrupts happen at an inopportune moment.

 * Remember to restore the original IPL before you return from this
 * function. Otherwise, we will not get any interrupts after returning
 * from this function.
 *
 * Using intr_disable/intr_enable would be equally as effective as
 * modifying the IPL in this case. However, in some cases, we may want
 * more fine grained control, making modifying the IPL more
 * suitable. We modify the IPL here for consistency.
 */
void
sched_make_runnable(kthread_t *thr)
{
	uint8_t prev_ipl = intr_getipl();
	intr_setipl(IPL_HIGH);
	
	thr->kt_state = KT_RUN;
	ktqueue_enqueue(&kt_runq, thr);
	
	intr_setipl(prev_ipl);
        /*NOT_YET_IMPLEMENTED("PROCS: sched_make_runnable");*/
}
Пример #2
0
/*
 * Since we are modifying the run queue, we _MUST_ set the IPL to high
 * so that no interrupts happen at an inopportune moment.

 * Remember to restore the original IPL before you return from this
 * function. Otherwise, we will not get any interrupts after returning
 * from this function.
 *
 * Using intr_disable/intr_enable would be equally as effective as
 * modifying the IPL in this case. However, in some cases, we may want
 * more fine grained control, making modifying the IPL more
 * suitable. We modify the IPL here for consistency.
 */
void
sched_make_runnable(kthread_t *thr)
{
	/*----Kernel1:PROCS:sched_make_runnable:Begins---*/
	KASSERT(thr != NULL);
	uint8_t old_ipl = apic_getipl();
	apic_setipl(IPL_HIGH);
	KASSERT(&kt_runq != thr->kt_wchan && "thread already on the runq");
	thr->kt_state = KT_RUN;
	ktqueue_enqueue(&kt_runq,thr);
	apic_setipl(old_ipl);
	/*----Ends----*/	
}
Пример #3
0
/*
 * Similar to sleep on, but the sleep can be cancelled.
 *
 * Don't forget to check the kt_cancelled flag at the correct times.
 *
 * Use the private queue manipulation functions above.
 */
int
sched_cancellable_sleep_on(ktqueue_t *q)
{
	if (curthr->kt_cancelled)
		return -EINTR;
	curthr->kt_state = KT_SLEEP_CANCELLABLE;
	ktqueue_enqueue(q, curthr);
	
	sched_switch();
	
	if (curthr->kt_cancelled)
		return -EINTR;
	return 0;
}
Пример #4
0
/*
 * Since we are modifying the run queue, we _MUST_ set the IPL to high
 * so that no interrupts happen at an inopportune moment.

 * Remember to restore the original IPL before you return from this
 * function. Otherwise, we will not get any interrupts after returning
 * from this function.
 *
 * Using intr_disable/intr_enable would be equally as effective as
 * modifying the IPL in this case. However, in some cases, we may want
 * more fine grained control, making modifying the IPL more
 * suitable. We modify the IPL here for consistency.
 */
void
sched_make_runnable(kthread_t *thr)
{
    KASSERT(&kt_runq != thr->kt_wchan);
    dbg(DBG_PRINT, "(GRADING1A 4.b)\n");
    int oldIPL=intr_getipl();
    intr_setipl(IPL_HIGH);

    thr->kt_state = KT_RUN;
    ktqueue_enqueue(&kt_runq, thr);

    intr_setipl(oldIPL);

    /*NOT_YET_IMPLEMENTED("PROCS: sched_make_runnable"); */
}
Пример #5
0
void
sched_broadcast_on(ktqueue_t *q)
{
       kthread_t *temp;

       while(!list_empty(&(q->tq_list)))
       {
                temp = ktqueue_dequeue(q);
                temp->kt_state = KT_RUN;
                ktqueue_enqueue(&kt_runq, temp);
       }

       sched_queue_init(q);
       return;

}
Пример #6
0
kthread_t *
sched_wakeup_on(ktqueue_t *q)
{
        kthread_t *thr = NULL;
        if(list_empty(&(q->tq_list)))               
                return NULL;
        else
                thr = ktqueue_dequeue(q);
        
        KASSERT((thr->kt_state == KT_SLEEP) || (thr->kt_state == KT_SLEEP_CANCELLABLE));

        thr->kt_state = KT_RUN;
        ktqueue_enqueue(&kt_runq, thr);
        
        return thr;
}
Пример #7
0
/*
 * Similar to sleep on, but the sleep can be cancelled.
 *
 * Don't forget to check the kt_cancelled flag at the correct times.
 *
 * Use the private queue manipulation functions above.
 */
int
sched_cancellable_sleep_on(ktqueue_t *q)
{
        //NOT_YET_IMPLEMENTED("PROCS: sched_cancellable_sleep_on");
        if (curthr->kt_cancelled) {
                return -EINTR;
        }
        ktqueue_enqueue(q, curthr);
        curthr->kt_state = KT_SLEEP_CANCELLABLE;
        sched_switch();

        if (curthr->kt_cancelled) {
                return -EINTR;
        }
        return 0;
}
Пример #8
0
/*
 * Since we are modifying the run queue, we _MUST_ set the IPL to high
 * so that no interrupts happen at an inopportune moment.

 * Remember to restore the original IPL before you return from this
 * function. Otherwise, we will not get any interrupts after returning
 * from this function.
 *
 * Using intr_disable/intr_enable would be equally as effective as
 * modifying the IPL in this case. However, in some cases, we may want
 * more fine grained control, making modifying the IPL more
 * suitable. We modify the IPL here for consistency.
 */
void
sched_make_runnable(kthread_t *thr)
{
        uint8_t oldIPL = intr_getipl(); /* Check what currently running IPL is */
        intr_setipl(IPL_HIGH); /* Block all hardware interrupts */

        /* Add thread to run queue */
        ktqueue_enqueue(&kt_runq, thr);
        /* Make thread runnable (just in case it wasn't already) */
        thr->kt_state = KT_RUN;

        intr_setipl(oldIPL); /* Reset IPL level */
        /* 
        NOT_YET_IMPLEMENTED("PROCS: sched_make_runnable");
        */
}
Пример #9
0
/*
 * Similar to sleep on, but the sleep can be cancelled.
 *
 * Don't forget to check the kt_cancelled flag at the correct times.
 *
 * Use the private queue manipulation functions above.
 */
int
sched_cancellable_sleep_on(ktqueue_t *q)
{
        kthread_t *temp = curthr;
        temp->kt_state = KT_SLEEP_CANCELLABLE;
        
        if(temp->kt_cancelled == 1)
                return -EINTR;
        else
               {
                    ktqueue_enqueue(q, temp);
                    sched_switch();
               } 
        
        return 0;

}
Пример #10
0
/*
 * Updates the thread's state and enqueues it on the given
 * queue. Returns when the thread has been woken up with wakeup_on or
 * broadcast_on.
 *
 * Use the private queue manipulation functions above.
 */
void
sched_sleep_on(ktqueue_t *q)
{
	/*
	enqueue on this
	get off run queue
	context_switch
	*/
	curthr->kt_state = KT_SLEEP;
	ktqueue_enqueue(q, curthr);
	
	/*Why did i do this?
	ktqueue_remove(&kt_runq, curthr);*/
	sched_switch();
	
	
       /* NOT_YET_IMPLEMENTED("PROCS: sched_sleep_on");*/
}
Пример #11
0
/*
 * Similar to sleep on, but the sleep can be cancelled.
 *
 * Don't forget to check the kt_cancelled flag at the correct times.
 *
 * Use the private queue manipulation functions above.
 */
int
sched_cancellable_sleep_on(ktqueue_t *q)
{
    if(curthr->kt_cancelled) {
        dbg(DBG_PRINT, "(GRADING1C 5)\n");
        return -EINTR;
    }

    curthr->kt_state = KT_SLEEP_CANCELLABLE;
    ktqueue_enqueue(q, curthr);
    sched_switch();

    if(curthr->kt_cancelled) {
        dbg(DBG_PRINT, "(GRADING1C 5)\n");
        return -EINTR;
    }
    dbg(DBG_PRINT, "(GRADING1C 3)\n");
    return 0;
    /*
            NOT_YET_IMPLEMENTED("PROCS: sched_cancellable_sleep_on");
            return 0;*/
}
Пример #12
0
/*
 * In this function, you will be modifying the run queue, which can
 * also be modified from an interrupt context. In order for thread
 * contexts and interrupt contexts to play nicely, you need to mask
 * all interrupts before reading or modifying the run queue and
 * re-enable interrupts when you are done. This is analagous to
 * locking a mutex before modifying a data structure shared between
 * threads. Masking interrupts is accomplished by setting the IPL to
 * high.
 *
 * Once you have masked interrupts, you need to remove a thread from
 * the run queue and switch into its context from the currently
 * executing context.
 *
 * If there are no threads on the run queue (assuming you do not have
 * any bugs), then all kernel threads are waiting for an interrupt
 * (for example, when reading from a block device, a kernel thread
 * will wait while the block device seeks). You will need to re-enable
 * interrupts and wait for one to occur in the hopes that a thread
 * gets put on the run queue from the interrupt context.
 *
 * The proper way to do this is with the intr_wait call. See
 * interrupt.h for more details on intr_wait.
 *
 * Note: When waiting for an interrupt, don't forget to modify the
 * IPL. If the IPL of the currently executing thread masks the
 * interrupt you are waiting for, the interrupt will never happen, and
 * your run queue will remain empty. This is very subtle, but
 * _EXTREMELY_ important.
 *
 * Note: Don't forget to set curproc and curthr. When sched_switch
 * returns, a different thread should be executing than the thread
 * which was executing when sched_switch was called.
 *
 * Note: The IPL is process specific.
 */
void
sched_switch(void)
{
        kthread_t *next_thr;

        /* Somewhere in here: set interrupts to protect run queue
            intr_setipl(IPL_LOW) or IPL_HIGH, in include/main/interrupt.h
        */
        uint8_t oldIPL = intr_getipl(); /* Check what currently running IPL is */
        intr_setipl(IPL_HIGH); /* Block all hardware interrupts */

        /* Enqueue requesting thread on run queue if still runnable
            (dead threads become unschedulable)
        */
        if (curthr->kt_state == KT_RUN) ktqueue_enqueue(&kt_runq, curthr);

        /* Pick a runnable thread. Take someone off the run queue. */

        /* If no threads on run queue, re-enable interrupts and wait for one to occur */
        if (sched_queue_empty(&kt_runq)) {
          intr_wait();
          /* Once this returns, there should be a process in the run queue */
        }

        /* Remove a thread from the run queue */
        next_thr = ktqueue_dequeue(&kt_runq);

        /* Manage curproc, curthr */
        kthread_t *old_thr = curthr;
        proc_t *old_proc = curproc;

        curthr = next_thr;
        curproc = next_thr->kt_proc;

        /* Switch context from old context to new context */
        context_switch(&old_thr->kt_ctx, &curthr->kt_ctx);

        /* NOT_YET_IMPLEMENTED("PROCS: sched_switch"); */
}
Пример #13
0
void
sched_make_runnable(kthread_t *thr)
{
    
    KASSERT(&kt_runq != thr->kt_wchan);

    static int i = 1;
        if(thr->kt_proc->p_pid == 0 && i == 1)
            {
                sched_queue_init(&kt_runq);
                i = i+1;
            }

        dbg(DBG_THR,"ADDING PROCESS: %s, ON RUN_QUEUE\n", thr->kt_proc->p_comm);

        uint8_t curr_intr_level = apic_getipl();
        apic_setipl(IPL_HIGH);

        thr->kt_state = KT_RUN;
        ktqueue_enqueue(&kt_runq,thr);

        apic_setipl(curr_intr_level);

}