summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libmisc
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1997-04-09 20:18:54 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1997-04-09 20:18:54 +0000
commitfc7bc517db4a6b6b5cf0e0e4c829ee01b0cb32a5 (patch)
treead4b85b59d644208f4cf74bc7f04a3d8a7bfc795 /c/src/lib/libmisc
parentadded rtmonuse and cpuuse directories (diff)
downloadrtems-fc7bc517db4a6b6b5cf0e0e4c829ee01b0cb32a5.tar.bz2
new files.
Diffstat (limited to 'c/src/lib/libmisc')
-rw-r--r--c/src/lib/libmisc/cpuuse/Makefile.in53
-rw-r--r--c/src/lib/libmisc/cpuuse/README41
-rw-r--r--c/src/lib/libmisc/cpuuse/cpuuse.c142
-rw-r--r--c/src/lib/libmisc/cpuuse/cpuuse.h41
-rw-r--r--c/src/lib/libmisc/cpuuse/internal.h96
-rw-r--r--c/src/lib/libmisc/rtmonuse/Makefile.in53
-rw-r--r--c/src/lib/libmisc/rtmonuse/rtmonuse.c173
-rw-r--r--c/src/lib/libmisc/rtmonuse/rtmonuse.h18
8 files changed, 617 insertions, 0 deletions
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 <rtems.h>
+
+extern rtems_configuration_table BSP_Configuration;
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#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 <rtems.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+
+#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