source: rtems/testsuites/libtests/heapwalk/init.c @ 809fb589

4.104.115
Last change on this file since 809fb589 was 809fb589, checked in by Joel Sherrill <joel.sherrill@…>, on 09/09/09 at 14:59:09

2009-09-09 Christian Mauderer <christian.mauderer@…>

  • heapwalk/init.c, heapwalk/heapwalk.scn, malloctest/init.c, malloctest/malloctest.scn: New test cases.
  • stackchk/blow.c, stackchk/stackchk.scn: Update for heap API changes.
  • Property mode set to 100644
File size: 9.8 KB
Line 
1/*
2 *  Test of Heap Walker
3 *
4 *  COPYRIGHT (c) 1989-2009.
5 *  On-Line Applications Research Corporation (OAR).
6 *
7 *  Copyright (c) 2009 embedded brains GmbH.
8 *
9 *  The license and distribution terms for this file may be
10 *  found in the file LICENSE in this distribution or at
11 *  http://www.rtems.com/license/LICENSE.
12 *
13 *  $Id$
14 */
15
16#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__
17#define CONFIGURE_INIT
18#include "system.h"
19
20#include <stdlib.h>
21#include <inttypes.h>
22#include <errno.h>
23#include <string.h>
24#include <rtems/score/heap.h>
25#include <rtems/dumpbuf.h>
26
27#define TEST_HEAP_SIZE 1024
28#define TEST_DEFAULT_PAGESIZE 128
29#define DUMP false
30
31unsigned TestHeapMemory[TEST_HEAP_SIZE];
32Heap_Control TestHeap;
33
34static void test_heap_init_with_page_size( uintptr_t page_size )
35{
36  memset( TestHeapMemory, 0xFF, sizeof(TestHeapMemory) );
37  _Heap_Initialize( &TestHeap, TestHeapMemory, sizeof(TestHeapMemory), page_size );
38}
39
40static void test_heap_init_default(void)
41{
42  test_heap_init_with_page_size( 0 );
43}
44
45static void test_heap_init_custom(void)
46{
47  test_heap_init_with_page_size( TEST_DEFAULT_PAGESIZE );
48}
49
50static void test_call_heap_walk( bool expectet_retval )
51{
52  bool retval = _Heap_Walk( &TestHeap, 0, DUMP );
53  rtems_test_assert( retval == expectet_retval );
54}
55
56static void *test_allocate_block(void)
57{
58  return _Heap_Allocate_aligned_with_boundary( &TestHeap, 1, 0, 0 );
59}
60
61static void test_create_heap_with_gaps()
62{
63  void *p1 = test_allocate_block();
64  void *p2 = test_allocate_block();
65  void *p3 = test_allocate_block();
66  void *p4 = test_allocate_block();
67  void *p5 = test_allocate_block();
68  void *p6 = test_allocate_block();
69  _Heap_Free( &TestHeap, p1 );
70  _Heap_Free( &TestHeap, p3 );
71  _Heap_Free( &TestHeap, p5 );
72}
73
74static void *test_fill_heap()
75{
76  void *p1 = NULL;
77  void *p2 = NULL;
78
79  do {
80    p2 = p1;
81    p1 = test_allocate_block();
82  }while( p1 != NULL );
83
84  return p2;
85}
86
87static void test_system_not_up(void)
88{
89  rtems_interrupt_level level;
90
91  puts( "start with a system state != SYSTEM_STATE_UP" );
92
93  rtems_interrupt_disable( level );
94  System_state_Codes state = _System_state_Get();
95  _System_state_Set( SYSTEM_STATE_FAILED );
96  test_call_heap_walk( true );
97  _System_state_Set( state );
98  rtems_interrupt_enable( level );
99}
100
101static void test_check_control(void)
102{
103  puts( "testing the _Heap_Walk_check_control() function" );
104
105  puts( "\ttest what happens if page size = 0" );
106  test_heap_init_default();
107  TestHeap.page_size = 0;
108  test_call_heap_walk( false );
109
110  puts( "\tset page size to a not CPU-aligned value" );
111  test_heap_init_default();
112  TestHeap.page_size = 3 * (CPU_ALIGNMENT) / 2;
113  test_call_heap_walk( false );
114
115  puts( "\tset minimal block size to a not page aligned value" );
116  test_heap_init_custom();
117  TestHeap.min_block_size = TEST_DEFAULT_PAGESIZE / 2;
118  test_call_heap_walk( false );
119
120  /*
121   * Set the page size to a value, other than the first block alloc area.  Set
122   * even the min_block_size to that value to avoid it being not alligned.
123   */
124  puts( "\tlet the alloc area of the first block be not page-aligned" );
125  test_heap_init_custom();
126  TestHeap.page_size = (uintptr_t) TestHeap.first_block + CPU_ALIGNMENT;
127  TestHeap.min_block_size = TestHeap.page_size;
128  test_call_heap_walk( false );
129
130  puts( "\tclear the previous used flag of the first block" );
131  test_heap_init_default();
132  TestHeap.first_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
133  test_call_heap_walk( false );
134
135  puts( "\tset the previous block size of the first block to an invalid value" );
136  test_heap_init_custom();
137  TestHeap.first_block->prev_size = 0;
138  test_call_heap_walk( false );
139
140  puts( "\tset invalid next block for last block" );
141  test_heap_init_custom();
142  TestHeap.last_block->size_and_flag = 0;
143  test_call_heap_walk( false );
144}
145
146static void test_check_free_list(void)
147{
148  void *p1 = NULL;
149  Heap_Block *first_free_block = NULL;
150  Heap_Block *secound_free_block = NULL;
151  Heap_Block *third_free_block = NULL;
152  Heap_Block *used_block = NULL;
153
154  puts( "testing the _Heap_Walk_check_free_list() function" );
155
156  puts( "\tno free blocks" );
157  test_heap_init_custom();
158  test_fill_heap();
159  test_call_heap_walk( true );
160
161  puts( "\tcreate a loop in the free list" );
162  test_heap_init_default();
163  test_create_heap_with_gaps();
164  /* find free blocks */
165  first_free_block = _Heap_Free_list_first( &TestHeap );
166  secound_free_block = first_free_block->next;
167  third_free_block = secound_free_block->next;
168  /* create a loop */
169  third_free_block->next = secound_free_block;
170  secound_free_block->prev = third_free_block;
171  test_call_heap_walk( false );
172
173  puts( "\tput a block outside the heap to the free list" );
174  test_heap_init_default();
175  first_free_block = _Heap_Free_list_first( &TestHeap );
176  first_free_block->next = TestHeap.first_block - 1;
177  test_call_heap_walk( false );
178
179  puts( "\tput a block on the free list, which is not page-aligned" );
180  test_heap_init_custom();
181  test_create_heap_with_gaps();
182  first_free_block = _Heap_Free_list_first( &TestHeap );
183  first_free_block->next = (Heap_Block *) ((uintptr_t) first_free_block->next + CPU_ALIGNMENT);
184  first_free_block->next->prev = first_free_block;
185  test_call_heap_walk( false );
186
187  puts( "\tput a used block on the free list" );
188  test_heap_init_custom();
189  test_create_heap_with_gaps();
190  p1 = test_allocate_block();
191  first_free_block = _Heap_Free_list_first( &TestHeap );
192  used_block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
193  _Heap_Free_list_insert_after( first_free_block, used_block );
194  test_call_heap_walk( false );
195}
196
197static void test_freshly_initialized(void)
198{
199  puts( "Walk freshly initialized heap" );
200  test_heap_init_default();
201  test_call_heap_walk( true );
202}
203
204static void test_main_loop(void)
205{
206  void *p1 = NULL;
207  void *p2 = NULL;
208  Heap_Block *block = NULL;
209  Heap_Block *next_block = NULL;
210
211  puts( "Test the main loop" );
212 
213  puts( "\tset the blocksize so, that the next block is outside the heap" );
214  test_heap_init_custom();
215  /* use all blocks */
216  p1 = test_fill_heap();
217  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
218  block->size_and_flag = ( 2 * _Heap_Block_size( block ) ) | HEAP_PREV_BLOCK_USED;
219  test_call_heap_walk( false );
220
221  puts( "\twalk a heap with blocks with different states of the previous-used flag" );
222  test_heap_init_custom();
223  test_create_heap_with_gaps();
224  test_allocate_block(); /* fill one gap */
225  test_call_heap_walk( true );
226
227  puts( "\tcreate a block with a not page aligned size" );
228  test_heap_init_custom();
229  p1 = test_allocate_block();
230  p2 = test_allocate_block();
231  _Heap_Free( &TestHeap, p1 );
232  block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
233  block->size_and_flag = (3 * TestHeap.page_size / 2) & ~HEAP_PREV_BLOCK_USED;
234  test_call_heap_walk( false );
235
236  puts( "\tcreate a block with a size smaller than the min_block_size" );
237  test_heap_init_default();
238  p1 = test_allocate_block();
239  p2 = test_allocate_block();
240  _Heap_Free( &TestHeap, p1 );
241  block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
242  block->size_and_flag = 0;
243  test_call_heap_walk( false );
244
245  puts( "\tmake a block with a size, so that the block reaches into the next block" );
246  test_heap_init_default();
247  p1 = test_allocate_block();
248  p2 = test_allocate_block();
249  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size  );
250  block->size_and_flag = ( 3 * _Heap_Block_size( block ) / 2 ) | HEAP_PREV_BLOCK_USED;
251  test_call_heap_walk( false );
252
253  puts( "\tmake a block with a size, so that it includes the next block" );
254  test_heap_init_default();
255  p1 = test_allocate_block();
256  p2 = test_allocate_block();
257  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size  );
258  next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
259  block->size_and_flag = ( _Heap_Block_size( block ) + _Heap_Block_size( next_block ) ) | HEAP_PREV_BLOCK_USED;
260  test_call_heap_walk( true );
261}
262
263static void test_check_free_block(void)
264{
265  Heap_Block *block = NULL;
266  Heap_Block *next_block = NULL;
267  Heap_Block *first_free_block = NULL;
268  Heap_Block *secound_free_block = NULL;
269  void *p1 = NULL;
270 
271  puts( "test the _Heap_Walk_check_free_block() function" );
272
273  puts( "\tset a previous size for the next block which is not equal to the size of the actual block" );
274  test_heap_init_default();
275  block = _Heap_Free_list_first( &TestHeap );
276  next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
277  next_block->prev_size = _Heap_Block_size( block ) - 1;
278  test_call_heap_walk( false );
279
280  puts( "\tclear the previous_used flag of the first free block after an used block" );
281  test_heap_init_default();
282  p1 = test_allocate_block();
283  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
284  first_free_block = _Heap_Free_list_first( &TestHeap );
285  first_free_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
286  first_free_block->prev_size = _Heap_Block_size( block );
287  _Heap_Free_list_insert_after( first_free_block, block );
288  test_call_heap_walk( false );
289
290  puts( "\ttake a free block out of the free list" );
291  test_heap_init_custom();
292  test_create_heap_with_gaps();
293  first_free_block = _Heap_Free_list_first( &TestHeap );
294  secound_free_block = first_free_block->next;
295  _Heap_Free_list_remove( secound_free_block );
296  test_call_heap_walk( false );
297}
298
299static void test_output(void)
300{
301  puts( "test the output-function for the _Heap_Walk()" );
302  puts( "therefore use the (already tested) case with a page size of 0" );
303  /* use simple case where one PASS and one FAIL will be put out */
304  test_heap_init_default();
305  TestHeap.page_size = 0;
306  test_call_heap_walk( false );
307   _Heap_Walk( &TestHeap, 0, true );
308}
309
310rtems_task Init(
311  rtems_task_argument argument
312)
313{
314  puts( "\n\n*** HEAP WALK TEST ***" );
315
316  test_system_not_up();
317  test_check_control();
318  test_check_free_list();
319  test_freshly_initialized();
320  test_main_loop();
321  test_check_free_block();
322  test_output();
323
324  puts( "*** END OF HEAP WALK TEST ***" );
325  rtems_test_exit(0);
326}
Note: See TracBrowser for help on using the repository browser.