Пример #1
0
enum pm_state_e pm_checkstate(int domain)
{
  FAR struct pm_domain_s *pdom;
  clock_t now, elapsed;
  irqstate_t flags;
  int index;

  /* Get a convenience pointer to minimize all of the indexing */

  DEBUGASSERT(domain >= 0 && domain < CONFIG_PM_NDOMAINS);
  pdom = &g_pmglobals.domain[domain];

  /* Check for the end of the current time slice.  This must be performed
   * with interrupts disabled so that it does not conflict with the similar
   * logic in pm_activity().
   */

  flags = enter_critical_section();

  /* Check the elapsed time.  In periods of low activity, time slicing is
   * controlled by IDLE loop polling; in periods of higher activity, time
   * slicing is controlled by driver activity.  In either case, the duration
   * of the time slice is only approximate; during times of heavy activity,
   * time slices may be become longer and the activity level may be over-
   * estimated.
   */

  now     = clock_systimer();
  elapsed = now - pdom->stime;
  if (elapsed >= TIME_SLICE_TICKS)
    {
      int16_t accum;

      /* Sample the count, reset the time and count, and assess the PM
       * state.  This is an atomic operation because interrupts are
       * still disabled.
       */

      accum       = pdom->accum;
      pdom->stime = now;
      pdom->accum = 0;

      (void)pm_update(domain, accum, elapsed);
    }

  /* Consider the possible power state lock here */

  for (index = 0; index < pdom->recommended; index++)
    {
      if (pdom->stay[index] != 0)
        {
          pdom->recommended = index;
          break;
        }
    }

  leave_critical_section(flags);

  return pdom->recommended;
}
Пример #2
0
enum pm_state_e pm_checkstate(void)
{
  uint32_t now;
  irqstate_t flags;

  /* Check for the end of the current time slice.  This must be performed
   * with interrupts disabled so that it does not conflict with the similar
   * logic in pm_activity().
   */

  flags = irqsave();

  /* Check the elapsed time.  In periods of low activity, time slicing is
   * controlled by IDLE loop polling; in periods of higher activity, time
   * slicing is controlled by driver activity.  In either case, the duration
   * of the time slice is only approximate; during times of heavy activity,
   * time slices may be become longer and the activity level may be over-
   * estimated.
   */

   now = clock_systimer();
   if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
    {
       int16_t accum;

       /* Sample the count, reset the time and count, and assess the PM
        * state.  This is an atomic operation because interrupts are
        * still disabled.
        */

       accum             = g_pmglobals.accum;
       g_pmglobals.stime = now;
       g_pmglobals.accum = 0;

       /* Reassessing the PM state may require some computation.  However,
        * the work will actually be performed on a worker thread at a user-
        * controlled priority.
        */

       (void)pm_update(accum);
    }
  irqrestore(flags);

  /* Return the recommended state.  Assuming that we are called from the
   * IDLE thread at the lowest priority level, any updates scheduled on the
   * worker thread above should have already been peformed and the recommended
   * state should be current:
   */

  return g_pmglobals.recommended;
}
Пример #3
0
void pm_activity(int priority)
{
  uint32_t now;
  uint32_t accum;
  irqstate_t flags;

  /* Just increment the activity count in the current time slice. The priority
   * is simply the number of counts that are added.
   */

  if (priority > 0)
    {
      /* Add the priority to the accumulated counts in a critical section. */

      flags = irqsave();
      accum = (uint32_t)g_pmglobals.accum + priority;

      /* Make sure that we do not overflow the underlying uint16_t representation */

      if (accum > INT16_MAX)
        {
          accum = INT16_MAX;
        }

      /* Save the updated count */

      g_pmglobals.accum = (int16_t)accum;

      /* Check the elapsed time.  In periods of low activity, time slicing is
       * controlled by IDLE loop polling; in periods of higher activity, time
       * slicing is controlled by driver activity.  In either case, the duration
       * of the time slice is only approximate; during times of heavy activity,
       * time slices may be become longer and the activity level may be over-
       * estimated.
       */

      now = clock_systimer();
      if (now - g_pmglobals.stime >= TIME_SLICE_TICKS)
        {
          int16_t tmp;

          /* Sample the count, reset the time and count, and assess the PM
           * state.  This is an atomic operation because interrupts are
           * still disabled.
           */

          tmp               = g_pmglobals.accum;
          g_pmglobals.stime = now;
          g_pmglobals.accum = 0;

          /* Reassessing the PM state may require some computation.  However,
           * the work will actually be performed on a worker thread at a user-
           * controlled priority.
           */

          (void)pm_update(tmp);
        }

      irqrestore(flags);
    }
}