From 90a5d194a2712d7e28eafa1aac0b9fdb32e7b96b Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 6 Sep 2007 22:51:25 +0000 Subject: 2007-09-06 Joel Sherrill * libcsupport/Makefile.am, libcsupport/src/printk.c: * libcsupport/src/printk_plugin.c: New file. include/rtems/bspIo.h, libmisc/cpuuse/cpuusagereport.c, libmisc/cpuuse/cpuuse.h, libmisc/stackchk/check.c, libmisc/stackchk/stackchk.h: rtems/include/rtems/rtems/ratemon.h, rtems/src/ratemonreportstatistics.c: Added capability to specify your own "printf" routine to various reporting functions. This added an XXX_with_plugin as the underlying implementation for + rtems_rate_monotonic_report_statistics + rtems_stack_checker_report_usage + rtems_cpu_usage_report As demonstration, the http netdemo can now print out stack and cpu usage reports. --- cpukit/ChangeLog | 16 ++++++++++++ cpukit/include/rtems/bspIo.h | 21 +++++++++++++-- cpukit/libcsupport/Makefile.am | 6 ++--- cpukit/libcsupport/src/printk.c | 41 +++++++++++++++--------------- cpukit/libcsupport/src/printk_plugin.c | 33 ++++++++++++++++++++++++ cpukit/libmisc/cpuuse/cpuusagereport.c | 35 +++++++++++++++++-------- cpukit/libmisc/cpuuse/cpuuse.h | 13 +++++++++- cpukit/libmisc/stackchk/check.c | 33 ++++++++++++++++++++---- cpukit/libmisc/stackchk/stackchk.h | 17 +++++++++++++ cpukit/rtems/include/rtems/rtems/ratemon.h | 15 +++++++++++ cpukit/rtems/src/ratemonreportstatistics.c | 33 ++++++++++++++++-------- 11 files changed, 210 insertions(+), 53 deletions(-) create mode 100644 cpukit/libcsupport/src/printk_plugin.c diff --git a/cpukit/ChangeLog b/cpukit/ChangeLog index 8a8610c3a5..f67ffece3c 100644 --- a/cpukit/ChangeLog +++ b/cpukit/ChangeLog @@ -1,3 +1,19 @@ +2007-09-06 Joel Sherrill + + * libcsupport/Makefile.am, libcsupport/src/printk.c: + * libcsupport/src/printk_plugin.c: New file. + include/rtems/bspIo.h, libmisc/cpuuse/cpuusagereport.c, + libmisc/cpuuse/cpuuse.h, libmisc/stackchk/check.c, + libmisc/stackchk/stackchk.h: rtems/include/rtems/rtems/ratemon.h, + rtems/src/ratemonreportstatistics.c: Added capability to specify + your own "printf" routine to various reporting functions. This + added an XXX_with_plugin as the underlying implementation for + + rtems_rate_monotonic_report_statistics + + rtems_stack_checker_report_usage + + rtems_cpu_usage_report + As demonstration, the http netdemo can now print out stack + and cpu usage reports. + 2007-09-06 Joel Sherrill * shttpd/compat_rtems.c: Style clean up. diff --git a/cpukit/include/rtems/bspIo.h b/cpukit/include/rtems/bspIo.h index d3eda5610a..3e8eb5a534 100644 --- a/cpukit/include/rtems/bspIo.h +++ b/cpukit/include/rtems/bspIo.h @@ -37,8 +37,25 @@ extern BSP_polling_getchar_function_type BSP_poll_char; * and initialisation of the previous variable are done. */ #include -extern void vprintk(char *fmt, va_list ap); -extern void printk(char *fmt, ...); + +extern void vprintk(const char *fmt, va_list ap); +extern void printk(const char *fmt, ...); + +/* + * This routine is passed into RTEMS reporting functions + * that may have their output redirected. In particular, + * the cpu usage, period usage, and stack usage reporting + * functions use this. If the user provides their + * own "printf plugin", then they may redirect those reports + * as they see fit. + */ +extern int printk_plugin(void *context, const char *fmt, ...); + +/* + * Type definition for function which can be plugged in to + * certain reporting routines to redirect the output + */ +typedef int (*rtems_printk_plugin_t)(void *, const char *format, ...); #ifdef __cplusplus } diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index 96ab0d0413..fdbeb48994 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -84,9 +84,9 @@ LIBC_GLUE_C_FILES = src/__getpid.c src/__gettod.c src/__times.c \ BSD_LIBC_C_FILES = src/strlcpy.c src/strlcat.c -libcsupport_a_SOURCES = src/gxx_wrappers.c src/printk.c $(BSD_LIBC_C_FILES) \ - $(BASE_FS_C_FILES) $(MALLOC_C_FILES) $(ERROR_C_FILES) \ - $(ASSOCIATION_C_FILES) +libcsupport_a_SOURCES = src/gxx_wrappers.c src/printk.c src/printk_plugin.c \ + $(BSD_LIBC_C_FILES) $(BASE_FS_C_FILES) $(MALLOC_C_FILES) \ + $(ERROR_C_FILES) $(ASSOCIATION_C_FILES) if UNIX libcsupport_a_SOURCES += src/unixlibc.c src/unixlibc_io.c src/hosterr.c diff --git a/cpukit/libcsupport/src/printk.c b/cpukit/libcsupport/src/printk.c index a3926f2fc8..21f077ef16 100644 --- a/cpukit/libcsupport/src/printk.c +++ b/cpukit/libcsupport/src/printk.c @@ -1,22 +1,21 @@ -/*-------------------------------------------------------------------------+ -| printk.c v1.1 - PC386 BSP - 1997/08/07 -+--------------------------------------------------------------------------+ -| (C) Copyright 1997 - -| - NavIST Group - Real-Time Distributed Systems and Industrial Automation -| -| http://pandora.ist.utl.pt -| -| Instituto Superior Tecnico * Lisboa * PORTUGAL -+--------------------------------------------------------------------------+ -| Disclaimer: -| -| This file is provided "AS IS" without warranty of any kind, either -| expressed or implied. -+--------------------------------------------------------------------------+ -| This code is based on code by: Jose Rufino - IST -| -| $Id$ -+--------------------------------------------------------------------------*/ +/* + * + * (C) Copyright 1997 - + * - NavIST Group - Real-Time Distributed Systems and Industrial Automation + * + * http://pandora.ist.utl.pt + * + * Instituto Superior Tecnico * Lisboa * PORTUGAL + * + * Disclaimer: + * + * This file is provided "AS IS" without warranty of any kind, either + * expressed or implied. + *--------------------------------------------------------------------------+ + * This code is based on code by: Jose Rufino - IST + * + * $Id$ + *--------------------------------------------------------------------------*/ #if HAVE_CONFIG_H #include "config.h" @@ -71,7 +70,7 @@ printNum(long unsigned int num, int base, int sign, int maxwidth, int lead) | Returns: Nothing. +--------------------------------------------------------------------------*/ void -vprintk(char *fmt, va_list ap) +vprintk(const char *fmt, va_list ap) { char c, *str; int lflag, base, sign, width, lead; @@ -138,7 +137,7 @@ vprintk(char *fmt, va_list ap) } /* vprintk */ void -printk(char *fmt, ...) +printk(const char *fmt, ...) { va_list ap; /* points to each unnamed argument in turn */ diff --git a/cpukit/libcsupport/src/printk_plugin.c b/cpukit/libcsupport/src/printk_plugin.c new file mode 100644 index 0000000000..c135300345 --- /dev/null +++ b/cpukit/libcsupport/src/printk_plugin.c @@ -0,0 +1,33 @@ +/* + * 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$ + */ + +#if HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include + +int printk_plugin( + void *ignored, + const char *format, + ... +) +{ + va_list arg_pointer; + + va_start (arg_pointer, format); + + vprintk( format, arg_pointer ); + + return 0; +} + diff --git a/cpukit/libmisc/cpuuse/cpuusagereport.c b/cpukit/libmisc/cpuuse/cpuusagereport.c index 9c9bd4aef2..2a4c569e26 100644 --- a/cpukit/libmisc/cpuuse/cpuusagereport.c +++ b/cpukit/libmisc/cpuuse/cpuusagereport.c @@ -27,8 +27,7 @@ #include #include -#if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \ - defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) +#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) #include #endif @@ -43,7 +42,10 @@ * rtems_cpu_usage_report */ -void rtems_cpu_usage_report( void ) +void rtems_cpu_usage_report_with_plugin( + void *context, + rtems_printk_plugin_t print +) { uint32_t i; uint32_t api_index; @@ -57,6 +59,9 @@ void rtems_cpu_usage_report( void ) 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 @@ -81,7 +86,10 @@ void rtems_cpu_usage_report( void ) } #endif - printk( "CPU Usage by thread\n" + #if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) + (*print)( context, "--- CPU Usage times are seconds:microseconds ---\n" ); + #endif + (*print)( context, "CPU Usage by thread\n" #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS " ID NAME SECONDS PERCENT\n" #else @@ -104,7 +112,7 @@ void rtems_cpu_usage_report( void ) rtems_object_get_name( the_thread->Object.id, sizeof(name), name ); - printk( "0x%08" PRIx32 " %4s ", the_thread->Object.id, name ); + (*print)( context, "0x%08" PRIx32 " %4s ", the_thread->Object.id, name ); #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS /* @@ -124,7 +132,9 @@ void rtems_cpu_usage_report( void ) /* * Print the information */ - printk("%2" PRId32 ".%06" PRId32 " %3" PRId32 ".%02" PRId32 "\n", + + (*print)( context, + "%2" PRId32 ":%06" PRId32 " %3" PRId32 ".%02" PRId32 "\n", ran.tv_sec, ran.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND, ival, fval ); @@ -133,7 +143,7 @@ void rtems_cpu_usage_report( void ) the_thread->ticks_executed * 10000 / total_units : 0; fval = ival % 100; ival /= 100; - printk( + (*print)( context, "%8" PRId32 " %3" PRId32 ".%02" PRId32"\n", the_thread->ticks_executed, ival, @@ -145,16 +155,21 @@ void rtems_cpu_usage_report( void ) } #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS - printk( "Time since last CPU Usage reset %" PRId32 + (*print)( context, "Time since last CPU Usage reset %" PRId32 ".%06" PRId32 " seconds\n", total.tv_sec, total.tv_nsec / TOD_NANOSECONDS_PER_MICROSECOND ); #else - printk( + (*print)( context, "Ticks since last reset = %" PRId32 "\n", _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset ); - printk( "Total Units = %" PRId32 "\n\n", total_units ); + (*print)( context, "Total Units = %" PRId32 "\n\n", total_units ); #endif } + +void rtems_cpu_usage_report( void ) +{ + rtems_cpu_usage_report_with_plugin( NULL, printk_plugin ); +} diff --git a/cpukit/libmisc/cpuuse/cpuuse.h b/cpukit/libmisc/cpuuse/cpuuse.h index 994c80e90a..b38927e7c6 100644 --- a/cpukit/libmisc/cpuuse/cpuuse.h +++ b/cpukit/libmisc/cpuuse/cpuuse.h @@ -3,7 +3,7 @@ * This include file contains information necessary to utilize * and install the cpu usage reporting mechanism. * - * COPYRIGHT (c) 1989-2006. + * COPYRIGHT (c) 1989-2007. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -16,10 +16,21 @@ #ifndef __RTEMS_CPUUSE_h #define __RTEMS_CPUUSE_h +#include + #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 */ diff --git a/cpukit/libmisc/stackchk/check.c b/cpukit/libmisc/stackchk/check.c index 3e0a39651a..5134936a3f 100644 --- a/cpukit/libmisc/stackchk/check.c +++ b/cpukit/libmisc/stackchk/check.c @@ -351,10 +351,13 @@ void *Stack_check_find_high_water_mark( } /* - * Stack_check_Dump_threads_usage( + * Stack_check_Dump_threads_usage * * Try to print out how much stack was actually used by the task. */ +static void *print_context; +static rtems_printk_plugin_t print_handler; + void Stack_check_Dump_threads_usage( Thread_Control *the_thread ) @@ -368,6 +371,9 @@ void Stack_check_Dump_threads_usage( if ( !the_thread ) return; + if ( !print_handler ) + return; + /* * XXX HACK to get to interrupt stack */ @@ -402,7 +408,9 @@ void Stack_check_Dump_threads_usage( name[ 4 ] = '\0'; } - printk("0x%08" PRIx32 " %4s 0x%p - 0x%p %8" PRId32 " %8" PRId32 "\n", + (*print_handler)( + print_context, + "0x%08" PRIx32 " %4s 0x%p - 0x%p %8" PRId32 " %8" PRId32 "\n", the_thread ? the_thread->Object.id : ~0, name, stack->area, @@ -432,13 +440,19 @@ void Stack_check_Dump_threads_usage( * rtems_stack_checker_report_usage */ -void rtems_stack_checker_report_usage( void ) +void rtems_stack_checker_report_usage_with_plugin( + void *context, + rtems_printk_plugin_t print +) { if (Stack_check_Initialized == 0) return; - printk("Stack usage by thread\n"); - printk( + print_context = context; + print_handler = print; + + (*print)( context, "Stack usage by thread\n"); + (*print)( context, " ID NAME LOW HIGH AVAILABLE USED\n" ); @@ -447,4 +461,13 @@ void rtems_stack_checker_report_usage( void ) /* dump interrupt stack info if any */ Stack_check_Dump_threads_usage((Thread_Control *) -1); + + print_context = NULL; + print_handler = NULL; + +} + +void rtems_stack_checker_report_usage( void ) +{ + rtems_stack_checker_report_usage_with_plugin( NULL, printk_plugin ); } diff --git a/cpukit/libmisc/stackchk/stackchk.h b/cpukit/libmisc/stackchk/stackchk.h index 78c0c9377d..b0dd69930a 100644 --- a/cpukit/libmisc/stackchk/stackchk.h +++ b/cpukit/libmisc/stackchk/stackchk.h @@ -18,6 +18,8 @@ #ifndef __RTEMS_STACK_CHECKER_h #define __RTEMS_STACK_CHECKER_h +#include + #ifdef __cplusplus extern "C" { #endif @@ -42,6 +44,21 @@ boolean rtems_stack_checker_is_blown( void ); */ void rtems_stack_checker_report_usage( void ); +/** @brief Print Stack Usage Report + * + * This method prints a stack usage report for the curently executing + * task. + * + * @param[in] context is the context to pass to the print handler + * @param[in] print is the print handler + * + * @note It uses the CALLER's routine to print the report. + */ +void rtems_stack_checker_report_usage_with_plugin( + void *context, + rtems_printk_plugin_t print +); + /************************************************************* ************************************************************* ** Prototyped only so the user extension can be installed ** diff --git a/cpukit/rtems/include/rtems/rtems/ratemon.h b/cpukit/rtems/include/rtems/rtems/ratemon.h index 66c2752bf3..8645dec4a9 100644 --- a/cpukit/rtems/include/rtems/rtems/ratemon.h +++ b/cpukit/rtems/include/rtems/rtems/ratemon.h @@ -32,6 +32,8 @@ #define RTEMS_RATEMON_EXTERN extern #endif +#include + #ifdef __cplusplus extern "C" { #endif @@ -273,6 +275,19 @@ rtems_status_code rtems_rate_monotonic_reset_statistics( */ void rtems_rate_monotonic_reset_all_statistics( void ); +/* + * rtems_rate_monotonic_report_statistics + * + * DESCRIPTION: + * + * This directive allows a thread to print the statistics information + * on ALL period instances which have non-zero counts using printk. + */ +void rtems_rate_monotonic_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +); + /* * rtems_rate_monotonic_report_statistics * diff --git a/cpukit/rtems/src/ratemonreportstatistics.c b/cpukit/rtems/src/ratemonreportstatistics.c index 7e03105e1a..039b700034 100644 --- a/cpukit/rtems/src/ratemonreportstatistics.c +++ b/cpukit/rtems/src/ratemonreportstatistics.c @@ -40,7 +40,10 @@ * inside and outside of RTEMS. It is presented as part of the Manager * but actually uses other services of the Manager. */ -void rtems_rate_monotonic_report_statistics( void ) +void rtems_rate_monotonic_report_statistics_with_plugin( + void *context, + rtems_printk_plugin_t print +) { rtems_status_code status; rtems_id id; @@ -48,13 +51,16 @@ void rtems_rate_monotonic_report_statistics( void ) rtems_rate_monotonic_period_status the_status; char name[5]; - printk( "Period information by period\n" ); + if ( !print ) + return; + + (*print)( context, "Period information by period\n" ); #if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) - printk( "--- Period times are seconds:microseconds ---\n" ); + (*print)( context, "--- Period times are seconds:microseconds ---\n" ); #endif #if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS) - printk( "--- CPU Usage times are seconds:microseconds ---\n" ); + (*print)( context, "--- CPU Usage times are seconds:microseconds ---\n" ); #endif /* Layout by columns -- in memory of Hollerith :) @@ -66,10 +72,10 @@ ididididid NNNN ccccc mmmmmm X Uncomment the following if you are tinkering with the formatting. Be sure to test the various cases. */ - printk("\ + (*print)( context,"\ 1234567890123456789012345678901234567890123456789012345678901234567890123456789\ \n"); - printk( " ID OWNER COUNT MISSED CPU TIME " + (*print)( context, " ID OWNER COUNT MISSED CPU TIME " #ifdef RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS " " #endif @@ -108,7 +114,7 @@ ididididid NNNN ccccc mmmmmm X * Print part of report line that is not dependent on granularity */ - printk( + (*print)( context, "0x%08" PRIx32 " %4s %5" PRId32 " %6" PRId32 " ", id, name, the_stats.count, the_stats.missed_count @@ -126,7 +132,7 @@ ididididid NNNN ccccc mmmmmm X the_stats.count, &cpu_average ); - printk( + (*print)( context, "%" PRId32 ":" NANOSECONDS_FMT "/" /* min cpu time */ "%" PRId32 ":" NANOSECONDS_FMT "/" /* max cpu time */ "%" PRId32 ":" NANOSECONDS_FMT " ", /* avg cpu time */ @@ -144,7 +150,7 @@ ididididid NNNN ccccc mmmmmm X fval_cpu = ival_cpu % 100; ival_cpu /= 100; - printk( + (*print)( context, "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 " ", the_stats.min_cpu_time, the_stats.max_cpu_time, ival_cpu, fval_cpu ); @@ -162,7 +168,7 @@ ididididid NNNN ccccc mmmmmm X the_stats.count, &wall_average ); - printk( + (*print)( context, "%" PRId32 ":" PERCENT_FMT "/" /* min wall time */ "%" PRId32 ":" PERCENT_FMT "/" /* max wall time */ "%" PRId32 ":" PERCENT_FMT "\n", /* avg wall time */ @@ -179,7 +185,7 @@ ididididid NNNN ccccc mmmmmm X ival_wall = the_stats.total_wall_time * 100 / the_stats.count; fval_wall = ival_wall % 100; ival_wall /= 100; - printk( + (*print)( context, "%3" PRId32 "/%4" PRId32 "/%3" PRId32 ".%02" PRId32 "\n", the_stats.min_wall_time, the_stats.max_wall_time, ival_wall, fval_wall ); @@ -187,3 +193,8 @@ ididididid NNNN ccccc mmmmmm X } } } + +void rtems_rate_monotonic_report_statistics( void ) +{ + rtems_rate_monotonic_report_statistics_with_plugin( NULL, printk_plugin ); +} -- cgit v1.2.3