summaryrefslogtreecommitdiffstats
path: root/cpukit/libmisc/cpuuse/cpuusagereport.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libmisc/cpuuse/cpuusagereport.c')
-rw-r--r--cpukit/libmisc/cpuuse/cpuusagereport.c205
1 files changed, 205 insertions, 0 deletions
diff --git a/cpukit/libmisc/cpuuse/cpuusagereport.c b/cpukit/libmisc/cpuuse/cpuusagereport.c
new file mode 100644
index 0000000000..92445520b7
--- /dev/null
+++ b/cpukit/libmisc/cpuuse/cpuusagereport.c
@@ -0,0 +1,205 @@
+/*
+ * CPU Usage Reporter
+ *
+ * COPYRIGHT (c) 1989-2010.
+ * 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 <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <ctype.h>
+#include <inttypes.h>
+
+#include <rtems/cpuuse.h>
+#include <rtems/bspIo.h>
+
+#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ #include <rtems/score/timestamp.h>
+#endif
+
+#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ extern Timestamp_Control 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;
+ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ Timestamp_Control uptime, total, ran, uptime_at_last_reset;
+ #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.
+ */
+ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ _Timestamp_Set_to_zero( &total );
+ uptime_at_last_reset = CPU_usage_Uptime_at_last_reset;
+ #else
+ for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
+ #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ #endif
+
+ 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,
+ "-------------------------------------------------------------------------------\n"
+ " CPU USAGE BY THREAD\n"
+ "------------+----------------------------------------+---------------+---------\n"
+ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ " ID | NAME | SECONDS | PERCENT\n"
+ #else
+ " ID | NAME | TICKS | PERCENT\n"
+ #endif
+ "------------+----------------------------------------+---------------+---------\n"
+ );
+
+ for ( api_index = 1 ; api_index <= OBJECTS_APIS_LAST ; api_index++ ) {
+ #if !defined(RTEMS_POSIX_API) || defined(RTEMS_DEBUG)
+ if ( !_Objects_Information_table[ api_index ] )
+ continue;
+ #endif
+
+ 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 " | %-38s |",
+ the_thread->Object.id,
+ name
+ );
+
+ #ifndef __RTEMS_USE_TICKS_FOR_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 ) {
+ Timestamp_Control used;
+ Timestamp_Control last = _Thread_Time_of_last_context_switch;
+ _TOD_Get_uptime( &uptime );
+ _Timestamp_Subtract( &last, &uptime, &used );
+ _Timestamp_Add_to( &ran, &used );
+ } else {
+ _TOD_Get_uptime( &uptime );
+ }
+ _Timestamp_Subtract( &uptime_at_last_reset, &uptime, &total );
+ _Timestamp_Divide( &ran, &total, &ival, &fval );
+
+ /*
+ * Print the information
+ */
+
+ (*print)( context,
+ "%7" PRIu32 ".%06" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
+ _Timestamp_Get_seconds( &ran ),
+ _Timestamp_Get_nanoseconds( &ran ) /
+ TOD_NANOSECONDS_PER_MICROSECOND,
+ ival, fval
+ );
+ #else
+ if (total_units) {
+ uint64_t ival_64;
+
+ ival_64 = the_thread->cpu_time_used;
+ ival_64 *= 100000;
+ ival = ival_64 / total_units;
+ } else {
+ ival = 0;
+ }
+
+ fval = ival % 1000;
+ ival /= 1000;
+ (*print)( context,
+ "%14" PRIu32 " |%4" PRIu32 ".%03" PRIu32 "\n",
+ the_thread->cpu_time_used,
+ ival,
+ fval
+ );
+ #endif
+ }
+ }
+ }
+
+ #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__
+ (*print)(
+ context,
+ "------------+----------------------------------------+---------------+---------\n"
+ " TIME SINCE LAST CPU USAGE RESET IN SECONDS: %7" PRIu32 ".%06" PRIu32 "\n"
+ "-------------------------------------------------------------------------------\n",
+ _Timestamp_Get_seconds( &total ),
+ _Timestamp_Get_nanoseconds( &total ) / TOD_NANOSECONDS_PER_MICROSECOND
+ );
+ #else
+ (*print)(
+ context,
+ "------------+----------------------------------------+---------------+---------\n"
+ " TICKS SINCE LAST SYSTEM RESET: %14" PRIu32 "\n"
+ " TOTAL UNITS: %14" PRIu32 "\n"
+ "-------------------------------------------------------------------------------\n",
+ _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset,
+ total_units
+ );
+ #endif
+}
+
+void rtems_cpu_usage_report( void )
+{
+ rtems_cpu_usage_report_with_plugin( NULL, printk_plugin );
+}