Files
rtems/cpukit/libmisc/cpuuse/cpuusagereport.c
Joel Sherrill 5fa5185324 2008-06-06 Joel Sherrill <joel.sherrill@OARcorp.com>
* libcsupport/src/__times.c, libmisc/cpuuse/cpuusagereport.c,
	libmisc/cpuuse/cpuusagereset.c, libmisc/monitor/mon-task.c,
	rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c,
	rtems/src/ratemonperiod.c, score/include/rtems/score/thread.h,
	score/src/threaddispatch.c, score/src/threadinitialize.c,
	score/src/threadtickletimeslice.c: Add typedefs for cpu usage and
	period timing statistics. Also renamed related variables and
	structure members so they are the same whether you are using
	nanosecond (e.g. struct timespec) or ticks (e.g. uint32_t)
	granularity. This lays the groundwork for future cleanup.
2008-06-06 15:44:11 +00:00

178 lines
4.8 KiB
C

/*
* CPU Usage Reporter
*
* COPYRIGHT (c) 1989-2007
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <rtems.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <inttypes.h>
#include <rtems/cpuuse.h>
#include <rtems/bspIo.h>
#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
#include <rtems/score/timespec.h>
#endif
#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
extern struct timespec CPU_usage_Uptime_at_last_reset;
#else
extern uint32_t CPU_usage_Ticks_at_last_reset;
#endif
/*PAGE
*
* rtems_cpu_usage_report
*/
void rtems_cpu_usage_report_with_plugin(
void *context,
rtems_printk_plugin_t print
)
{
uint32_t i;
uint32_t api_index;
Thread_Control *the_thread;
Objects_Information *information;
char name[13];
uint32_t ival, fval;
#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
struct timespec uptime, total, ran;
#else
uint32_t total_units = 0;
#endif
if ( !print )
return;
/*
* When not using nanosecond CPU usage resolution, we have to count
* the number of "ticks" we gave credit for to give the user a rough
* guideline as to what each number means proportionally.
*/
#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
_TOD_Get_uptime( &uptime );
_Timespec_Subtract( &CPU_usage_Uptime_at_last_reset, &uptime, &total );
#else
for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
if ( !_Objects_Information_table[ api_index ] )
continue;
information = _Objects_Information_table[ api_index ][ 1 ];
if ( information ) {
for ( i=1 ; i <= information->maximum ; i++ ) {
the_thread = (Thread_Control *)information->local_table[ i ];
if ( the_thread )
total_units += the_thread->cpu_time_used;
}
}
}
#endif
(*print)( context, "CPU Usage by thread\n"
#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
" ID NAME SECONDS PERCENT\n"
#else
" ID NAME TICKS PERCENT\n"
#endif
);
for ( api_index = 1 ;
api_index <= OBJECTS_APIS_LAST ;
api_index++ ) {
if ( !_Objects_Information_table[ api_index ] )
continue;
information = _Objects_Information_table[ api_index ][ 1 ];
if ( information ) {
for ( i=1 ; i <= information->maximum ; i++ ) {
the_thread = (Thread_Control *)information->local_table[ i ];
if ( !the_thread )
continue;
rtems_object_get_name( the_thread->Object.id, sizeof(name), name );
(*print)(
context,
"0x%08" PRIx32 " %-12s ",
the_thread->Object.id,
name
);
#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
/*
* If this is the currently executing thread, account for time
* since the last context switch.
*/
ran = the_thread->cpu_time_used;
if ( _Thread_Executing->Object.id == the_thread->Object.id ) {
struct timespec used;
_Timespec_Subtract(
&_Thread_Time_of_last_context_switch, &uptime, &used
);
_Timespec_Add_to( &ran, &used );
};
_Timespec_Divide( &ran, &total, &ival, &fval );
/*
* Print the information
*/
(*print)( context,
"%3" PRId32 ".%06" PRId32 " %3" PRId32 ".%03" PRId32 "\n",
ran.tv_sec, ran.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND,
ival, fval
);
#else
ival = (total_units) ?
the_thread->cpu_time_used * 10000 / total_units : 0;
fval = ival % 100;
ival /= 100;
(*print)( context,
"%8" PRId32 " %3" PRId32 ".%02" PRId32"\n",
the_thread->cpu_time_used,
ival,
fval
);
#endif
}
}
}
#ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
(*print)( context, "Time since last CPU Usage reset %" PRId32
".%06" PRId32 " seconds\n",
total.tv_sec,
total.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND
);
#else
(*print)( context,
"Ticks since last reset = %" PRId32 "\n",
_Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset
);
(*print)( context, "Total Units = %" PRId32 "\n", total_units );
#endif
}
void rtems_cpu_usage_report( void )
{
rtems_cpu_usage_report_with_plugin( NULL, printk_plugin );
}