source: rtems/cpukit/score/src/heapwalk.c @ 77b1020a

4.104.114.84.95
Last change on this file since 77b1020a was 77b1020a, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/18/07 at 07:34:25

2007-03-18 Ralf Corsépius <ralf.corsepius@…>

  • score/src/heapwalk.c: include stdlib.h.
  • Property mode set to 100644
File size: 4.3 KB
RevLine 
[93b4e6ef]1/*
2 *  Heap Handler
3 *
[08311cc3]4 *  COPYRIGHT (c) 1989-1999.
[93b4e6ef]5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  The license and distribution terms for this file may be
8 *  found in the file LICENSE in this distribution or at
[dd687d97]9 *  http://www.rtems.com/license/LICENSE.
[93b4e6ef]10 *
11 *  $Id$
12 */
13
[a8eed23]14#if HAVE_CONFIG_H
15#include "config.h"
16#endif
[93b4e6ef]17
[77b1020a]18#include <stdlib.h> /* abort */
19
[93b4e6ef]20#include <rtems/system.h>
21#include <rtems/score/sysstate.h>
22#include <rtems/score/heap.h>
23
24/*PAGE
25 *
26 *  _Heap_Walk
27 *
28 *  This kernel routine walks the heap and verifies its correctness.
29 *
30 *  Input parameters:
31 *    the_heap  - pointer to heap header
32 *    source    - a numeric indicator of the invoker of this routine
33 *    do_dump   - when TRUE print the information
34 *
35 *  Output parameters: NONE
36 */
37
[962e894f]38#if !defined(RTEMS_HEAP_DEBUG)
[93b4e6ef]39
[962e894f]40boolean _Heap_Walk(
[93b4e6ef]41  Heap_Control  *the_heap,
42  int            source,
43  boolean        do_dump
44)
45{
[962e894f]46  return TRUE;
[93b4e6ef]47}
48
[962e894f]49#else /* defined(RTEMS_HEAP_DEBUG) */
[93b4e6ef]50
51#include <stdio.h>
52
[962e894f]53boolean _Heap_Walk(
[93b4e6ef]54  Heap_Control  *the_heap,
55  int            source,
56  boolean        do_dump
57)
58{
[962e894f]59  Heap_Block *the_block = the_heap->start;
60  Heap_Block *const end = the_heap->final;
61  Heap_Block *const tail = _Heap_Tail(the_heap);
62  int error = 0;
63  int passes = 0;
[93b4e6ef]64
65  /*
66   * We don't want to allow walking the heap until we have
67   * transferred control to the user task so we watch the
68   * system state.
69   */
70
71  if ( !_System_state_Is_up( _System_state_Get() ) )
[962e894f]72    return FALSE;
[93b4e6ef]73
[962e894f]74  if (source < 0)
75    source = the_heap->stats.instance;
[93b4e6ef]76
[962e894f]77  if (do_dump == TRUE)
[a607d363]78    printf("\nPASS: %d start %p final %p first %p last %p begin %p end %p\n",
[962e894f]79      source, the_block, end,
80      _Heap_First(the_heap), _Heap_Last(the_heap),
81      the_heap->begin, the_heap->end);
[93b4e6ef]82
83  /*
84   * Handle the 1st block
85   */
86
[962e894f]87  if (!_Heap_Is_prev_used(the_block)) {
[a607d363]88    printf("PASS: %d !HEAP_PREV_USED flag of 1st block isn't set\n", source);
[93b4e6ef]89    error = 1;
90  }
91
[80f2885b]92  if (the_block->prev_size != the_heap->page_size) {
[a607d363]93    printf("PASS: %d !prev_size of 1st block isn't page_size\n", source);
[962e894f]94    error = 1;
95  }
96
97  while ( the_block < end ) {
98    uint32_t const the_size = _Heap_Block_size(the_block);
99    Heap_Block *const next_block = _Heap_Block_at(the_block, the_size);
100    boolean prev_used = _Heap_Is_prev_used(the_block);
101
102    if (do_dump) {
[a607d363]103      printf("PASS: %d block %p size %d(%c)",
[962e894f]104        source, the_block, the_size, (prev_used ? 'U' : 'F'));
105      if (prev_used)
[a607d363]106        printf(" prev_size %d", the_block->prev_size);
[962e894f]107      else
[a607d363]108        printf(" (prev_size) %d", the_block->prev_size);
[93b4e6ef]109    }
110
[962e894f]111    if (!_Heap_Is_block_in(the_heap, next_block)) {
[a607d363]112      if (do_dump) printf("\n");
113      printf("PASS: %d !block %p is out of heap\n", source, next_block);
[962e894f]114      error = 1;
115      break;
116    }
[93b4e6ef]117
[962e894f]118    if (!_Heap_Is_prev_used(next_block)) {
119      if (do_dump)
[a607d363]120        printf( " prev %p next %p", the_block->prev, the_block->next);
[962e894f]121      if (_Heap_Block_size(the_block) != next_block->prev_size) {
[a607d363]122        if (do_dump) printf("\n");
123        printf("PASS: %d !front and back sizes don't match", source);
[93b4e6ef]124        error = 1;
[962e894f]125      }
126      if (!prev_used) {
[a607d363]127        if (do_dump || error) printf("\n");
128        printf("PASS: %d !two consecutive blocks are free", source);
[962e894f]129        error = 1;
130      }
131
132      { /* Check if 'the_block' is in the free block list */
133        Heap_Block* block = _Heap_First(the_heap);
134        while(block != the_block && block != tail)
135          block = block->next;
136        if(block != the_block) {
[a607d363]137          if (do_dump || error) printf("\n");
138          printf("PASS: %d !the_block not in the free list", source);
[962e894f]139          error = 1;
[93b4e6ef]140        }
141      }
[962e894f]142
[93b4e6ef]143    }
[a607d363]144    if (do_dump || error) printf("\n");
[93b4e6ef]145
[962e894f]146    if (the_size < the_heap->min_block_size) {
[a607d363]147      printf("PASS: %d !block size is too small\n", source);
[962e894f]148      error = 1;
149      break;
150    }
151    if (!_Heap_Is_aligned( the_size, the_heap->page_size)) {
[a607d363]152      printf("PASS: %d !block size is misaligned\n", source);
[962e894f]153      error = 1;
154    }
155
156    if (++passes > (do_dump ? 10 : 0) && error)
157      break;
158
159    the_block = next_block;
160  }
161
162  if (the_block != end) {
[a607d363]163    printf("PASS: %d !last block address isn't equal to 'final'\n", source);
[962e894f]164    error = 1;
165  }
166
[80f2885b]167  if (_Heap_Block_size(the_block) != the_heap->page_size) {
[a607d363]168    printf("PASS: %d !last block's size isn't page_size\n", source);
[962e894f]169    error = 1;
[93b4e6ef]170  }
171
[962e894f]172  if(do_dump && error)
173    abort();
174
175  return error == 0;
176
[93b4e6ef]177}
[962e894f]178#endif  /* defined(RTEMS_HEAP_DEBUG) */
Note: See TracBrowser for help on using the repository browser.