sched/scheduler.c
/**************************************************************************
 * Name:
 *  sched_preempt_task
 *
 * Description:
 *  Move the task from running to waiting list and activate the next task.
 *
 * Input Arguments:
 *  to_preempt_tcb - the task to be preempted
 *
 * Assumptions:
 *  The task received as argument should not be in the RUNNING state.
 *
 ************************************************************************/


Move the task from running to waiting list and activate the next task.

Input Arguments:
to_preempt_tcb - the task to be preempted

The task received as argument should not be in the RUNNING state.
Move the task from running to waiting list and activate the next task . Input Arguments : to_preempt_tcb - the task to be preempted The task received as argument should not be in the RUNNING state .
void sched_preempt_task(tcb_t *to_preempt_tcb)
{
  tcb_t *new_tcb = NULL;
  struct list_head *current, *temp;
  irq_state_t irq_state = cpu_disableint();
  list_for_each_safe(current, temp, &g_tcb_waiting_list)
  {
    new_tcb = container_of(current, tcb_t, next_tcb);
    if (new_tcb && new_tcb->t_state == READY)
    {
      list_del(current);
      list_add(current, &g_tcb_list);
    }
  }
  assert(to_preempt_tcb->t_state != RUNNING);
  list_del(&to_preempt_tcb->next_tcb);
  if (to_preempt_tcb->t_state == READY)
  {
    SCHED_DEBUG_INFO("%s preempted\n", to_preempt_tcb->task_name);
    list_add_tail(&to_preempt_tcb->next_tcb, &g_tcb_list);
  }
  else if (to_preempt_tcb->t_state == WAITING_FOR_SEM ||
           to_preempt_tcb->t_state == HALTED)
  {
    list_add(&to_preempt_tcb->next_tcb, &g_tcb_waiting_list);
  }
  volatile int is_context_restored = cpu_savecontext(to_preempt_tcb->mcu_context);
  if (is_context_restored)
  {
    SCHED_DEBUG_INFO("%s restored context\n", to_preempt_tcb->task_name);
    return;
  }
  SCHED_DEBUG_INFO("%s saved context\n", to_preempt_tcb->task_name);
  list_for_each_entry(new_tcb, &g_tcb_list, next_tcb)
  {
    assert(new_tcb->t_state == READY);
    new_tcb->t_state = RUNNING;
    g_current_tcb = &new_tcb->next_tcb;
    SCHED_DEBUG_INFO("%s now run\n", new_tcb->task_name);
    cpu_enableint(irq_state);
    cpu_restorecontext(new_tcb->mcu_context);
  }
  cpu_enableint(irq_state);
}
void sched_preempt_task ( tcb_t * to_preempt_tcb ) { tcb_t * new_tcb = NULL ; struct list_head * current , * temp ; irq_state_t irq_state = cpu_disableint ( ) ; list_for_each_safe ( current , temp , & g_tcb_waiting_list ) { new_tcb = container_of ( current , tcb_t , next_tcb ) ; if ( new_tcb && new_tcb -> t_state == READY ) { list_del ( current ) ; list_add ( current , & g_tcb_list ) ; } } assert ( to_preempt_tcb -> t_state != RUNNING ) ; list_del ( & to_preempt_tcb -> next_tcb ) ; if ( to_preempt_tcb -> t_state == READY ) { SCHED_DEBUG_INFO ( " \n " , to_preempt_tcb -> task_name ) ; list_add_tail ( & to_preempt_tcb -> next_tcb , & g_tcb_list ) ; } else if ( to_preempt_tcb -> t_state == WAITING_FOR_SEM || to_preempt_tcb -> t_state == HALTED ) { list_add ( & to_preempt_tcb -> next_tcb , & g_tcb_waiting_list ) ; } volatile int is_context_restored = cpu_savecontext ( to_preempt_tcb -> mcu_context ) ; if ( is_context_restored ) { SCHED_DEBUG_INFO ( " \n " , to_preempt_tcb -> task_name ) ; return ; } SCHED_DEBUG_INFO ( " \n " , to_preempt_tcb -> task_name ) ; list_for_each_entry ( new_tcb , & g_tcb_list , next_tcb ) { assert ( new_tcb -> t_state == READY ) ; new_tcb -> t_state = RUNNING ; g_current_tcb = & new_tcb -> next_tcb ; SCHED_DEBUG_INFO ( " \n " , new_tcb -> task_name ) ; cpu_enableint ( irq_state ) ; cpu_restorecontext ( new_tcb -> mcu_context ) ; } cpu_enableint ( irq_state ) ; }
Name:
  sched_preempt_task
Name : sched_preempt_task
/* Is there any task in the waiting list that needs to be added back
   * in the ready list ?
   */ /* If the task to preempt is not in :
   * READY, WAITING_FOR_SEM or HALTED
   * something is wrong.
   */ /* Delete the task from the current list */ /* The task slot expired we need to scheduler a new task.
     * Place the task at the end of the list.
     */ /* The task is preempted because it was blocked by a semaphore
      * or it was done executing the entry point and it needs to be halted.
      */ /* Save the current context in the task that needs to be preempted */ /* All the tasks from this list should be in the READY state */ /* Great, we found a task that it is the ready state.
     * Move the task in the runing state and restore its context.
     */ /* Re-enable the interrupts */ /* Switch the context to the new task */