source: rtems/cpukit/score/src/heapwalk.c @ 962e894f

4.104.114.84.95
Last change on this file since 962e894f was 962e894f, checked in by Joel Sherrill <joel.sherrill@…>, on 01/20/05 at 18:22:29

2005-01-20 Sergei Organov <osv@…>

PR 536/rtems
Heap manager re-implementation to consume less memory and still satisfy
alignment requirements.


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