source: rtems/cpukit/score/src/heapwalk.c @ a8eed23

4.104.114.84.95
Last change on this file since a8eed23 was a8eed23, checked in by Ralf Corsepius <ralf.corsepius@…>, on 01/27/05 at 05:57:05

Include config.h.

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