diff options
Diffstat (limited to 'cpukit/libmisc/cpuuse')
-rw-r--r-- | cpukit/libmisc/cpuuse/README | 21 | ||||
-rw-r--r-- | cpukit/libmisc/cpuuse/cpuusagedata.c | 28 | ||||
-rw-r--r-- | cpukit/libmisc/cpuuse/cpuusagereport.c | 205 | ||||
-rw-r--r-- | cpukit/libmisc/cpuuse/cpuusagereset.c | 60 | ||||
-rw-r--r-- | cpukit/libmisc/cpuuse/cpuuse.h | 51 |
5 files changed, 365 insertions, 0 deletions
diff --git a/cpukit/libmisc/cpuuse/README b/cpukit/libmisc/cpuuse/README new file mode 100644 index 0000000000..ac674bb0b6 --- /dev/null +++ b/cpukit/libmisc/cpuuse/README @@ -0,0 +1,21 @@ +# +# $Id$ +# + +This directory contains code to report and reset per-task CPU usage. +If the BSP supports nanosecond timestamp granularity, this this information +is very accurate. Otherwise, it is dependendent on the tick granularity. + +It provides two primary features: + + + Generate a CPU Usage Report + + Reset CPU Usage Information + +NOTES: + +1. If configured for tick granularity, CPU usage is "docked" by a + clock tick at each context switch. +2. If configured for nanosecond granularity, no work is done at each + clock tick. All bookkeeping is done as part of a context switch. + + diff --git a/cpukit/libmisc/cpuuse/cpuusagedata.c b/cpukit/libmisc/cpuuse/cpuusagedata.c new file mode 100644 index 0000000000..2d74b7eadf --- /dev/null +++ b/cpukit/libmisc/cpuuse/cpuusagedata.c @@ -0,0 +1,28 @@ +/* + * CPU Usage Reporter - Shared Data + * + * COPYRIGHT (c) 1989-2009 + * 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 <rtems/cpuuse.h> +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + #include <rtems/score/timespec.h> +#endif + +#ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + struct timespec CPU_usage_Uptime_at_last_reset; +#else + uint32_t CPU_usage_Ticks_at_last_reset; +#endif 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 ); +} diff --git a/cpukit/libmisc/cpuuse/cpuusagereset.c b/cpukit/libmisc/cpuuse/cpuusagereset.c new file mode 100644 index 0000000000..0bf46903f1 --- /dev/null +++ b/cpukit/libmisc/cpuuse/cpuusagereset.c @@ -0,0 +1,60 @@ +/* + * CPU Usage Reporter + * + * COPYRIGHT (c) 1989-2009 + * 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 <rtems/score/timestamp.h> + +#include <stdlib.h> +#include <ctype.h> +#include <inttypes.h> + +#include <rtems/cpuuse.h> + +static void CPU_usage_Per_thread_handler( + Thread_Control *the_thread +) +{ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _Timestamp_Set_to_zero( &the_thread->cpu_time_used ); + #else + the_thread->cpu_time_used = 0; + #endif +} + +/* + * External data that is shared by cpu usage code but not declared in .h files. + */ +#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 + +/* + * rtems_cpu_usage_reset + */ +void rtems_cpu_usage_reset( void ) +{ + #ifndef __RTEMS_USE_TICKS_FOR_STATISTICS__ + _TOD_Get_uptime( &CPU_usage_Uptime_at_last_reset ); + _Thread_Time_of_last_context_switch = CPU_usage_Uptime_at_last_reset; + #else + CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot; + #endif + + rtems_iterate_over_all_threads(CPU_usage_Per_thread_handler); +} diff --git a/cpukit/libmisc/cpuuse/cpuuse.h b/cpukit/libmisc/cpuuse/cpuuse.h new file mode 100644 index 0000000000..b38927e7c6 --- /dev/null +++ b/cpukit/libmisc/cpuuse/cpuuse.h @@ -0,0 +1,51 @@ +/* cpuuse.h + * + * This include file contains information necessary to utilize + * and install the cpu usage reporting mechanism. + * + * 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$ + */ + +#ifndef __RTEMS_CPUUSE_h +#define __RTEMS_CPUUSE_h + +#include <rtems/bspIo.h> + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * rtems_cpu_usage_report_with_handler + */ + +void rtems_cpu_usage_report_with_plugin( + void *context, + rtems_printk_plugin_t handler +); + +/* + * rtems_cpu_usage_report + */ + +void rtems_cpu_usage_report( void ); + +/* + * rtems_cpu_usage_reset + */ + +void rtems_cpu_usage_reset( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ |