/*
|
/*
|
* Heap Handler
|
* Heap Handler
|
*
|
*
|
* COPYRIGHT (c) 1989-1999.
|
* COPYRIGHT (c) 1989-1999.
|
* On-Line Applications Research Corporation (OAR).
|
* On-Line Applications Research Corporation (OAR).
|
*
|
*
|
* The license and distribution terms for this file may be
|
* The license and distribution terms for this file may be
|
* found in the file LICENSE in this distribution or at
|
* found in the file LICENSE in this distribution or at
|
* http://www.OARcorp.com/rtems/license.html.
|
* http://www.OARcorp.com/rtems/license.html.
|
*
|
*
|
* $Id: heapwalk.c,v 1.2 2001-09-27 11:59:34 chris Exp $
|
* $Id: heapwalk.c,v 1.2 2001-09-27 11:59:34 chris Exp $
|
*/
|
*/
|
|
|
|
|
#include <rtems/system.h>
|
#include <rtems/system.h>
|
#include <rtems/score/sysstate.h>
|
#include <rtems/score/sysstate.h>
|
#include <rtems/score/heap.h>
|
#include <rtems/score/heap.h>
|
|
|
/*PAGE
|
/*PAGE
|
*
|
*
|
* _Heap_Walk
|
* _Heap_Walk
|
*
|
*
|
* This kernel routine walks the heap and verifies its correctness.
|
* This kernel routine walks the heap and verifies its correctness.
|
*
|
*
|
* Input parameters:
|
* Input parameters:
|
* the_heap - pointer to heap header
|
* the_heap - pointer to heap header
|
* source - a numeric indicator of the invoker of this routine
|
* source - a numeric indicator of the invoker of this routine
|
* do_dump - when TRUE print the information
|
* do_dump - when TRUE print the information
|
*
|
*
|
* Output parameters: NONE
|
* Output parameters: NONE
|
*/
|
*/
|
|
|
#ifndef RTEMS_DEBUG
|
#ifndef RTEMS_DEBUG
|
|
|
void _Heap_Walk(
|
void _Heap_Walk(
|
Heap_Control *the_heap,
|
Heap_Control *the_heap,
|
int source,
|
int source,
|
boolean do_dump
|
boolean do_dump
|
)
|
)
|
{
|
{
|
}
|
}
|
|
|
#else
|
#else
|
|
|
#include <stdio.h>
|
#include <stdio.h>
|
#include <unistd.h>
|
#include <unistd.h>
|
|
|
void _Heap_Walk(
|
void _Heap_Walk(
|
Heap_Control *the_heap,
|
Heap_Control *the_heap,
|
int source,
|
int source,
|
boolean do_dump
|
boolean do_dump
|
)
|
)
|
{
|
{
|
Heap_Block *the_block = 0; /* avoid warnings */
|
Heap_Block *the_block = 0; /* avoid warnings */
|
Heap_Block *next_block = 0; /* avoid warnings */
|
Heap_Block *next_block = 0; /* avoid warnings */
|
int notdone = 1;
|
int notdone = 1;
|
int error = 0;
|
int error = 0;
|
int passes = 0;
|
int passes = 0;
|
|
|
/*
|
/*
|
* We don't want to allow walking the heap until we have
|
* We don't want to allow walking the heap until we have
|
* transferred control to the user task so we watch the
|
* transferred control to the user task so we watch the
|
* system state.
|
* system state.
|
*/
|
*/
|
|
|
if ( !_System_state_Is_up( _System_state_Get() ) )
|
if ( !_System_state_Is_up( _System_state_Get() ) )
|
return;
|
return;
|
|
|
the_block = the_heap->start;
|
the_block = the_heap->start;
|
|
|
if (do_dump == TRUE) {
|
if (do_dump == TRUE) {
|
printf("\nPASS: %d start @ 0x%p final 0x%p, first 0x%p last 0x%p\n",
|
printf("\nPASS: %d start @ 0x%p final 0x%p, first 0x%p last 0x%p\n",
|
source, the_heap->start, the_heap->final,
|
source, the_heap->start, the_heap->final,
|
the_heap->first, the_heap->last
|
the_heap->first, the_heap->last
|
);
|
);
|
}
|
}
|
|
|
/*
|
/*
|
* Handle the 1st block
|
* Handle the 1st block
|
*/
|
*/
|
|
|
if (the_block->back_flag != HEAP_DUMMY_FLAG) {
|
if (the_block->back_flag != HEAP_DUMMY_FLAG) {
|
printf("PASS: %d Back flag of 1st block isn't HEAP_DUMMY_FLAG\n", source);
|
printf("PASS: %d Back flag of 1st block isn't HEAP_DUMMY_FLAG\n", source);
|
error = 1;
|
error = 1;
|
}
|
}
|
|
|
while (notdone) {
|
while (notdone) {
|
passes++;
|
passes++;
|
if (error && (passes > 10))
|
if (error && (passes > 10))
|
abort();
|
abort();
|
|
|
if (do_dump == TRUE) {
|
if (do_dump == TRUE) {
|
printf("PASS: %d Block @ 0x%p Back %d, Front %d",
|
printf("PASS: %d Block @ 0x%p Back %d, Front %d",
|
source, the_block,
|
source, the_block,
|
the_block->back_flag, the_block->front_flag);
|
the_block->back_flag, the_block->front_flag);
|
if ( _Heap_Is_block_free(the_block) ) {
|
if ( _Heap_Is_block_free(the_block) ) {
|
printf( " Prev 0x%p, Next 0x%p\n",
|
printf( " Prev 0x%p, Next 0x%p\n",
|
the_block->previous, the_block->next);
|
the_block->previous, the_block->next);
|
} else {
|
} else {
|
printf("\n");
|
printf("\n");
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
* Handle the last block
|
* Handle the last block
|
*/
|
*/
|
|
|
if ( the_block->front_flag != HEAP_DUMMY_FLAG ) {
|
if ( the_block->front_flag != HEAP_DUMMY_FLAG ) {
|
next_block = _Heap_Next_block(the_block);
|
next_block = _Heap_Next_block(the_block);
|
if ( the_block->front_flag != next_block->back_flag ) {
|
if ( the_block->front_flag != next_block->back_flag ) {
|
error = 1;
|
error = 1;
|
printf("PASS: %d Front and back flags don't match\n", source);
|
printf("PASS: %d Front and back flags don't match\n", source);
|
printf(" Current Block (%p): Back - %d, Front - %d",
|
printf(" Current Block (%p): Back - %d, Front - %d",
|
the_block, the_block->back_flag, the_block->front_flag);
|
the_block, the_block->back_flag, the_block->front_flag);
|
if (do_dump == TRUE) {
|
if (do_dump == TRUE) {
|
if (_Heap_Is_block_free(the_block)) {
|
if (_Heap_Is_block_free(the_block)) {
|
printf(" Prev 0x%p, Next 0x%p\n",
|
printf(" Prev 0x%p, Next 0x%p\n",
|
the_block->previous, the_block->next);
|
the_block->previous, the_block->next);
|
} else {
|
} else {
|
printf("\n");
|
printf("\n");
|
}
|
}
|
} else {
|
} else {
|
printf("\n");
|
printf("\n");
|
}
|
}
|
printf(" Next Block (%p): Back - %d, Front - %d",
|
printf(" Next Block (%p): Back - %d, Front - %d",
|
next_block, next_block->back_flag, next_block->front_flag);
|
next_block, next_block->back_flag, next_block->front_flag);
|
if (do_dump == TRUE) {
|
if (do_dump == TRUE) {
|
if (_Heap_Is_block_free(next_block)) {
|
if (_Heap_Is_block_free(next_block)) {
|
printf(" Prev 0x%p, Next 0x%p\n",
|
printf(" Prev 0x%p, Next 0x%p\n",
|
the_block->previous, the_block->next);
|
the_block->previous, the_block->next);
|
} else {
|
} else {
|
printf("\n");
|
printf("\n");
|
}
|
}
|
} else {
|
} else {
|
printf("\n");
|
printf("\n");
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
if (the_block->front_flag == HEAP_DUMMY_FLAG)
|
if (the_block->front_flag == HEAP_DUMMY_FLAG)
|
notdone = 0;
|
notdone = 0;
|
else
|
else
|
the_block = next_block;
|
the_block = next_block;
|
}
|
}
|
|
|
if (error)
|
if (error)
|
abort();
|
abort();
|
}
|
}
|
#endif
|
#endif
|
|
|