forked from Imagelibrary/rtems
new files.
This commit is contained in:
53
c/src/lib/libmisc/cpuuse/Makefile.in
Normal file
53
c/src/lib/libmisc/cpuuse/Makefile.in
Normal file
@@ -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
|
||||||
41
c/src/lib/libmisc/cpuuse/README
Normal file
41
c/src/lib/libmisc/cpuuse/README
Normal file
@@ -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.
|
||||||
142
c/src/lib/libmisc/cpuuse/cpuuse.c
Normal file
142
c/src/lib/libmisc/cpuuse/cpuuse.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
41
c/src/lib/libmisc/cpuuse/cpuuse.h
Normal file
41
c/src/lib/libmisc/cpuuse/cpuuse.h
Normal file
@@ -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 */
|
||||||
96
c/src/lib/libmisc/cpuuse/internal.h
Normal file
96
c/src/lib/libmisc/cpuuse/internal.h
Normal file
@@ -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 */
|
||||||
53
c/src/lib/libmisc/rtmonuse/Makefile.in
Normal file
53
c/src/lib/libmisc/rtmonuse/Makefile.in
Normal file
@@ -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
|
||||||
173
c/src/lib/libmisc/rtmonuse/rtmonuse.c
Normal file
173
c/src/lib/libmisc/rtmonuse/rtmonuse.c
Normal file
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
c/src/lib/libmisc/rtmonuse/rtmonuse.h
Normal file
18
c/src/lib/libmisc/rtmonuse/rtmonuse.h
Normal file
@@ -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
|
||||||
53
c/src/libmisc/cpuuse/Makefile.in
Normal file
53
c/src/libmisc/cpuuse/Makefile.in
Normal file
@@ -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
|
||||||
41
c/src/libmisc/cpuuse/README
Normal file
41
c/src/libmisc/cpuuse/README
Normal file
@@ -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.
|
||||||
142
c/src/libmisc/cpuuse/cpuuse.c
Normal file
142
c/src/libmisc/cpuuse/cpuuse.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
41
c/src/libmisc/cpuuse/cpuuse.h
Normal file
41
c/src/libmisc/cpuuse/cpuuse.h
Normal file
@@ -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 */
|
||||||
96
c/src/libmisc/cpuuse/internal.h
Normal file
96
c/src/libmisc/cpuuse/internal.h
Normal file
@@ -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 */
|
||||||
53
c/src/libmisc/rtmonuse/Makefile.in
Normal file
53
c/src/libmisc/rtmonuse/Makefile.in
Normal file
@@ -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
|
||||||
173
c/src/libmisc/rtmonuse/rtmonuse.c
Normal file
173
c/src/libmisc/rtmonuse/rtmonuse.c
Normal file
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
c/src/libmisc/rtmonuse/rtmonuse.h
Normal file
18
c/src/libmisc/rtmonuse/rtmonuse.h
Normal file
@@ -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
|
||||||
41
cpukit/libmisc/cpuuse/README
Normal file
41
cpukit/libmisc/cpuuse/README
Normal file
@@ -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.
|
||||||
142
cpukit/libmisc/cpuuse/cpuuse.c
Normal file
142
cpukit/libmisc/cpuuse/cpuuse.c
Normal file
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
41
cpukit/libmisc/cpuuse/cpuuse.h
Normal file
41
cpukit/libmisc/cpuuse/cpuuse.h
Normal file
@@ -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 */
|
||||||
173
cpukit/libmisc/rtmonuse/rtmonuse.c
Normal file
173
cpukit/libmisc/rtmonuse/rtmonuse.c
Normal file
@@ -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
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
18
cpukit/libmisc/rtmonuse/rtmonuse.h
Normal file
18
cpukit/libmisc/rtmonuse/rtmonuse.h
Normal file
@@ -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
|
||||||
Reference in New Issue
Block a user