mirror of
https://github.com/t-crest/rtems.git
synced 2025-11-16 12:34:47 +00:00
2007-09-06 Joel Sherrill <joel.sherrill@oarcorp.com>
* 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.
This commit is contained in:
@@ -1,3 +1,19 @@
|
||||
2007-09-06 Joel Sherrill <joel.sherrill@oarcorp.com>
|
||||
|
||||
* 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 <joel.sherrill@oarcorp.com>
|
||||
|
||||
* shttpd/compat_rtems.c: Style clean up.
|
||||
|
||||
@@ -37,8 +37,25 @@ extern BSP_polling_getchar_function_type BSP_poll_char;
|
||||
* and initialisation of the previous variable are done.
|
||||
*/
|
||||
#include <stdarg.h>
|
||||
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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
|
||||
33
cpukit/libcsupport/src/printk_plugin.c
Normal file
33
cpukit/libcsupport/src/printk_plugin.c
Normal file
@@ -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 <stdarg.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
int printk_plugin(
|
||||
void *ignored,
|
||||
const char *format,
|
||||
...
|
||||
)
|
||||
{
|
||||
va_list arg_pointer;
|
||||
|
||||
va_start (arg_pointer, format);
|
||||
|
||||
vprintk( format, arg_pointer );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
#include <rtems/cpuuse.h>
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#if defined(RTEMS_ENABLE_NANOSECOND_RATE_MONOTONIC_STATISTICS) || \
|
||||
defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
|
||||
#if defined(RTEMS_ENABLE_NANOSECOND_CPU_USAGE_STATISTICS)
|
||||
#include <rtems/score/timespec.h>
|
||||
#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 );
|
||||
}
|
||||
|
||||
@@ -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 <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
|
||||
*/
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#ifndef __RTEMS_STACK_CHECKER_h
|
||||
#define __RTEMS_STACK_CHECKER_h
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#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 **
|
||||
|
||||
@@ -32,6 +32,8 @@
|
||||
#define RTEMS_RATEMON_EXTERN extern
|
||||
#endif
|
||||
|
||||
#include <rtems/bspIo.h>
|
||||
|
||||
#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
|
||||
*
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user