bool sched_removereadytorun(FAR _TCB *rtcb)
{
  bool ret = false;

  /* Check if the TCB to be removed is at the head of the ready
   * to run list.  In this case, we are removing the currently
   * active task.
   */

  if (!rtcb->blink)
    {
      /* There must always be at least one task in the list (the idle task) */

      ASSERT(rtcb->flink != NULL);

      /* Inform the instrumentation layer that we are switching tasks */

      sched_note_switch(rtcb, rtcb->flink);

      rtcb->flink->task_state = TSTATE_TASK_RUNNING;
      ret = true;
    }

  /* Remove the TCB from the ready-to-run list */

  dq_rem((FAR dq_entry_t*)rtcb, (dq_queue_t*)&g_readytorun);

  rtcb->task_state = TSTATE_TASK_INVALID;
  return ret;
}
bool sched_removereadytorun(FAR struct tcb_s *rtcb)
{
  FAR struct tcb_s *ntcb = NULL;
  bool ret = false;

  /* Check if the TCB to be removed is at the head of the ready to run list.
   * In this case, we are removing the currently active task.
   */

  if (!rtcb->blink)
    {
      /* There must always be at least one task in the list (the idle task) */

      ntcb = (FAR struct tcb_s *)rtcb->flink;
      DEBUGASSERT(ntcb != NULL);

      /* Inform the instrumentation layer that we are switching tasks */

      sched_note_switch(rtcb, ntcb);
      ntcb->task_state = TSTATE_TASK_RUNNING;
      ret = true;
    }

  /* Remove the TCB from the ready-to-run list */

  dq_rem((FAR dq_entry_t *)rtcb, (FAR dq_queue_t *)&g_readytorun);

  /* Since the TCB is not in any list, it is now invalid */

  rtcb->task_state = TSTATE_TASK_INVALID;
  return ret;
}
bool sched_addreadytorun(FAR _TCB *btcb)
{
  FAR _TCB *rtcb = (FAR _TCB*)g_readytorun.head;
  bool ret;

  /* Check if pre-emption is disabled for the current running task and if
   * the new ready-to-run task  would cause the current running task to be
   * preempted.
   */

  if (rtcb->lockcount && rtcb->sched_priority < btcb->sched_priority)
    {
      /* Yes.  Preemption would occur!  Add the new ready-to-run task to the
       * g_pendingtasks task list for now.
       */

      sched_addprioritized(btcb, (FAR dq_queue_t*)&g_pendingtasks);
      btcb->task_state = TSTATE_TASK_PENDING;
      ret = false;
    }

  /* Otherwise, add the new task to the g_readytorun task list */

  else if (sched_addprioritized(btcb, (FAR dq_queue_t*)&g_readytorun))
    {
      /* Information the instrumentation logic that we are switching tasks */

      sched_note_switch(rtcb, btcb);

      /* The new btcb was added at the head of the g_readytorun list.  It
       * is now to new active task!
       */

      ASSERT(!rtcb->lockcount && btcb->flink != NULL);

      btcb->task_state = TSTATE_TASK_RUNNING;
      btcb->flink->task_state = TSTATE_TASK_READYTORUN;
      ret = true;
    }
  else
    {
      /* The new btcb was added in the middle of the g_readytorun list */

      btcb->task_state = TSTATE_TASK_READYTORUN;
      ret = false;
    }

  return ret;
}
Example #4
0
bool sched_mergepending(void)
{
  FAR struct tcb_s *pndtcb;
  FAR struct tcb_s *pndnext;
  FAR struct tcb_s *rtrtcb;
  FAR struct tcb_s *rtrprev;
  bool ret = false;

  /* Initialize the inner search loop */

  rtrtcb = (FAR struct tcb_s*)g_readytorun.head;

  /* Process every TCB in the g_pendingtasks list */

  for (pndtcb = (FAR struct tcb_s*)g_pendingtasks.head; pndtcb; pndtcb = pndnext)
    {
      pndnext = pndtcb->flink;

      /* Search the g_readytorun list to find the location to insert the 
       * new pndtcb. Each is list is maintained in ascending sched_priority
       * order.
       */

      for (;
           (rtrtcb && pndtcb->sched_priority <= rtrtcb->sched_priority);
           rtrtcb = rtrtcb->flink);

      /* Add the pndtcb to the spot found in the list.  Check if the
       * pndtcb goes at the ends of the g_readytorun list. This would be
       * error condition since the idle test must always be at the end of
       * the g_readytorun list!
       */

      if (!rtrtcb)
        {
          PANIC(OSERR_NOIDLETASK);
        }
      else
        {
          /* The pndtcb goes just before rtrtcb */

          rtrprev = rtrtcb->blink;
          if (!rtrprev)
            {
              /* Special case: Inserting pndtcb at the head of the list */
              /* Inform the instrumentation layer that we are switching tasks */

              sched_note_switch(rtrtcb, pndtcb);

              /* Then insert at the head of the list */

              pndtcb->flink      = rtrtcb;
              pndtcb->blink      = NULL;
              rtrtcb->blink      = pndtcb;
              g_readytorun.head  = (FAR dq_entry_t*)pndtcb;
              rtrtcb->task_state = TSTATE_TASK_READYTORUN;
              pndtcb->task_state = TSTATE_TASK_RUNNING;
              ret                = true;
            }
          else
            {
              /* Insert in the middle of the list */

              pndtcb->flink      = rtrtcb;
              pndtcb->blink      = rtrprev;
              rtrprev->flink     = pndtcb;
              rtrtcb->blink      = pndtcb;
              pndtcb->task_state = TSTATE_TASK_READYTORUN;
            }
        }

      /* Set up for the next time through */

      rtrtcb = pndtcb;
    }

  /* Mark the input list empty */

  g_pendingtasks.head = NULL;
  g_pendingtasks.tail = NULL;

  return ret;
}