예제 #1
0
uint64_t sim_runtime_ns(void) {
  if (time_scale)
    return (now_ns() - begin) / time_scale;
  return TICKS_TO_US(ticks) * 1000 ;
}
/*
 * sleepStats_logWakeup
 */
void sleepStats_logWakeup(sleepStats_input *statInput)
{
  int64                   wakeupDelta;
  int64                   wakeupAdjust;
  const char              *wakeupReason;
  RPM_master_stats        *rpmStats;
  boolean                 isRPMAssisted = FALSE;
#ifdef SLEEP_ENABLE_AUTO_LPR_PROFILING  
  sleep_fLUT_node         *fLUT         = statInput->fLUT;
#endif  
  
  CORE_VERIFY_PTR(rpmStats = sleepStats_getRpmDataPtr());

  switch(statInput->master_wakeup_reason)
  {
    case SLEEP_STATS_WAKEUP_RPM_SCHEDULED:
    {
      isRPMAssisted = TRUE;
    }

    case SLEEP_STATS_WAKEUP_SA_SCHEDULED:
    {
      wakeupReason = "Timer";
      break;
    }

    case SLEEP_STATS_WAKEUP_RPM_UNSCHEDULED:
    {
      isRPMAssisted = TRUE;
    }

    case SLEEP_STATS_WAKEUP_SA_UNSCHEDULED:
    {
      wakeupReason = "Rude";
      break;
    }

    case SLEEP_STATS_WAKEUP_RPM_UNKNOWN:
    {
      isRPMAssisted = TRUE;
    }

    default:
    {
      wakeupReason = "Unknown";
    }
  }

#ifdef SLEEP_ENABLE_AUTO_LPR_PROFILING
  if((isRPMAssisted == TRUE ||
      SLEEP_STATS_WAKEUP_SA_SCHEDULED == statInput->master_wakeup_reason))
  {
    /* Exit overhead is actual wakeup to first point in master code */
    uint64 exitTime =
      sleepStats_getLprTimeData(SLEEP_STATS_TIME_MSTR_RETURN_TYPE) -
       statInput->actual_wakeup_time;

    l2_lprm PCType = 
      (l2_lprm)sleepStats_getMiscData(SLEEP_STATS_MISC_PC_L2_MODE_TYPE);

    power_collapse_overhead *overhead = &fLUT->dynamic_data.PC_overhead[PCType];

    sleepStats_updateValue(&overhead->exit, exitTime);

    /* Can only compute PC enter overhead if RPM assisted */
    if(isRPMAssisted == TRUE)
    {
      /* Enter overhead is last point in master code to actual shutdown */
      uint64 enterTime = inp64(&rpmStats->shutdown_req) -
        sleepStats_getLprTimeData(SLEEP_STATS_TIME_MSTR_SHUTDOWN_TYPE);

      sleepStats_updateValue(&overhead->enter, enterTime);
    }
  }
#endif

  /* Get inaccuracy in the master wakeup so only the local latency
   * is adjusted later */
  if( statInput->actual_wakeup_time >= statInput->backoff_deadline )
  {
    /* RPM or idle timer woke up the master late */
    wakeupAdjust = (int64)(statInput->actual_wakeup_time - 
                           statInput->backoff_deadline); 
  }
  else
  {
    /* RPM or idle timer woke up the master early */
    wakeupAdjust = -((int64)(statInput->backoff_deadline - 
                             statInput->actual_wakeup_time));
  }
  
  if(statInput->os_overhead.count > 0)
  {
    /* Log OS bringup times */
    sleepLog_printf(SLEEP_LOG_LEVEL_PROFILING, 2 + (3*2),
                    "Warmboot stats (Count: %d) "
                    "(Power collapse: 0x%llx) (Core resume: 0x%llx) "
                    "(Sleep resume: 0x%llx) "
                    "(WB time: %duS)" ,
                    statInput->os_overhead.count,
                    ULOG64_DATA(statInput->os_overhead.sleep_time),
                    ULOG64_DATA(statInput->os_overhead.awake_time),
                    ULOG64_DATA(statInput->os_overhead.sleep_resume),
                    TICKS_TO_US(statInput->os_overhead.sleep_resume - 
                                statInput->os_overhead.awake_time));
  }

  if(isRPMAssisted == TRUE)
  {
    /* Log RPM bringup info */
    sleepLog_printf( SLEEP_LOG_LEVEL_PROFILING, 2 + (3*2),
                     "RPM stats (wakeup_ind: 0x%llx) (bringup_req: 0x%llx) "
                     "(bringup_ack: 0x%llx) (sleep trans time: %d) "
                     "(wake trans time: %d)",
                     ULOG64_DATA(inp64(&rpmStats->wakeup_ind)),
                     ULOG64_DATA(inp64(&rpmStats->bringup_req)),
                     ULOG64_DATA(inp64(&rpmStats->bringup_ack)),
                     rpmStats->last_sleep_transition_duration,
                     rpmStats->last_wake_transition_duration );
  }
  
  /* Log master wakeup */
  sleepLog_QDSSPrintf( SLEEP_LOG_LEVEL_INFO, SLEEP_WAKEUP_NUM_ARGS,
                       SLEEP_WAKEUP_STR, SLEEP_WAKEUP, 
                       wakeupReason, 
                       statInput->master_interrupt,
                       ULOG64_DATA(statInput->actual_wakeup_time),
                       ULOG64_DATA(statInput->backoff_deadline),
                       ULOG64_DATA(wakeupAdjust) ); 

  /* Log late sleep exits */
  if( statInput->sleep_exit_stm > statInput->hard_deadline )
  {
    /* Get difference of sleep exit time to expected exit */
    wakeupDelta = statInput->sleep_exit_stm - statInput->hard_deadline;
    
    sleepLog_printf( SLEEP_LOG_LEVEL_WARNING, 4*2,
                     "WARNING (message: \"Late sleep exit\") "
                     "(Actual: 0x%llx) (Expected: 0x%llx) "
                     "(diff ticks: %lld) (diff us: %lld)",
                     ULOG64_DATA(statInput->sleep_exit_stm), 
                     ULOG64_DATA(statInput->hard_deadline),
                     ULOG64_DATA(wakeupDelta),
                     ULOG64_DATA(TICKS_TO_US(wakeupDelta)));
  }
#ifdef SLEEP_ENABLE_AUTO_SYNTH_BACKOFF_ADJUSTMENT
  else
  {
    /* Early wake ups are negative values */
    wakeupDelta = -(statInput->hard_deadline - statInput->sleep_exit_stm);
  }

  /* Record stats and make any adjustments only for RPM assisted or scheduled
   * stand alone PC modes.
   * Since we don't have an accurate wakeup time for
   * unscheduled standalone mode, we're unable to adjust latencies for that
   * mode*/ 
  if(isRPMAssisted == TRUE ||
     SLEEP_STATS_WAKEUP_SA_SCHEDULED == statInput->master_wakeup_reason )
  {
    sleepStats_adjustSynthmode(statInput, wakeupDelta, wakeupAdjust);
  }

#endif /* SLEEP_ENABLE_AUTO_SYNTH_BACKOFF_ADJUSTMENT */

  return;
}