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

4.115
Last change on this file since cdf30f05 was cdf30f05, checked in by Sebastian Huber <sebastian.huber@…>, on 06/19/15 at 12:57:44

rtems: Add rtems_interrupt_local_disable|enable()

Add rtems_interrupt_local_disable|enable() as suggested by Pavel Pisa to
emphasize that interrupts are only disabled on the current processor.
Do not define the rtems_interrupt_disable|enable|flash() macros and
functions on SMP configurations since they don't ensure system wide
mutual exclusion.

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