From fc7bc517db4a6b6b5cf0e0e4c829ee01b0cb32a5 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Wed, 9 Apr 1997 20:18:54 +0000 Subject: new files. --- c/src/lib/libmisc/cpuuse/Makefile.in | 53 ++++++++++ c/src/lib/libmisc/cpuuse/README | 41 ++++++++ c/src/lib/libmisc/cpuuse/cpuuse.c | 142 +++++++++++++++++++++++++++ c/src/lib/libmisc/cpuuse/cpuuse.h | 41 ++++++++ c/src/lib/libmisc/cpuuse/internal.h | 96 ++++++++++++++++++ c/src/lib/libmisc/rtmonuse/Makefile.in | 53 ++++++++++ c/src/lib/libmisc/rtmonuse/rtmonuse.c | 173 +++++++++++++++++++++++++++++++++ c/src/lib/libmisc/rtmonuse/rtmonuse.h | 18 ++++ 8 files changed, 617 insertions(+) create mode 100644 c/src/lib/libmisc/cpuuse/Makefile.in create mode 100644 c/src/lib/libmisc/cpuuse/README create mode 100644 c/src/lib/libmisc/cpuuse/cpuuse.c create mode 100644 c/src/lib/libmisc/cpuuse/cpuuse.h create mode 100644 c/src/lib/libmisc/cpuuse/internal.h create mode 100644 c/src/lib/libmisc/rtmonuse/Makefile.in create mode 100644 c/src/lib/libmisc/rtmonuse/rtmonuse.c create mode 100644 c/src/lib/libmisc/rtmonuse/rtmonuse.h (limited to 'c/src/lib/libmisc') diff --git a/c/src/lib/libmisc/cpuuse/Makefile.in b/c/src/lib/libmisc/cpuuse/Makefile.in new file mode 100644 index 0000000000..5311e1c271 --- /dev/null +++ b/c/src/lib/libmisc/cpuuse/Makefile.in @@ -0,0 +1,53 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +LIB=${ARCH}/libcpuuse-tmp.a + +# C source names, if any, go here -- minus the .c +C_PIECES=cpuuse +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= +INSTALLED_H_FILES=$(srcdir)/cpuuse.h + +SRCS=$(C_FILES) $(H_FILES) $(INSTALLED_H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += -I. +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${LIB}: ${SRCS} ${OBJS} + $(make-library) + +all: ${ARCH} $(SRCS) $(LIB) + $(INSTALL) -m 444 ${INSTALLED_H_FILES} ${PROJECT_RELEASE}/include +# $(INSTALL) -m 444 ${H_FILES} ${PROJECT_RELEASE}/include/rtems diff --git a/c/src/lib/libmisc/cpuuse/README b/c/src/lib/libmisc/cpuuse/README new file mode 100644 index 0000000000..e8a30006a1 --- /dev/null +++ b/c/src/lib/libmisc/cpuuse/README @@ -0,0 +1,41 @@ +# +# README,v 1.3 1995/12/19 20:13:47 joel Exp +# + +This directory contains a stack bounds checker. It provides two +primary features: + + + check for stack overflow at each context switch + + provides an educated guess at each task's stack usage + +The stack overflow check at context switch works by looking for +a 16 byte pattern at the logical end of the stack to be corrupted. +The "guesser" assumes that the entire stack was prefilled with a known +pattern and assumes that the pattern is still in place if the memory +has not been used as a stack. + +Both of these can be fooled by pushing large holes onto the stack +and not writing to them... or (much more unlikely) writing the +magic patterns into memory. + +This code has not been extensively tested. It is provided as a tool +for RTEMS users to catch the most common mistake in multitasking +systems ... too little stack space. Suggestions and comments are appreciated. + +NOTES: + +1. Stack usage information is questionable on CPUs which push + large holes on stack. + +2. The stack checker has a tendency to generate a fault when + trying to print the helpful diagnostic message. If it comes + out, congratulations. If not, then the variable Stack_check_Blown_task + contains a pointer to the TCB of the offending task. This + is usually enough to go on. + +FUTURE: + +1. Determine how/if gcc will generate stack probe calls and support that. + +2. Get accurate stack usage numbers on i960.. it pushes very large + holes on the stack. diff --git a/c/src/lib/libmisc/cpuuse/cpuuse.c b/c/src/lib/libmisc/cpuuse/cpuuse.c new file mode 100644 index 0000000000..d62fab506f --- /dev/null +++ b/c/src/lib/libmisc/cpuuse/cpuuse.c @@ -0,0 +1,142 @@ +/* + * CPU Usage Reporter + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994, 1996. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * check.c,v 1.13 1996/04/22 16:51:52 joel Exp + * + */ + +#include + +extern rtems_configuration_table BSP_Configuration; + +#include +#include +#include +#include + +#include "cpuuse.h" + +unsigned32 CPU_usage_Ticks_at_last_reset; + +/*PAGE + * + * CPU_usage_Dump + */ + +void CPU_usage_Dump( void ) +{ + unsigned32 i; + unsigned32 class_index; + Thread_Control *the_thread; + Objects_Information *information; + unsigned32 u32_name; + char name[5]; + unsigned32 total_units = 0; + + for ( class_index = OBJECTS_CLASSES_FIRST ; + class_index <= OBJECTS_CLASSES_LAST ; + class_index++ ) { + information = _Objects_Information_table[ class_index ]; + if ( information && information->is_thread ) { + for ( i=1 ; i <= information->maximum ; i++ ) { + the_thread = (Thread_Control *)information->local_table[ i ]; + + if ( the_thread ) + total_units += the_thread->ticks_executed; + } + } + } + + printf("CPU Usage by thread\n"); +#if defined(unix) || ( CPU_HARDWARE_FP == TRUE ) + printf( " ID NAME TICKS PERCENT\n" ); +#else + printf( " ID NAME TICKS\n" ); +#endif + + for ( class_index = OBJECTS_CLASSES_FIRST ; + class_index <= OBJECTS_CLASSES_LAST ; + class_index++ ) { + information = _Objects_Information_table[ class_index ]; + if ( information && information->is_thread ) { + for ( i=1 ; i <= information->maximum ; i++ ) { + the_thread = (Thread_Control *)information->local_table[ i ]; + + if ( !the_thread ) + continue; + + u32_name = *(unsigned32 *)the_thread->Object.name; + + name[ 0 ] = (u32_name >> 24) & 0xff; + name[ 1 ] = (u32_name >> 16) & 0xff; + name[ 2 ] = (u32_name >> 8) & 0xff; + name[ 3 ] = (u32_name >> 0) & 0xff; + name[ 4 ] = '\0'; + +#if defined(unix) || ( CPU_HARDWARE_FP == TRUE ) + printf( "0x%08x %4s %8d %5.3f\n", + the_thread->Object.id, + name, + the_thread->ticks_executed, + (total_units) ? + (double)the_thread->ticks_executed / (double)total_units : + (double)total_units + ); +#else + printf( "0x%08x %4s %8d\n", + the_thread->Object.id, + name, + the_thread->ticks_executed + ); +#endif + } + } + } + + printf( + "\nTicks since last reset = %d\n", + _Watchdog_Ticks_since_boot - CPU_usage_Ticks_at_last_reset + ); + printf( "\nTotal Units = %d\n", total_units ); +} + +/*PAGE + * + * CPU_usage_Reset + */ + +void CPU_usage_Reset( void ) +{ + unsigned32 i; + unsigned32 class_index; + Thread_Control *the_thread; + Objects_Information *information; + + CPU_usage_Ticks_at_last_reset = _Watchdog_Ticks_since_boot; + + for ( class_index = OBJECTS_CLASSES_FIRST ; + class_index <= OBJECTS_CLASSES_LAST ; + class_index++ ) { + information = _Objects_Information_table[ class_index ]; + if ( information && information->is_thread ) { + for ( i=1 ; i <= information->maximum ; i++ ) { + the_thread = (Thread_Control *)information->local_table[ i ]; + + if ( !the_thread ) + continue; + + the_thread->ticks_executed = 0; + } + } + } + +} + diff --git a/c/src/lib/libmisc/cpuuse/cpuuse.h b/c/src/lib/libmisc/cpuuse/cpuuse.h new file mode 100644 index 0000000000..11b7fc1015 --- /dev/null +++ b/c/src/lib/libmisc/cpuuse/cpuuse.h @@ -0,0 +1,41 @@ +/* cpuuse.h + * + * This include file contains information necessary to utilize + * and install the cpu usage reporting mechanism. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994, 1996. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * stackchk.h,v 1.3 1995/12/19 20:13:52 joel Exp + */ + +#ifndef __CPU_USE_h +#define __CPU_USE_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * CPU_usage_Dump + */ + +void CPU_usage_Dump( void ); + +/* + * CPU_usage_Reset + */ + +void CPU_usage_Reset( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libmisc/cpuuse/internal.h b/c/src/lib/libmisc/cpuuse/internal.h new file mode 100644 index 0000000000..a8c4c28044 --- /dev/null +++ b/c/src/lib/libmisc/cpuuse/internal.h @@ -0,0 +1,96 @@ +/* internal.h + * + * This include file contains internal information + * for the RTEMS stack checker. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * internal.h,v 1.5 1995/12/19 20:13:50 joel Exp + */ + +#ifndef __INTERNAL_STACK_CHECK_h +#define __INTERNAL_STACK_CHECK_h + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This structure is used to fill in and compare the "end of stack" + * marker pattern. + * pattern area must be a multiple of 4 words. + */ + +#ifdef CPU_STACK_CHECK_SIZE +#define PATTERN_SIZE_WORDS (((CPU_STACK_CHECK_SIZE / 4) + 3) & ~0x3) +#else +#define PATTERN_SIZE_WORDS 4 +#endif + +#define PATTERN_SIZE_BYTES (PATTERN_SIZE_WORDS * 4) + +typedef struct { + unsigned32 pattern[ PATTERN_SIZE_WORDS ]; +} Stack_check_Control; + +/* + * The pattern used to fill the entire stack. + */ + +#define BYTE_PATTERN 0xA5 +#define U32_PATTERN 0xA5A5A5A5 + +/* + * Stack_check_Create_extension + */ + +boolean Stack_check_Create_extension( + Thread_Control *running, + Thread_Control *the_thread +); + +/* + * Stack_check_Begin_extension + */ + +void Stack_check_Begin_extension( + Thread_Control *the_thread +); + +/* + * Stack_check_Switch_extension + */ + +void Stack_check_Switch_extension( + Thread_Control *running, + Thread_Control *heir +); + +/* + * Stack_check_Fatal_extension + */ + +void Stack_check_Fatal_extension( + Internal_errors_Source source, + boolean is_internal, + unsigned32 status +); + +/* + * Stack_check_Dump_usage + */ + +void Stack_check_Dump_usage( void ); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libmisc/rtmonuse/Makefile.in b/c/src/lib/libmisc/rtmonuse/Makefile.in new file mode 100644 index 0000000000..6f0808f8f2 --- /dev/null +++ b/c/src/lib/libmisc/rtmonuse/Makefile.in @@ -0,0 +1,53 @@ +# +# $Id$ +# + +@SET_MAKE@ +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH=@srcdir@ + +LIB=${ARCH}/librtmonuse-tmp.a + +# C source names, if any, go here -- minus the .c +C_PIECES=rtmonuse +C_FILES=$(C_PIECES:%=%.c) +C_O_FILES=$(C_PIECES:%=${ARCH}/%.o) + +H_FILES= +INSTALLED_H_FILES=$(srcdir)/rtmonuse.h + +SRCS=$(C_FILES) $(H_FILES) $(INSTALLED_H_FILES) +OBJS=$(C_O_FILES) + +include $(RTEMS_CUSTOM) +include $(PROJECT_ROOT)/make/lib.cfg + +# +# (OPTIONAL) Add local stuff here using += +# + +DEFINES += +CPPFLAGS += -I. +CFLAGS += + +LD_PATHS += +LD_LIBS += +LDFLAGS += + +# +# Add your list of files to delete here. The config files +# already know how to delete some stuff, so you may want +# to just run 'make clean' first to see what gets missed. +# 'make clobber' already includes 'make clean' +# + +CLEAN_ADDITIONS += +CLOBBER_ADDITIONS += + +${LIB}: ${SRCS} ${OBJS} + $(make-library) + +all: ${ARCH} $(SRCS) $(LIB) + $(INSTALL) -m 444 ${INSTALLED_H_FILES} ${PROJECT_RELEASE}/include +# $(INSTALL) -m 444 ${H_FILES} ${PROJECT_RELEASE}/include/rtems diff --git a/c/src/lib/libmisc/rtmonuse/rtmonuse.c b/c/src/lib/libmisc/rtmonuse/rtmonuse.c new file mode 100644 index 0000000000..272290176e --- /dev/null +++ b/c/src/lib/libmisc/rtmonuse/rtmonuse.c @@ -0,0 +1,173 @@ +/* + * $Id$ + */ + +#include +#include +#include +#include + +#include "rtmonuse.h" + +typedef struct { + rtems_id id; + unsigned32 count; + unsigned32 missed_count; + unsigned32 min_cpu_time; + unsigned32 max_cpu_time; + unsigned32 total_cpu_time; + unsigned32 min_wall_time; + unsigned32 max_wall_time; + unsigned32 total_wall_time; +} Period_usage_t; + +Period_usage_t *Period_usage_Information; + +/*PAGE + * + * Period_usage_Initialize + */ + +void Period_usage_Initialize( void ) +{ + int maximum; + + maximum = _Configuration_Table->RTEMS_api_configuration->maximum_periods; + + Period_usage_Information = malloc( sizeof(Period_usage_t) * (maximum+1) ); + + Period_usage_Reset(); +} + +/*PAGE + * + * Period_usage_Reset + */ + +void Period_usage_Reset( void ) +{ + unsigned32 i; + Period_usage_t *the_usage; + + for ( i=0 ; + i<_Configuration_Table->RTEMS_api_configuration->maximum_periods ; + i++ ) { + the_usage = &Period_usage_Information[ i ]; + + the_usage->count = 0; + the_usage->missed_count = 0; + the_usage->min_cpu_time = 0xFFFFFFFF; + the_usage->max_cpu_time = 0; + the_usage->total_cpu_time = 0; + the_usage->min_wall_time = 0xFFFFFFFF; + the_usage->max_wall_time = 0; + the_usage->total_wall_time = 0; + + } +} + +/*PAGE + * + * Period_usage_Update + */ + +void Period_usage_Update( + rtems_id id +) +{ + rtems_rate_monotonic_period_status rm_status; + rtems_status_code status; + Period_usage_t *the_usage; + + assert( Period_usage_Information ); + + status = rtems_rate_monotonic_get_status( id, &rm_status ); + assert( status == RTEMS_SUCCESSFUL ); + + the_usage = &Period_usage_Information[ rtems_get_index( id ) ]; + + the_usage->id = id; + the_usage->count++; + if ( rm_status.state == RATE_MONOTONIC_EXPIRED ) + the_usage->missed_count++; + the_usage->total_cpu_time += rm_status.ticks_executed_since_last_period; + the_usage->total_wall_time += rm_status.ticks_since_last_period; + + /* + * Update CPU time + */ + + if ( rm_status.ticks_executed_since_last_period < the_usage->min_cpu_time ) + the_usage->min_cpu_time = rm_status.ticks_executed_since_last_period; + + if ( rm_status.ticks_executed_since_last_period > the_usage->max_cpu_time ) + the_usage->max_cpu_time = rm_status.ticks_executed_since_last_period; + + /* + * Update Wall time + */ + + if ( rm_status.ticks_since_last_period < the_usage->min_wall_time ) + the_usage->min_wall_time = rm_status.ticks_since_last_period; + + if ( rm_status.ticks_since_last_period > the_usage->max_wall_time ) + the_usage->max_wall_time = rm_status.ticks_since_last_period; + +} + +/*PAGE + * + * Period_usage_Dump + */ + +void Period_usage_Dump( void ) +{ + unsigned32 i; + Period_usage_t *the_usage; + Rate_monotonic_Control *the_period; + unsigned32 u32_name; + char name[5]; + + printf( "Period information by period\n" ); + printf( " ID OWNER PERIODS MISSED CPU TIME WALL TIME\n" ); + + /* + * RTEMS does not use an index of zero for object ids. + */ + + for ( i=1 ; + i<_Configuration_Table->RTEMS_api_configuration->maximum_periods ; + i++ ) { + the_usage = &Period_usage_Information[ i ]; + if ( the_usage->count == 0 ) + continue; + + the_period = + (Rate_monotonic_Control *)_Rate_monotonic_Information.local_table[ i ]; + + if ( the_period->owner ) + u32_name = *(unsigned32 *)the_period->owner->Object.name; + else + u32_name = rtems_build_name(' ', ' ', ' ', ' '); + + name[ 0 ] = (u32_name >> 24) & 0xff; + name[ 1 ] = (u32_name >> 16) & 0xff; + name[ 2 ] = (u32_name >> 8) & 0xff; + name[ 3 ] = (u32_name >> 0) & 0xff; + name[ 4 ] = '\0'; + + printf( + "0x%08x %4s %6d %3d %d/%d/%5.2f %d/%d/%3.2f\n", + the_usage->id, + name, + the_usage->count, + the_usage->missed_count, + the_usage->min_cpu_time, + the_usage->max_cpu_time, + (double) the_usage->total_cpu_time / (double) the_usage->count, + the_usage->min_wall_time, + the_usage->max_wall_time, + (double) the_usage->total_wall_time / (double) the_usage->count + ); + } +} diff --git a/c/src/lib/libmisc/rtmonuse/rtmonuse.h b/c/src/lib/libmisc/rtmonuse/rtmonuse.h new file mode 100644 index 0000000000..f0580a4f0b --- /dev/null +++ b/c/src/lib/libmisc/rtmonuse/rtmonuse.h @@ -0,0 +1,18 @@ +/* + * $Id$ + */ + +#ifndef __RATE_MONOTONIC_USAGE_h +#define __RATE_MONOTONIC_USAGE_h + +void Period_usage_Initialize( void ); + +void Period_usage_Reset( void ); + +void Period_usage_Update( + rtems_id id +); + +void Period_usage_Dump( void ); + +#endif -- cgit v1.2.3