source: rtems/cpukit/score/src/heapwalk.c @ 671e042e

4.104.115
Last change on this file since 671e042e was 671e042e, checked in by Joel Sherrill <joel.sherrill@…>, on 06/13/09 at 22:49:28

2009-06-13 Joel Sherrill <joel.sherrill@…>

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