Пример #1
0
/**
 * @brief Signals the occurrence of an event on all applicable devices.
 * This function should be called on timer interrupts to determine that
 * the interrupt corresponds to the event frequency of a device. If the
 * interrupt corresponded to the interrupt frequency of a device, this
 * function should ensure that the task is made ready to run
 */
void dev_update(unsigned long millis __attribute__((unused)))
{
	disable_interrupts();
	int i = 0;
	bool_e flag = FALSE;
	for (i = 0; i < NUM_DEVICES; i++) {
	        if (devices[i].next_match <= millis) {
        		devices[i].next_match += dev_freq[i];
            		tcb_t* sleep_queue = devices[i].sleep_q;

            		if (sleep_queue != 0) {
				flag = TRUE;
               			 while(sleep_queue != 0) {
				    	runqueue_add(sleep_queue,sleep_queue->native_prio);
				   	sleep_queue = sleep_queue->sleep_queue;
				 }
              			 devices[i].sleep_q = 0;

           		 }
		}
	}

	if(flag == TRUE)
		 dispatch_save();
	enable_interrupts();

}
Пример #2
0
/**
 * @brief Signals the occurrence of an event on all applicable devices. 
 * This function should be called on timer interrupts to determine that 
 * the interrupt corresponds to the event frequency of a device. If the 
 * interrupt corresponded to the interrupt frequency of a device, this 
 * function should ensure that the task is made ready to run 
 */
void dev_update(unsigned long millis)
{
    disable_interrupts();

    int i;
    for (i = 0; i < NUM_DEVICES; i++) {
        // if a devices task match the time the add all sleep takes to the run queue
        if (devices[i].next_match <= millis) {
            while (devices[i].sleep_queue) {
                //print_sleep_queue();
                tcb_t* head = devices[i].sleep_queue;
                runqueue_add(head, head->cur_prio);
                // go to the next sleep task
                devices[i].sleep_queue = head->sleep_queue;
                // set the current task's next to null
                head->sleep_queue = NULL;
            }

            // update next match
            devices[i].next_match += dev_freq[i];
        }
    }

    // do context switch after the devices state are updated
    dispatch_save();
}
Пример #3
0
/* c_irq_handler - custom irq handler called by assembly irq handler 
   after state has been saved/restored appropriately.
	Parameters: None 
*/
void c_irq_handler(){
	unsigned stamp;
	mmio_t oscr = (mmio_t)OSCR;
	mmio_t ossr = (mmio_t)OSSR;
	mmio_t osmr0 = (mmio_t)OSMR_0;
	if(*ossr & OSSR_M0){
		//keep global time by checking if oscr has overlapped start_time
		if(lastoscr<start_time && *oscr>=start_time){
			rollovercount++;
		}
		lastoscr = *oscr;
		dotime(&stamp);

		//set next interrupt for 10ms later
		*osmr0 = *oscr + OSTMR_FREQ/100;

		//unset interrupts
		*ossr |= OSSR_M0;

		//update devices and switch to highest prio task
		dev_update((unsigned long)stamp);
		dispatch_save();
	}
	if(*ossr & OSSR_M1)
		*ossr |= OSSR_M1;
	if(*ossr & OSSR_M2)
		*ossr |= OSSR_M2;
	if(*ossr & OSSR_M3)
		*ossr |= OSSR_M3;
}
Пример #4
0
void irq_handler(void) {
	disable_interrupts();

	irq_time ++;
	dev_update(irq_time);
	reg_set(OSTMR_OSSR_ADDR, OSTMR_OSSR_M0);
	reg_write(OSTMR_OSCR_ADDR, TIMER_CLEAR);

	/* Wait for timer to reset */
	while(((volatile unsigned)reg_read(INT_ICPR_ADDR) >>INT_OSTMR_0) & 0x1);

	dispatch_save();
}
Пример #5
0
int mutex_lock_syscall(int mutex  __attribute__((unused)))
{
	//printf("mutex_lock, %d\n", mutex);
	// if mutex invalid
	if (mutex >= OS_NUM_MUTEX || gtMutex[mutex].bAvailable == 1) {
		return EINVAL;
	}
	
	if (gtMutex[mutex].pHolding_Tcb == get_cur_tcb())
		return EDEADLOCK;
	
	// if blocked
	if (gtMutex[mutex].bLock == 1) {
		tcb_t** tmp = &(gtMutex[mutex].pSleep_queue);
		while (1) {
			if (*tmp == (void *)0) {
				gtMutex[mutex].pSleep_queue = runqueue_remove(get_cur_prio());
				break;
			}
			if((*tmp)->sleep_queue == (void *)0) {
				(*tmp)->sleep_queue = runqueue_remove(get_cur_prio());
				((*tmp)->sleep_queue) = (void *)0;
				break;
			}
			tmp = (tcb_t **)&((*tmp)->sleep_queue);
		}
		//printf("blocked!!!!!!!!!\n");
		//printf("mutex holding tcb: %d\n", (gtMutex[mutex].pHolding_Tcb)->native_prio);
		dispatch_save();
	}

	// if not blocked		
	gtMutex[mutex].bLock = 1;
	gtMutex[mutex].pHolding_Tcb = get_cur_tcb();
	
	//printf("mutex holding tcb: %d\n", (gtMutex[mutex].pHolding_Tcb)->native_prio);
	//printf("mutex sleep queue\n");
	/*
	tcb_t* tmp = gtMutex[mutex].pSleep_queue;
	while (tmp != (void *)0) {
		printf("sleep %d\n", tmp->native_prio);
		tmp = tmp->sleep_queue;
	}
	*/
	return 0;

}
Пример #6
0
/**
 * @brief Signals the occurrence of an event on all applicable devices.
 * This function should be called on timer interrupts to determine that
 * the interrupt corresponds to the event frequency of a device. If the
 * interrupt corresponded to the interrupt frequency of a device, this
 * function should ensure that the task is made ready to run
 */
void dev_update(unsigned long millis )
{
	disable_interrupts();
	//check each device for an event
	int i;
	int have_some = 0;
	//if(debug_enabled ==1) puts("dev_update::checking \n");
	for( i = 0; i < NUM_DEVICES - 1; i++)
	{
		if( millis >= devices[i].next_match)
		{
			if(debug_enabled ==1) printf("dev_update::waking up %d\n",i);
			//wake up device!
			//make tasks ready to run

			//for each sleeper
			tcb_t* sleepy = devices[i].sleep_queue;
			tcb_t* next;
			while( sleepy != 0)
			{
				//WAKE UP SLEEPY
				runqueue_add(sleepy, sleepy->cur_prio);

				if(debug_enabled == 1)printf("dev_update...dev = %d:::woke up (prio)= %d::next =  %x\n", i, (unsigned)sleepy->cur_prio, (unsigned)sleepy->sleep_queue);
				//another sleeper?
				next = sleepy->sleep_queue;
				sleepy->sleep_queue = 0;
				sleepy = next;

				//set flag that there is a reason to update
				have_some = 1;

			}

			//set next match point in millis
			devices[i].next_match += dev_freq[i];
		}
	}
	//re-evaluate our priorities, if we have a reason to
	if(have_some == 1 ) dispatch_save();
	enable_interrupts();
}
Пример #7
0
int mutex_unlock(int mutex  __attribute__((unused)))
{
    tcb_t* temp;

    disable_interrupts();

    // if the provided mutex identifier if invalid
    if(mutex > OS_NUM_MUTEX
            || gtMutex[mutex].bAvailable == TRUE) {
        
        enable_interrupts();
        return -EINVAL;
    
    } 

    if(gtMutex[mutex].pHolding_Tcb != get_cur_tcb()) {
        
        // if the urrent task does not hold the mutex
        enable_interrupts();
        return -EPERM;
    
    } else {
        temp = gtMutex[mutex].pHolding_Tcb;
        temp->holds_lock = 0;
        #ifdef HLP
            temp->cur_prio = temp->native_prio;
        #endif // HLP

        // if there is no element in sleep queue
        if(gtMutex[mutex].pSleep_queue == 0) {
            gtMutex[mutex].bLock = 0;
            gtMutex[mutex].pHolding_Tcb = 0;
            enable_interrupts();
            return 0;
        } else {

            // if the sleep queue have tasks waiting for the mutex

            // first tcb in sleeping queue gets the mutex
            gtMutex[mutex].pHolding_Tcb = gtMutex[mutex].pSleep_queue;
            // move the head of mutex sleeping queue to next
            gtMutex[mutex].pSleep_queue = gtMutex[mutex].pSleep_queue->sleep_queue;
            // clear the sleeping queue of the holding tcb
            gtMutex[mutex].pHolding_Tcb->sleep_queue = 0;

            gtMutex[mutex].pHolding_Tcb->holds_lock = 1;
            #ifdef HLP
                gtMutex[mutex].pHolding_Tcb->cur_prio = 0;
            #endif // HLP

            // put the wake up task into runqueue
            runqueue_add(gtMutex[mutex].pHolding_Tcb, gtMutex[mutex].pHolding_Tcb->cur_prio);
        
            // check the wake up task's priority and current running task's priority
            if(highest_prio() < get_cur_prio()) {
                // switch to the highest task
                dispatch_save();

            } else {
                // stay the same
                enable_interrupts();
                return 0;
            }
        }
    }

    // the function will not get here
	return 1; 
}