source: rtems/testsuites/libtests/heapwalk/init.c @ b0e81c96

4.115
Last change on this file since b0e81c96 was b0e81c96, checked in by Sebastian Huber <sebastian.huber@…>, on 06/07/10 at 09:33:32

2010-06-07 Sebastian Huber <sebastian.huber@…>

  • heapwalk/init.c, malloctest/init.c: Update for heap extend 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(void)
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(void)
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  puts( "\tset allocation area of the first block to be non page-aligned" );
121  test_heap_init_custom();
122  TestHeap.first_block = (Heap_Block *) ((char *) TestHeap.first_block + CPU_ALIGNMENT);
123  test_call_heap_walk( false );
124
125  puts( "\tclear the previous used flag of the first block" );
126  test_heap_init_default();
127  TestHeap.first_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
128  test_call_heap_walk( false );
129
130  puts( "\tset invalid next block for last block" );
131  test_heap_init_custom();
132  TestHeap.last_block->size_and_flag = 0;
133  test_call_heap_walk( false );
134}
135
136static void test_check_free_list(void)
137{
138  void *p1 = NULL;
139  Heap_Block *first_free_block = NULL;
140  Heap_Block *secound_free_block = NULL;
141  Heap_Block *third_free_block = NULL;
142  Heap_Block *used_block = NULL;
143
144  puts( "testing the _Heap_Walk_check_free_list() function" );
145
146  puts( "\tno free blocks" );
147  test_heap_init_custom();
148  test_fill_heap();
149  test_call_heap_walk( true );
150
151  puts( "\tcreate a loop in the free list" );
152  test_heap_init_default();
153  test_create_heap_with_gaps();
154  /* find free blocks */
155  first_free_block = _Heap_Free_list_first( &TestHeap );
156  secound_free_block = first_free_block->next;
157  third_free_block = secound_free_block->next;
158  /* create a loop */
159  third_free_block->next = secound_free_block;
160  secound_free_block->prev = third_free_block;
161  test_call_heap_walk( false );
162
163  puts( "\tput a block outside the heap to the free list" );
164  test_heap_init_default();
165  first_free_block = _Heap_Free_list_first( &TestHeap );
166  first_free_block->next = TestHeap.first_block - 1;
167  test_call_heap_walk( false );
168
169  puts( "\tput a block on the free list, which is not page-aligned" );
170  test_heap_init_custom();
171  test_create_heap_with_gaps();
172  first_free_block = _Heap_Free_list_first( &TestHeap );
173  first_free_block->next = (Heap_Block *) ((uintptr_t) first_free_block->next + CPU_ALIGNMENT);
174  first_free_block->next->prev = first_free_block;
175  test_call_heap_walk( false );
176
177  puts( "\tput a used block on the free list" );
178  test_heap_init_custom();
179  test_create_heap_with_gaps();
180  p1 = test_allocate_block();
181  first_free_block = _Heap_Free_list_first( &TestHeap );
182  used_block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
183  _Heap_Free_list_insert_after( first_free_block, used_block );
184  test_call_heap_walk( false );
185}
186
187static void test_freshly_initialized(void)
188{
189  puts( "Walk freshly initialized heap" );
190  test_heap_init_default();
191  test_call_heap_walk( true );
192}
193
194static void test_main_loop(void)
195{
196  void *p1 = NULL;
197  void *p2 = NULL;
198  Heap_Block *block = NULL;
199  Heap_Block *next_block = NULL;
200
201  puts( "Test the main loop" );
202
203  puts( "\tset the blocksize so, that the next block is outside the heap" );
204  test_heap_init_custom();
205  /* use all blocks */
206  p1 = test_fill_heap();
207  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
208  block->size_and_flag = ( 2 * _Heap_Block_size( block ) ) | HEAP_PREV_BLOCK_USED;
209  test_call_heap_walk( false );
210
211  puts( "\twalk a heap with blocks with different states of the previous-used flag" );
212  test_heap_init_custom();
213  test_create_heap_with_gaps();
214  test_allocate_block(); /* fill one gap */
215  test_call_heap_walk( true );
216
217  puts( "\tcreate a block with a not page aligned size" );
218  test_heap_init_custom();
219  p1 = test_allocate_block();
220  p2 = test_allocate_block();
221  _Heap_Free( &TestHeap, p1 );
222  block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
223  block->size_and_flag = (3 * TestHeap.page_size / 2) & ~HEAP_PREV_BLOCK_USED;
224  test_call_heap_walk( false );
225
226  puts( "\tcreate a block with a size smaller than the min_block_size" );
227  test_heap_init_default();
228  p1 = test_allocate_block();
229  p2 = test_allocate_block();
230  _Heap_Free( &TestHeap, p1 );
231  block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
232  block->size_and_flag = 0;
233  test_call_heap_walk( false );
234
235  puts( "\tmake a block with a size, so that the block reaches into the next block" );
236  test_heap_init_default();
237  p1 = test_allocate_block();
238  p2 = test_allocate_block();
239  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size  );
240  block->size_and_flag = ( 3 * _Heap_Block_size( block ) / 2 ) | HEAP_PREV_BLOCK_USED;
241  test_call_heap_walk( false );
242
243  puts( "\tcreate a block with invalid successor" );
244  test_heap_init_default();
245  test_allocate_block();
246  p1 = test_allocate_block();
247  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size  );
248  block->size_and_flag = (0 - TestHeap.page_size) | HEAP_PREV_BLOCK_USED;
249  test_call_heap_walk( false );
250
251  puts( "\tmake a block with a size, so that it includes the next block" );
252  test_heap_init_default();
253  p1 = test_allocate_block();
254  p2 = test_allocate_block();
255  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size  );
256  next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
257  block->size_and_flag = ( _Heap_Block_size( block ) + _Heap_Block_size( next_block ) ) | HEAP_PREV_BLOCK_USED;
258  test_call_heap_walk( true );
259}
260
261static void test_check_free_block(void)
262{
263  Heap_Block *block = NULL;
264  Heap_Block *next_block = NULL;
265  Heap_Block *first_free_block = NULL;
266  Heap_Block *secound_free_block = NULL;
267  void *p1 = NULL;
268
269  puts( "test the _Heap_Walk_check_free_block() function" );
270
271  puts( "\tset a previous size for the next block which is not equal to the size of the actual block" );
272  test_heap_init_default();
273  block = _Heap_Free_list_first( &TestHeap );
274  next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
275  next_block->prev_size = _Heap_Block_size( block ) - 1;
276  test_call_heap_walk( false );
277
278  puts( "\tclear the previous_used flag of the first free block after an used block" );
279  test_heap_init_default();
280  p1 = test_allocate_block();
281  block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
282  first_free_block = _Heap_Free_list_first( &TestHeap );
283  first_free_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
284  first_free_block->prev_size = _Heap_Block_size( block );
285  _Heap_Free_list_insert_after( first_free_block, block );
286  test_call_heap_walk( false );
287
288  puts( "\ttake a free block out of the free list" );
289  test_heap_init_custom();
290  test_create_heap_with_gaps();
291  first_free_block = _Heap_Free_list_first( &TestHeap );
292  secound_free_block = first_free_block->next;
293  _Heap_Free_list_remove( secound_free_block );
294  test_call_heap_walk( false );
295}
296
297static void test_output(void)
298{
299  puts( "test the output-function for the _Heap_Walk()" );
300  puts( "therefore use the (already tested) case with a page size of 0" );
301  /* use simple case where one PASS and one FAIL will be put out */
302  test_heap_init_default();
303  TestHeap.page_size = 0;
304  test_call_heap_walk( false );
305   _Heap_Walk( &TestHeap, 0, true );
306}
307
308rtems_task Init(
309  rtems_task_argument argument
310)
311{
312  puts( "\n\n*** HEAP WALK TEST ***" );
313
314  test_system_not_up();
315  test_check_control();
316  test_check_free_list();
317  test_freshly_initialized();
318  test_main_loop();
319  test_check_free_block();
320  test_output();
321
322  puts( "*** END OF HEAP WALK TEST ***" );
323  rtems_test_exit(0);
324}
Note: See TracBrowser for help on using the repository browser.