📄 ixperfprofaccxcycle.c
字号:
/*** IxPerfProfAccXcycle.c* * @par * IXP400 SW Release version 2.1 * * -- Copyright Notice -- * * @par * Copyright (c) 2001-2005, Intel Corporation. * All rights reserved. * * @par * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of the Intel Corporation nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * * @par * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * * @par * -- End of Copyright Notice --** C file for Xcycle for the Perf Prof component (IxPerfProfAcc)** -- Description --* The Xcycle tool provides a measurement of available cycles during high* load versus measurement taken during zero or minimum load.** The user needs to first perform a calibration during zero or minimum load.* A measurement of time (in APB clock cycles ) needed to perform a known* amount of CPU work is taken. This measurement is known as the* baseline. During baselining, the task that performs* the work is put into highest priority and interrupts* are disabled for that period. The time needed to perform this amount of* CPU work is expect to be shortest possible.** After calibration, users can then load program that they like to profile* into XScale. As the programs run in steady state, the Xcycle measurement* tool can be started. During measurement, this tool simply creates a* task of lowest priority possible.* User can choose up to IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS* measurements to run. Each measurement will perform the same amount of* CPU work as the baseline process. It is assumed that the CPU cycles given* to this lowest priority task are leftover from other processes.* Naturally, the time needed for each measurement will be more than the* baseline. The percentage utilization is simply taken as the ratio of* baseline vs time for each measurement in percentage.** The results will be return in average, minimum and maximum utilization* for the measurements.***/#include "IxPerfProfAccXcycle_p.h"#include "IxPerfProfAcc_p.h"#include "IxOsal.h"#ifdef __linuxapp/* * Linux app specific include files */#include "hwprbk.h" /* Driver to access APB timer */#include <sys/types.h>#include <sys/ioctl.h>#include <pthread.h>#include <stdio.h>/* * If not Linux App */#else/* * Include tasklib.h in VxWorks to silence warning. * Note. tasklib.h is included in IxOsal.h. */#ifdef __vxworks#include <taskLib.h>#endif#endif /* ifdef __linuxapp *//* * Static variables defined here *//* Flag to send stop signal to measurement */static BOOL ixPerfProfAccXcycleStopMeasurement = TRUE ;/* Flag to indicate if measurement is in progress */static BOOL ixPerfProfAccXcycleMeasurementInProgress = FALSE;/* Record number of measurements */static UINT32 ixPerfProfAccTotalMeasurementMade = 0 ;/* Results storage */static IxPerfProfAccXcycleMeasuredResults ixPerfProfAccXcycleResults [IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS] ;/* Baseline value */static UINT32 ixPerfProfAccXcycleCurrentBaseline = 0 ;/* Remember number of loops per time slice */static UINT32 ixNumLoopPerTimeSlice = 0 ;#ifdef __linuxapp/* * The Xcycle tools need to run on Linux Application space because it needs * to create user threads. In order to the APB timer, a driver needs to be * installed. The driver hwprb.o is required for this purpose. */static int iFileHwprb = 0 ;/* thread Id for Xcycle Start and Stop operation */static pthread_t xcycleThreadId; #elif defined (__vxworks)/* thread Id for Xcycle Start and Stop operation */ IxOsalThread xcycleThreadId;#endifINLINE UINT32ixPerfProfAccXcycleApbTimerGet (void){#ifdef __linuxapp UINT32 timerVal; if(ioctl(iFileHwprb, HWPRB_GET_TIMER_TICKS, &timerVal) != HWPRB_RET_OK) { /* * Problem with driver encountered. * Terminate the application and print error. */ printf ("\nHardware driver error. Cannot access APB timer !\n"); exit(0); } return timerVal;#else return (*((volatile unsigned long *)IX_OSAL_IXP400_OSTS_PHYS_BASE));#endif} /* end of ixPerfProfAccXcycleApbTimerGet() */INLINE voidixPerfProfAccXcycleLoopIter (UINT32 numLoop){ /* * This will take approximately 2 cycles per loop */ register int temp=numLoop; while (temp > 0 ) { temp--; }} /* end of ixPerfProfAccXcycleLoopIter() */voidixPerfProfAccXcycleNumPeriodRun (UINT32 numMeasurementsRequested){ UINT32 i = 0, /* temporary variable */ j = 0, /* temporary variable */ temp = 0, /* temporary variable */ startTime = 0, /* record time in the begining */ stopTime = 0, /* record time in the end */ totalMeasurementMade = 0 ; /* total runs made */ ixPerfProfAccTotalMeasurementMade = 0 ; /* * This for-loop will run continuously if (numMeasurementsRequested==0). * Otherwise, if will run until (i == numMeasurementsRequested ). * The loop will also terminate if ixPerfProfAccXcycleStopMeasurement * is TRUE. */ for (i = 0 ; (i < numMeasurementsRequested)||( 0 == numMeasurementsRequested); i++ ) { /* * Take the initial reading of timer */ startTime = ixPerfProfAccXcycleApbTimerGet (); /* * Perform IX_PERFPROF_ACC_XCYCLE_TIME_SLICES_PER_SEC times of * ixPerfProfAccXcycleLoopIter(ixNumLoopPerTimeSlice). This * should take ~1 sec if load is low. * If load is high, measurement may take longer but will terminate * if more than IX_PERFPROF_ACC_XCYCLE_MAX_TIME_IN_ONE_MEASUREMENT * seconds has passed. */ for (j = 0; IX_PERFPROF_ACC_XCYCLE_TIME_SLICES_PER_SEC > j; j++) { temp = ixNumLoopPerTimeSlice; ixPerfProfAccXcycleLoopIter(temp); stopTime = ixPerfProfAccXcycleApbTimerGet (); /* * Break out if it takes more than * IX_PERFPROF_ACC_XCYCLE_MAX_TIME_IN_ONE_MEASUREMENT sec for * one measurement (one i loop is one measurement ). * This prevent the thread from * taking too long to complete each measurements. Total number * of time slices (one j loop is equal to one time slice ) * will be less than IX_PERFPROF_ACC_XCYCLE_TIME_SLICES_PER_SEC * for this particular measurement. */ if ((stopTime - startTime)> (IX_PERFPROF_ACC_XCYCLE_MAX_TIME_IN_ONE_MEASUREMENT * IX_PERFPROF_ACC_XCYCLE_TIMER_FREQ)) break; } /* end for (j) loop */ /* * Collect run data for measurement number i */ ixPerfProfAccXcycleResults[i].xcycleCountStart = startTime; ixPerfProfAccXcycleResults[i].xcycleCountStop = stopTime; ixPerfProfAccXcycleResults[i].totalTimeSlices = j; /* * Stop measurement on user requests */ if (TRUE==ixPerfProfAccXcycleStopMeasurement) break; /* * Rotate back index i to 0 when it reaches maximum * This only applies to case where numMeasurementsRequested is 0 * Set totalMeasurementMade to possible maximum. */ if ((IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS <= i) && (0==numMeasurementsRequested)) { totalMeasurementMade = IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS; i = 0 ; } } /* end for i loop */ /* * If totalMeasurementMade is zero, then we have not reached * maximum of IX_PERFPROF_ACC_XCYCLE_MAX_NUM_OF_MEASUREMENTS. * Record totalMeasurementMade. */ if (0 == totalMeasurementMade ) { totalMeasurementMade = i; } /* * Record total number of measurements performed for computation of * result later. */ ixPerfProfAccTotalMeasurementMade = totalMeasurementMade ; /* * Set ixPerfProfAccXcycleStopMeasurement flag to TRUE so that * user trying to stop it gets a warning. */ ixPerfProfAccXcycleStopMeasurement = TRUE; /* * Set ixPerfProfAccXcycleMeasurementInProgress flag to FALSE. * This allows new measurement to be taken or baseline to be re-run. */ ixPerfProfAccXcycleMeasurementInProgress = FALSE ; /* * Unlock. Allow other utilities to run */ ixPerfProfAccUnlock();} /* end of ixPerfProfAccXcycleNumPeriodRun() */PUBLIC IxPerfProfAccStatusixPerfProfAccXcycleBaselineRun( UINT32 *numBaselineCycle){ int i, priority ; /* task priority. Value is OS dependent */ UINT32 interruptLockKey; UINT32 temp, startTime, /* used to store start time */ stopTime, /* used to store stop time */ duration; /* difference between stop and start time */#ifdef __vxworks IxOsalThread threadId; IX_STATUS result;#endif /*error check the parameter*/ if (NULL == numBaselineCycle) { /* report the error */ IX_PERFPROF_ACC_LOG( IX_OSAL_LOG_LVL_ERROR, IX_OSAL_LOG_DEV_STDERR, "ixPerfProfAccXcycleBaselineRun - numBaselineCycle is invalid\n", 0, 0, 0, 0, 0, 0); /* return error */ return IX_PERFPROF_ACC_STATUS_FAIL; } if (IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS == ixPerfProfAccLock()) { return IX_PERFPROF_ACC_STATUS_ANOTHER_UTIL_IN_PROGRESS; } /* * If the tool is running, then do not allow baselining to progress */ if (ixPerfProfAccXcycleMeasurementInProgress) { ixPerfProfAccUnlock(); return IX_PERFPROF_ACC_STATUS_XCYCLE_MEASUREMENT_IN_PROGRESS; } /* * Find out how many loops is needed to to complete * 1/IX_PERFPROF_ACC_XCYCLE_TIME_SLICES_PER_SEC seconds */ ixNumLoopPerTimeSlice= ixPerfProfAccXcycleComputeLoopsPerSlice(); /* * Disable interrupts so that no ISR can run. We get all the CPU * cycles. */ interruptLockKey = ixOsalIrqLock();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -