summaryrefslogtreecommitdiffstats
path: root/testsuites/libtests/heapwalk
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-09 14:59:09 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2009-09-09 14:59:09 +0000
commit809fb589fc3f4de6409aeebc8b967e9e0e3b5b7d (patch)
tree2d0e8db5e1f734dccd8206021aa83cff6c70e3e4 /testsuites/libtests/heapwalk
parent2009-09-09 Sebastian Huber <Sebastian.Huber@embedded-brains.de> (diff)
downloadrtems-809fb589fc3f4de6409aeebc8b967e9e0e3b5b7d.tar.bz2
2009-09-09 Christian Mauderer <christian.mauderer@embedded-brains.de>
* 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.
Diffstat (limited to 'testsuites/libtests/heapwalk')
-rw-r--r--testsuites/libtests/heapwalk/heapwalk.scn36
-rw-r--r--testsuites/libtests/heapwalk/init.c350
2 files changed, 284 insertions, 102 deletions
diff --git a/testsuites/libtests/heapwalk/heapwalk.scn b/testsuites/libtests/heapwalk/heapwalk.scn
index 4d41167903..220606ab5c 100644
--- a/testsuites/libtests/heapwalk/heapwalk.scn
+++ b/testsuites/libtests/heapwalk/heapwalk.scn
@@ -1,6 +1,36 @@
*** HEAP WALK TEST ***
-Calling Heap Walk without initialising
-PASS: 1 !HEAP_PREV_USED flag of 1st block isn't set
+start with a system state != SYSTEM_STATE_UP
+testing the _Heap_Walk_check_control() function
+ test what happens if page size = 0
+ set page size to a not CPU-aligned value
+ set minimal block size to a not page aligned value
+ let the alloc area of the first block be not page-aligned
+ clear the previous used flag of the first block
+ set the previous block size of the first block to an invalid value
+ set invalid next block for last block
+testing the _Heap_Walk_check_free_list() function
+ no free blocks
+ create a loop in the free list
+ put a block outside the heap to the free list
+ put a block on the free list, which is not page-aligned
+ put a used block on the free list
Walk freshly initialized heap
-Passing negative value for source
+Test the main loop
+ set the blocksize so, that the next block is outside the heap
+ walk a heap with blocks with different states of the previous-used flag
+ create a block with a not page aligned size
+ create a block with a size smaller than the min_block_size
+ make a block with a size, so that the block reaches into the next block
+ make a block with a size, so that it includes the next block
+test the _Heap_Walk_check_free_block() function
+ set a previous size for the next block which is not equal to the size of the actual block
+ clear the previous_used flag of the first free block after an used block
+ take a free block out of the free list
+test the output-function for the _Heap_Walk()
+therefore use the (already tested) case with a page size of 0
+PASS[0]: page size 0, min block size 16
+ area begin 0x????????, area end 0x????????
+ first block 0x????????, last block 0x????????
+ first free 0x????????, last free 0x????????
+FAIL[0]: page size is zero
*** END OF HEAP WALK TEST ***
diff --git a/testsuites/libtests/heapwalk/init.c b/testsuites/libtests/heapwalk/init.c
index 6da32e4d70..565c7fbf47 100644
--- a/testsuites/libtests/heapwalk/init.c
+++ b/testsuites/libtests/heapwalk/init.c
@@ -4,6 +4,8 @@
* COPYRIGHT (c) 1989-2009.
* On-Line Applications Research Corporation (OAR).
*
+ * Copyright (c) 2009 embedded brains GmbH.
+ *
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.rtems.com/license/LICENSE.
@@ -23,137 +25,286 @@
#include <rtems/dumpbuf.h>
#define TEST_HEAP_SIZE 1024
+#define TEST_DEFAULT_PAGESIZE 128
+#define DUMP false
+
unsigned TestHeapMemory[TEST_HEAP_SIZE];
Heap_Control TestHeap;
-static void test_heap_init(void)
+static void test_heap_init_with_page_size( uintptr_t page_size )
{
- memset( TestHeapMemory, '\0', sizeof(TestHeapMemory) );
- _Heap_Initialize( &TestHeap, TestHeapMemory, sizeof(TestHeapMemory), 0 );
+ memset( TestHeapMemory, 0xFF, sizeof(TestHeapMemory) );
+ _Heap_Initialize( &TestHeap, TestHeapMemory, sizeof(TestHeapMemory), page_size );
}
-void test_heap_walk_body( int source, bool do_dump );
-
-static void test_heap_walk( int source )
+static void test_heap_init_default(void)
{
- test_heap_walk_body( source, true );
- test_heap_walk_body( source, false );
+ test_heap_init_with_page_size( 0 );
}
-void test_heap_walk_body( int source, bool do_dump )
+static void test_heap_init_custom(void)
{
- unsigned i, j, original;
+ test_heap_init_with_page_size( TEST_DEFAULT_PAGESIZE );
+}
- _Heap_Walk( &TestHeap, source, do_dump );
+static void test_call_heap_walk( bool expectet_retval )
+{
+ bool retval = _Heap_Walk( &TestHeap, 0, DUMP );
+ rtems_test_assert( retval == expectet_retval );
+}
- /*
- * Now corrupt all non-zero values
- */
- for (i=0 ; i<TEST_HEAP_SIZE ; i++) {
- original = TestHeapMemory[i];
- if ( original == 0 )
- continue;
+static void *test_allocate_block(void)
+{
+ return _Heap_Allocate_aligned_with_boundary( &TestHeap, 1, 0, 0 );
+}
- /* mark it free -- may or may not have already been */
- TestHeapMemory[i] &= ~0x01U;
- _Heap_Walk( &TestHeap, source, do_dump );
+static void test_create_heap_with_gaps()
+{
+ void *p1 = test_allocate_block();
+ void *p2 = test_allocate_block();
+ void *p3 = test_allocate_block();
+ void *p4 = test_allocate_block();
+ void *p5 = test_allocate_block();
+ void *p6 = test_allocate_block();
+ _Heap_Free( &TestHeap, p1 );
+ _Heap_Free( &TestHeap, p3 );
+ _Heap_Free( &TestHeap, p5 );
+}
- /* mark it used -- may or may not have already been */
- TestHeapMemory[i] |= 0x01;
- _Heap_Walk( &TestHeap, source, do_dump );
+static void *test_fill_heap()
+{
+ void *p1 = NULL;
+ void *p2 = NULL;
- /* try values of 2-7 in the last three bits -- push alignment issues */
- for (j=2 ; j<=7 ; j++) {
- TestHeapMemory[i] = (TestHeapMemory[i] & ~0x7U) | j;
- _Heap_Walk( &TestHeap, source, do_dump );
- }
+ do {
+ p2 = p1;
+ p1 = test_allocate_block();
+ }while( p1 != NULL );
+ return p2;
+}
- /* try 0 and see what that does */
- TestHeapMemory[i] = 0x00;
- _Heap_Walk( &TestHeap, source, do_dump );
+static void test_system_not_up(void)
+{
+ rtems_interrupt_level level;
- /* try 0xffffffff and see what that does */
- TestHeapMemory[i] = 0xffffffff;
- _Heap_Walk( &TestHeap, source, do_dump );
+ puts( "start with a system state != SYSTEM_STATE_UP" );
- TestHeapMemory[i] = original;
- }
+ rtems_interrupt_disable( level );
+ System_state_Codes state = _System_state_Get();
+ _System_state_Set( SYSTEM_STATE_FAILED );
+ test_call_heap_walk( true );
+ _System_state_Set( state );
+ rtems_interrupt_enable( level );
}
-static void test_walk_freshly_initialized(void)
+static void test_check_control(void)
{
- puts( "Walk freshly initialized heap" );
- test_heap_init();
- test_heap_walk(1);
-}
+ puts( "testing the _Heap_Walk_check_control() function" );
+
+ puts( "\ttest what happens if page size = 0" );
+ test_heap_init_default();
+ TestHeap.page_size = 0;
+ test_call_heap_walk( false );
+
+ puts( "\tset page size to a not CPU-aligned value" );
+ test_heap_init_default();
+ TestHeap.page_size = 3 * (CPU_ALIGNMENT) / 2;
+ test_call_heap_walk( false );
+
+ puts( "\tset minimal block size to a not page aligned value" );
+ test_heap_init_custom();
+ TestHeap.min_block_size = TEST_DEFAULT_PAGESIZE / 2;
+ test_call_heap_walk( false );
-static void test_negative_source_value(void)
-{
/*
- * Passing a negative value for source so that
- * the control enters the if block on line 67
+ * Set the page size to a value, other than the first block alloc area. Set
+ * even the min_block_size to that value to avoid it being not alligned.
*/
- puts( "Passing negative value for source" );
- test_heap_init();
- test_heap_walk( -1 );
+ puts( "\tlet the alloc area of the first block be not page-aligned" );
+ test_heap_init_custom();
+ TestHeap.page_size = (uintptr_t) TestHeap.first_block + CPU_ALIGNMENT;
+ TestHeap.min_block_size = TestHeap.page_size;
+ test_call_heap_walk( false );
+
+ puts( "\tclear the previous used flag of the first block" );
+ test_heap_init_default();
+ TestHeap.first_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
+ test_call_heap_walk( false );
+
+ puts( "\tset the previous block size of the first block to an invalid value" );
+ test_heap_init_custom();
+ TestHeap.first_block->prev_size = 0;
+ test_call_heap_walk( false );
+
+ puts( "\tset invalid next block for last block" );
+ test_heap_init_custom();
+ TestHeap.last_block->size_and_flag = 0;
+ test_call_heap_walk( false );
}
-static void test_prev_block_flag_check(void)
+static void test_check_free_list(void)
{
- /* Calling heapwalk without initialising the heap.
- * Covers line 80 and 85 on heapwalk.
- * Actually covers more than that.
- */
- puts( "Calling Heap Walk without initialising" );
- test_heap_walk( 1 );
+ void *p1 = NULL;
+ Heap_Block *first_free_block = NULL;
+ Heap_Block *secound_free_block = NULL;
+ Heap_Block *third_free_block = NULL;
+ Heap_Block *used_block = NULL;
+
+ puts( "testing the _Heap_Walk_check_free_list() function" );
+
+ puts( "\tno free blocks" );
+ test_heap_init_custom();
+ test_fill_heap();
+ test_call_heap_walk( true );
+
+ puts( "\tcreate a loop in the free list" );
+ test_heap_init_default();
+ test_create_heap_with_gaps();
+ /* find free blocks */
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ secound_free_block = first_free_block->next;
+ third_free_block = secound_free_block->next;
+ /* create a loop */
+ third_free_block->next = secound_free_block;
+ secound_free_block->prev = third_free_block;
+ test_call_heap_walk( false );
+
+ puts( "\tput a block outside the heap to the free list" );
+ test_heap_init_default();
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ first_free_block->next = TestHeap.first_block - 1;
+ test_call_heap_walk( false );
+
+ puts( "\tput a block on the free list, which is not page-aligned" );
+ test_heap_init_custom();
+ test_create_heap_with_gaps();
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ first_free_block->next = (Heap_Block *) ((uintptr_t) first_free_block->next + CPU_ALIGNMENT);
+ first_free_block->next->prev = first_free_block;
+ test_call_heap_walk( false );
+
+ puts( "\tput a used block on the free list" );
+ test_heap_init_custom();
+ test_create_heap_with_gaps();
+ p1 = test_allocate_block();
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ used_block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
+ _Heap_Free_list_insert_after( first_free_block, used_block );
+ test_call_heap_walk( false );
}
-static void test_not_aligned(void)
+static void test_freshly_initialized(void)
{
- /*
- * Hack to get to the error case where the blocks are
- * not on the page size. We initialize a heap with
- * default settings and change the page size to something
- * large.
- */
- puts( "Testing case of blocks not on page size" );
- test_heap_init();
- TestHeap.page_size = 128;
- test_heap_walk( -1 );
+ puts( "Walk freshly initialized heap" );
+ test_heap_init_default();
+ test_call_heap_walk( true );
}
-static void test_first_block_not_aligned(void)
+static void test_main_loop(void)
{
- /*
- * Hack to get to the error case where the blocks are
- * not on the page size. We initialize a heap with
- * default settings and change the page size to something
- * large.
- */
- puts( "Testing case of blocks not on page size" );
- test_heap_init();
- _Heap_Free_list_head(&TestHeap)->next = (void *)1;
- test_heap_walk( -1 );
+ void *p1 = NULL;
+ void *p2 = NULL;
+ Heap_Block *block = NULL;
+ Heap_Block *next_block = NULL;
+
+ puts( "Test the main loop" );
+
+ puts( "\tset the blocksize so, that the next block is outside the heap" );
+ test_heap_init_custom();
+ /* use all blocks */
+ p1 = test_fill_heap();
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
+ block->size_and_flag = ( 2 * _Heap_Block_size( block ) ) | HEAP_PREV_BLOCK_USED;
+ test_call_heap_walk( false );
+
+ puts( "\twalk a heap with blocks with different states of the previous-used flag" );
+ test_heap_init_custom();
+ test_create_heap_with_gaps();
+ test_allocate_block(); /* fill one gap */
+ test_call_heap_walk( true );
+
+ puts( "\tcreate a block with a not page aligned size" );
+ test_heap_init_custom();
+ p1 = test_allocate_block();
+ p2 = test_allocate_block();
+ _Heap_Free( &TestHeap, p1 );
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
+ block->size_and_flag = (3 * TestHeap.page_size / 2) & ~HEAP_PREV_BLOCK_USED;
+ test_call_heap_walk( false );
+
+ puts( "\tcreate a block with a size smaller than the min_block_size" );
+ test_heap_init_default();
+ p1 = test_allocate_block();
+ p2 = test_allocate_block();
+ _Heap_Free( &TestHeap, p1 );
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p2, TestHeap.page_size );
+ block->size_and_flag = 0;
+ test_call_heap_walk( false );
+
+ puts( "\tmake a block with a size, so that the block reaches into the next block" );
+ test_heap_init_default();
+ p1 = test_allocate_block();
+ p2 = test_allocate_block();
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
+ block->size_and_flag = ( 3 * _Heap_Block_size( block ) / 2 ) | HEAP_PREV_BLOCK_USED;
+ test_call_heap_walk( false );
+
+ puts( "\tmake a block with a size, so that it includes the next block" );
+ test_heap_init_default();
+ p1 = test_allocate_block();
+ p2 = test_allocate_block();
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
+ next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
+ block->size_and_flag = ( _Heap_Block_size( block ) + _Heap_Block_size( next_block ) ) | HEAP_PREV_BLOCK_USED;
+ test_call_heap_walk( true );
}
-static void test_not_in_free_list(void)
+static void test_check_free_block(void)
{
- void *p1, *p2, *p3;
+ Heap_Block *block = NULL;
+ Heap_Block *next_block = NULL;
+ Heap_Block *first_free_block = NULL;
+ Heap_Block *secound_free_block = NULL;
+ void *p1 = NULL;
+
+ puts( "test the _Heap_Walk_check_free_block() function" );
- /*
- * Hack to get to the error case where the blocks are
- * not on the page size. We initialize a heap with
- * default settings and change the page size to something
- * large.
- */
- puts( "Testing case of blocks not on page size" );
- test_heap_init();
- p1 =_Heap_Allocate( &TestHeap, 32 );
- p2 =_Heap_Allocate( &TestHeap, 32 );
- p3 =_Heap_Allocate( &TestHeap, 32 );
- _Heap_Free( &TestHeap, p2 );
- test_heap_walk( -1 );
+ puts( "\tset a previous size for the next block which is not equal to the size of the actual block" );
+ test_heap_init_default();
+ block = _Heap_Free_list_first( &TestHeap );
+ next_block = _Heap_Block_at( block, _Heap_Block_size( block ) );
+ next_block->prev_size = _Heap_Block_size( block ) - 1;
+ test_call_heap_walk( false );
+
+ puts( "\tclear the previous_used flag of the first free block after an used block" );
+ test_heap_init_default();
+ p1 = test_allocate_block();
+ block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size );
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ first_free_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
+ first_free_block->prev_size = _Heap_Block_size( block );
+ _Heap_Free_list_insert_after( first_free_block, block );
+ test_call_heap_walk( false );
+
+ puts( "\ttake a free block out of the free list" );
+ test_heap_init_custom();
+ test_create_heap_with_gaps();
+ first_free_block = _Heap_Free_list_first( &TestHeap );
+ secound_free_block = first_free_block->next;
+ _Heap_Free_list_remove( secound_free_block );
+ test_call_heap_walk( false );
+}
+
+static void test_output(void)
+{
+ puts( "test the output-function for the _Heap_Walk()" );
+ puts( "therefore use the (already tested) case with a page size of 0" );
+ /* use simple case where one PASS and one FAIL will be put out */
+ test_heap_init_default();
+ TestHeap.page_size = 0;
+ test_call_heap_walk( false );
+ _Heap_Walk( &TestHeap, 0, true );
}
rtems_task Init(
@@ -162,12 +313,13 @@ rtems_task Init(
{
puts( "\n\n*** HEAP WALK TEST ***" );
- test_prev_block_flag_check();
- test_walk_freshly_initialized();
- test_negative_source_value();
- test_not_aligned();
- test_not_in_free_list();
- test_first_block_not_aligned();
+ test_system_not_up();
+ test_check_control();
+ test_check_free_list();
+ test_freshly_initialized();
+ test_main_loop();
+ test_check_free_block();
+ test_output();
puts( "*** END OF HEAP WALK TEST ***" );
rtems_test_exit(0);