Пример #1
0
/**
 * @brief Context switch to the highest priority task while saving off the 
 * current task state.
 *
 * This function needs to be externally synchronized.
 * We could be switching from the idle task.  The priority searcher has been tuned
 * to return IDLE_PRIO for a completely empty run_queue case.
 */
void dispatch_save(void)
{
	if(cur_tcb->cur_prio == HIGHEST_PRIO)
		return;

	tcb_t *dest, *temp;
	temp = cur_tcb;
	uint8_t hp = highest_prio();

	/* If the idle task is he only next high prio task
	   that means we are already running idle task */
	if(hp == IDLE_PRIO)
		dest = cur_tcb;
	else
		dest = runqueue_remove(hp);

	/* Set cur_tcb to the task that we are about to run */
	cur_tcb = dest;

	/* Set the cur_kstack var of the task that we are about to run */
	cur_kstack = (int)dest->kstack_high;
	
	/* Add the task that we just switched from back to the queue */
	runqueue_add(temp, temp->cur_prio);

	ctx_switch_full(&(dest->context), &(temp->context));
}
Пример #2
0
/**
 * @brief Context switch to the highest priority task while saving off the 
 * current task state.
 *
 * This function needs to beexternally synchronized.
 * We could be switching from the idle task.  The priority searcher has been tuned
 * to return IDLE_PRIO for a completely empty run_queue case.
 */
void dispatch_save(void)
{
	uint8_t next_prio;
	tcb_t *next_tcb, *saved_cur_tcb;

//	printf("inside dispatch save\n");

//	printf("added cur_tcb %u %p to run queue\n", cur_tcb->cur_prio, cur_tcb);
	next_prio = highest_prio();
	/*
	 * add the current task to the run queue...
	 */
	runqueue_add(cur_tcb, cur_tcb->cur_prio);
//	printf("next_prio is %u\n", next_prio);
		

	next_tcb = runqueue_remove(next_prio);
//	printf(" d save: removed next_tcb %u %p from run queue\n", next_tcb->cur_prio, next_tcb);
//	print_run_queue();
	saved_cur_tcb = cur_tcb;
	cur_tcb = next_tcb;
#if 0
	printf("before calling ctx sw full, cur->context is %p\n", &(saved_cur_tcb->context));
	printf("hexdump of cur->context is\n");
	hexdump(&saved_cur_tcb->context, 160);
	printf("before calling ctx sw full, next->context is %p\n", &(next_tcb->context));
	printf("hexdump of next->context is\n");
	hexdump(&next_tcb->context, 160);
#endif
//	disable_interrupts();
	ctx_switch_full((volatile void *)(&(next_tcb->context)),
					(volatile void *)(&(saved_cur_tcb->context)));
//	while(1);
}
Пример #3
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * and save the current task but don't mark is runnable.
 *
 * There is always an idle task to switch to.
 */
void dispatch_sleep(void)
{
	uint8_t next_prio;
	tcb_t *next_tcb, *saved_cur_tcb;

//	printf("inside dispatch sleep\n");
	next_prio = highest_prio();
//	printf("next_prio is %u\n", next_prio);
		
	next_tcb = runqueue_remove(next_prio);
//	printf("d sleep: removed next_tcb %u %p from run queue\n", next_tcb->cur_prio, next_tcb);
//	print_run_queue();
	saved_cur_tcb = cur_tcb;
	cur_tcb = next_tcb;
//	printf("before calling ctx sw full, next->context->sp is %p\n", next_tcb->context.sp);
//	printf("before calling ctx sw full, cur->context->sp is %p\n", saved_cur_tcb->context.sp);
//	printf("in dispatch sleep, sp is %u\n", get_kernel_sp());
//	hexdump(get_kernel_sp(), 200);
//	disable_interrupts();
//	printf("inside dispatch sleep hexdump of cur->context is\n");
//	hexdump(&saved_cur_tcb->context, 160);
	ctx_switch_full((volatile void *)(&(next_tcb->context)),
					(volatile void *)(&(saved_cur_tcb->context)));
//	while(1);
	
}
Пример #4
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * don't save the current task state.
 *
 * There is always an idle task to switch to.
 */
void dispatch_nosave(void)
{
	/* Get the highest priority */
	uint8_t prio = highest_prio();
	/* Get the corresponding task */
	tcb_t *tcb = runqueue_remove(prio);
	/* Call ctx_switch_half */
	cur_tcb = tcb;
	ctx_switch_half(&(cur_tcb -> context));
}
Пример #5
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * don't save the current task state.
 *
 * There is always an idle task to switch to.
 */
void dispatch_nosave(void)
{
  uint8_t prio = highest_prio();
  tcb_t *next_task = runqueue_remove(prio);

  //Enqueue current task
  runqueue_add(cur_tcb, cur_tcb->cur_prio);
  cur_tcb = next_task;
  ctx_switch_half(&(next_task->context));

}
Пример #6
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * and save the current task but don't mark is runnable.
 *
 * There is always an idle task to switch to.
 */
void dispatch_sleep(void)
{
  uint8_t prio = highest_prio();
  //printf("Highest prio is %d\n",prio);
  tcb_t *next_task = runqueue_remove(prio);
  
  tcb_t *tmp_task = cur_tcb;
  
  cur_tcb = next_task;
  
  ctx_switch_full(&(next_task->context), &(tmp_task->context));
	
}
Пример #7
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * and save the current task but don't mark is runnable.
 *
 * There is always an idle task to switch to.
 */
void dispatch_sleep(void)
{
	/* Similar implementation as dispatch_save but let the current task sleep, and don't 
	 * add it into the runqueue
	 */
	uint8_t prio = highest_prio();
	tcb_t *new_task;

	new_task = runqueue_remove(prio);

	sched_context_t *cur_ctx = &(cur_tcb -> context);
	cur_tcb = new_task;
	ctx_switch_full(&(new_task -> context), cur_ctx);

}
Пример #8
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * don't save the current task state.
 *
 * There is always an idle task to switch to.
 */
void dispatch_nosave(void)
{
	/*
	   This executes the first task
	   This ends up being the initial high prio task
	 */

	/* Set cur_tcb to the task that we are about to run */
	cur_tcb = runqueue_remove(highest_prio());

	/* Set the cur_kstack var of the task that we are about to run */
	cur_kstack = (int)cur_tcb->kstack_high;

	ctx_switch_half(&(cur_tcb->context));
}
Пример #9
0
/**
 * @brief Context switch to the highest priority task while saving off the 
 * current task state.
 *
 * This function needs to be externally synchronized.
 * We could be switching from the idle task.  The priority searcher has been tuned
 * to return IDLE_PRIO for a completely empty run_queue case.
 */
void dispatch_save(void)
{
	tcb_t *new_task;
	tcb_t *old_task = cur_tcb;
	uint8_t prio = highest_prio();
	/* If the current task is not the highest priority task */
	if (old_task -> cur_prio > prio) {

		new_task = runqueue_remove(prio);
		sched_context_t *old_ctx = &(old_task -> context);
		runqueue_add(old_task, old_task -> cur_prio);
		cur_tcb = new_task;
		/* !!! ctx_switch_full has not yet implemented */
		ctx_switch_full(&(new_task -> context), old_ctx);
	}
}
Пример #10
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * don't save the current task state.
 *
 * There is always an idle task to switch to.
 */
void dispatch_nosave(void)
{
	uint8_t next_prio;
	tcb_t *next_tcb;
//	printf("inside dispatch no save\n");
	next_prio = highest_prio();
//	printf("next_prio is %u\n", next_prio);
		
	/*
	 * manage the run queue...
	 */
	next_tcb = runqueue_remove(next_prio);
//	printf("d nosave: removed next_tcb %u %p from run queue\n", next_tcb->cur_prio, next_tcb);
//	print_run_queue();
	cur_tcb = next_tcb;
//	printf("before calling ctx sw half, context->sp is %p\n", next_tcb->context.sp);
	ctx_switch_half((volatile void *)(&(next_tcb->context)));
}
Пример #11
0
/**
 * @brief Context switch to the highest priority task that is not this task -- 
 * and save the current task but don't mark is runnable.
 *
 * There is always an idle task to switch to.
 */
void dispatch_sleep(void)
{
	tcb_t *dest, *temp;
	temp = cur_tcb;
	uint8_t cp = get_cur_prio(); /* i.e task that was just put to sleep */
	uint8_t hp = highest_prio(); /* next task to run */

	/* Run idle task if there are no other */
	if(cp == hp)
		dest = runqueue_remove(IDLE_PRIO);
	else
		dest = runqueue_remove(hp);

	/* Set cur_tcb to the task that we are about to run */
	cur_tcb = dest;
	
	/* Set the cur_kstack var of the task that we are about to run */
	cur_kstack = (int)dest->kstack_high;
	
	ctx_switch_full(&(dest->context), &(temp->context));
}
Пример #12
0
int mutex_lock(int mutex  __attribute__((unused)))
{ 
  // Get the current task
  tcb_t* cur_tcb = get_cur_tcb();
  mutex_t* cur_mutex = &(gtMutex[mutex]);
 
  // Check if mutex is in range
  if((mutex <0) || (mutex >= OS_NUM_MUTEX)) return EINVAL;

  // Check if deadlock error
  if(cur_tcb == gtMutex[mutex].pHolding_Tcb) return EDEADLOCK;

  // Disable interrupts
  disable_interrupts();

  // If mutex is locked (blocked), wait until freed up by sleeping
  while(cur_mutex->bLock == 1){
    // Enable interrupts
    enable_interrupts();
    
    dispatch_sleep();
    
    //Disable interrupts
    disable_interrupts();
  }
  
  // Set holding Tcb to current task, set bLock = TRUE, give curr\ent task highest priority, set cur tasks's "holds_lock" val to 1
  cur_mutex->bLock = 1;
    cur_mutex->pHolding_Tcb = cur_tcb;
    cur_tcb->cur_prio = highest_prio();
    cur_tcb->holds_lock = 1;

    // Enable Interrupts
    enable_interrupts();

    return 0;
}
Пример #13
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; 
}