summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/cpuuse
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2007-05-17 22:46:45 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2007-05-17 22:46:45 +0000
commitc3330a88ee5d674b09dded32ef1ccba26a9c3034 (patch)
treef7f247449fc18bc299ef695c3503f9b7790db97a /cpukit/libmisc/cpuuse
parentAdd .rh clause to extra_arg. (diff)
downloadrtems-c3330a88ee5d674b09dded32ef1ccba26a9c3034.tar.bz2
2007-05-17 Joel Sherrill <joel.sherrill@oarcorp.com>
* ChangeLog, configure.ac, libcsupport/src/__times.c, libmisc/cpuuse/cpuuse.c, libmisc/stackchk/check.c, rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemongetstatus.c, rtems/src/ratemonperiod.c, rtems/src/ratemonreportstatistics.c, rtems/src/ratemonresetall.c, rtems/src/ratemontimeout.c, score/Makefile.am, score/include/rtems/score/thread.h, score/include/rtems/score/timespec.h, score/src/threaddispatch.c, score/src/threadinitialize.c, score/src/threadtickletimeslice.c, score/src/timespecdivide.c: Add nanoseconds granularity to the rate monotonic period statistics and CPU usage statistics. This capability is enabled by default although may be conditionally disabled by the user. It could be too much overhead on small targets but it does not appear to be bad in early testing. Its impact on code size has not been evaluated either. It is possible that both forms of statistics gathering could be disabled with further tweaking of the conditional compilation. * score/src/timespecdividebyinteger.c: New file.
Diffstat (limited to 'cpukit/libmisc/cpuuse')
-rw-r--r--cpukit/libmisc/cpuuse/cpuuse.c129
1 files changed, 89 insertions, 40 deletions
diff --git a/cpukit/libmisc/cpuuse/cpuuse.c b/cpukit/libmisc/cpuuse/cpuuse.c
index 9e9be38db8..cf1b6f2b4d 100644
--- a/cpukit/libmisc/cpuuse/cpuuse.c
+++ b/cpukit/libmisc/cpuuse/cpuuse.c
@@ -26,7 +26,18 @@
#include <rtems/cpuuse.h>
#include <rtems/bspIo.h>
-uint32_t CPU_usage_Ticks_at_last_reset;
+#if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
+ defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
+ #include <rtems/score/timespec.h>
+
+ /* We print to 1/10's of milliseconds */
+ #define NANOSECONDS_DIVIDER 100000
+ #define PERCENT_FMT "%04" PRId32
+#endif
+
+#ifndef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ uint32_t CPU_usage_Ticks_at_last_reset;
+#endif
/*PAGE
*
@@ -41,27 +52,38 @@ void rtems_cpu_usage_report( void )
Objects_Information *information;
char name[5];
uint32_t ival, fval;
- uint32_t total_units = 0;
-
- 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->ticks_executed;
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ struct timespec uptime;
+ #else
+ uint32_t total_units = 0;
+ #endif
+
+ /*
+ * 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 );
+ #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->ticks_executed;
+ }
}
}
- }
-
+ #endif
+
printk( "CPU Usage by thread\n"
- " ID NAME TICKS PERCENT\n"
- );
+ " ID NAME TICKS PERCENT\n"
+ );
for ( api_index = 1 ;
api_index <= OBJECTS_APIS_LAST ;
@@ -77,36 +99,61 @@ void rtems_cpu_usage_report( void )
continue;
rtems_object_get_name( the_thread->Object.id, sizeof(name), name );
-
- ival = total_units ?
- the_thread->ticks_executed * 10000 / total_units : 0;
- fval = ival % 100;
- ival /= 100;
- printk(
- "0x%08" PRIx32 " %4s %8" PRId32 " %3" PRId32
- ".%02" PRId32"\n",
- the_thread->Object.id,
- name,
- the_thread->ticks_executed,
- ival,
- fval
- );
+
+ printk( "0x%08" PRIx32 " %4s ", the_thread->Object.id, name );
+
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ _Timespec_Divide( &the_thread->cpu_time_used, &uptime, &ival, &fval );
+
+ printk(
+ "%" PRId32 ".%06d" /* cpu time used */
+ " %3" PRId32 ".%02" PRId32 "\n", /* percentage */
+ the_thread->cpu_time_used.tv_sec,
+ the_thread->cpu_time_used.tv_nsec /
+ TOD_NANOSECONDS_PER_MICROSECOND,
+ ival,
+ fval
+ );
+ #else
+ ival = (total_units) ?
+ the_thread->ticks_executed * 10000 / total_units : 0;
+ fval = ival % 100;
+ ival /= 100;
+ printk(
+ "%8" PRId32 " %3" PRId32 ".%02" PRId32"\n",
+ the_thread->ticks_executed,
+ ival,
+ fval
+ );
+ #endif
}
}
}
- printk(
- "\nTicks since last reset = %" PRId32 "\n",
- _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset
- );
- printk( "\nTotal Units = %" PRId32 "\n", total_units );
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ printk( "Uptime %d.%06d seconds\n\n",
+ uptime.tv_sec,
+ uptime.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND
+ );
+ #else
+ printk(
+ "Ticks since last reset = %" PRId32 "\n",
+ _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset
+ );
+ printk( "Total Units = %" PRId32 "\n\n", total_units );
+ #endif
}
static void CPU_usage_Per_thread_handler(
Thread_Control *the_thread
)
{
- the_thread->ticks_executed = 0;
+ #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ the_thread->cpu_time_used.tv_sec = 0;
+ the_thread->cpu_time_used.tv_nsec = 0;
+ #else
+ the_thread->ticks_executed = 0;
+ #endif
}
/*
@@ -114,7 +161,9 @@ static void CPU_usage_Per_thread_handler(
*/
void rtems_cpu_usage_reset( void )
{
- CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot;
+ #ifndef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS
+ CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot;
+ #endif
rtems_iterate_over_all_threads(CPU_usage_Per_thread_handler);
}