diff options
Diffstat (limited to 'testsuites/libtests/malloctest/init.c')
-rw-r--r-- | testsuites/libtests/malloctest/init.c | 405 |
1 files changed, 359 insertions, 46 deletions
diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c index 1f49cd64de..4121e0d75f 100644 --- a/testsuites/libtests/malloctest/init.c +++ b/testsuites/libtests/malloctest/init.c @@ -14,6 +14,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. @@ -108,13 +110,13 @@ static void test_realloc(void) p4 = realloc( test_realloc, 32 ); } -#define TEST_HEAP_SIZE 1024 +#define TEST_HEAP_SIZE 2048 uint8_t TestHeapMemory[TEST_HEAP_SIZE]; Heap_Control TestHeap; -static void test_heap_default_init() +static void test_heap_default_init(void) { memset( &TestHeapMemory, 0x7f, TEST_HEAP_SIZE ); _Heap_Initialize( &TestHeap, TestHeapMemory, TEST_HEAP_SIZE, 0 ); @@ -125,7 +127,7 @@ static void test_free( void *addr ) rtems_test_assert( _Heap_Free( &TestHeap, addr ) ); } -static void test_heap_cases_1() +static void test_heap_cases_1(void) { void *p1, *p2, *p3, *p4; intptr_t u1, u2; @@ -169,7 +171,7 @@ static void test_heap_cases_1() */ test_heap_default_init(); puts( "Heap Initialized" ); - p1 = _Heap_Allocate( &TestHeap, 500 ); + p1 = _Heap_Allocate( &TestHeap, 400 ); rtems_test_assert( p1 != NULL ); p2 = _Heap_Allocate( &TestHeap, 496 ); rtems_test_assert( p2 != NULL ); @@ -357,7 +359,46 @@ static uintptr_t test_page_size(void) return TestHeap.page_size; } -static void test_heap_cases_2() +static void test_heap_do_initialize( + uintptr_t area_size, + uintptr_t page_size, + uintptr_t success_expected +) +{ + uintptr_t rv = + _Heap_Initialize( &TestHeap, TestHeapMemory, area_size, page_size ); + + if ( success_expected ) { + rtems_test_assert( rv > 0 && _Heap_Walk( &TestHeap, 0, false ) ); + } else { + rtems_test_assert( rv == 0 ); + } +} + +static void test_heap_initialize(void) +{ + uintptr_t rv = 0; + + puts( "run tests for _Heap_Initialize()" ); + + test_heap_do_initialize( TEST_HEAP_SIZE, 0, true ); + + test_heap_do_initialize( TEST_HEAP_SIZE, TEST_DEFAULT_PAGE_SIZE, true ); + + test_heap_do_initialize( 0, 0, false ); + + test_heap_do_initialize( (uintptr_t) -1, 0, false ); + + test_heap_do_initialize( TEST_HEAP_SIZE, (uintptr_t) -1, false ); + + test_heap_do_initialize( + TEST_HEAP_SIZE, + (uintptr_t) (-2 * CPU_ALIGNMENT), + false + ); +} + +static void test_heap_allocate(void) { void *p1 = NULL; void *p2 = NULL; @@ -540,60 +581,350 @@ static void test_heap_cases_2() p1 = test_init_and_alloc( alloc_size, alignment, boundary, NULL ); } -static void test_block_alloc( uintptr_t alloc_begin, uintptr_t alloc_size ) +static void *test_create_used_block( void ) +{ + uintptr_t const alloc_size = 3 * TEST_DEFAULT_PAGE_SIZE; + uintptr_t const alignment = 0; + uintptr_t const boundary = 0; + + return test_alloc_simple( alloc_size, alignment, boundary ); +} + +static void test_block_alloc( + int free_variant, + int alloc_variant, + uintptr_t alloc_begin, + uintptr_t alloc_size +) { + void *p1 = NULL; + void *p2 = NULL; + void *p3 = NULL; + + uintptr_t size_fresh_heap = 0; + uintptr_t pages_per_default_block = 0; + uint32_t exp_free_pages = 0; + uint32_t exp_free_blocks = 0; + uint32_t exp_used_blocks = 0; + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + size_fresh_heap = _Heap_Get_size( &TestHeap ); + exp_free_pages = size_fresh_heap / TestHeap.page_size; + + p1 = test_create_used_block(); + p2 = test_create_used_block(); + p3 = test_create_used_block(); + + pages_per_default_block = _Heap_Block_size( + _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size ) + ) / TestHeap.page_size; + + if (free_variant == 1) { + test_free( p1 ); + } else if (free_variant == 2) { + test_free( p3 ); + } else if (free_variant == 3) { + test_free( p2 ); + test_free( p3 ); + } _Heap_Block_allocate( &TestHeap, - TestHeap.first_block, + _Heap_Block_of_alloc_area( (uintptr_t) p2, test_page_size()), alloc_begin, alloc_size ); test_check_alloc_simple( (void *) alloc_begin, alloc_size, 0, 0 ); + + /* check statistics */ + switch( free_variant ) { + case 1: + exp_free_pages = exp_free_pages - 2 * pages_per_default_block; + exp_used_blocks = 2; + + switch( alloc_variant ) { + case 1: + /* allocate block full space */ + exp_free_blocks = 2; + break; + case 2: + /* allocate block in the middle */ + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + exp_free_blocks = 3; + break; + case 3: + /* allocate block at the end */ + exp_free_pages = exp_free_pages + pages_per_default_block - 2; + exp_free_blocks = 2; + break; + default: + /* allocate block at the beginning */ + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + exp_free_blocks = 3; + break; + } + break; + case 2: + exp_free_pages = exp_free_pages - 2 * pages_per_default_block; + exp_used_blocks = 2; + + switch( alloc_variant ) { + case 1: + /* allocate block full space */ + exp_free_blocks = 1; + break; + case 2: + /* allocate block in the middle */ + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + exp_free_blocks = 2; + break; + case 3: + /* allocate block at the end */ + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + exp_free_blocks = 2; + break; + default: + /* allocate block at the beginning */ + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + exp_free_blocks = 1; + break; + } + break; + case 3: + exp_free_pages = exp_free_pages - pages_per_default_block; + exp_used_blocks = 2; + + switch( alloc_variant ) { + case 1: + /* allocate block full space */ + exp_free_pages = exp_free_pages - pages_per_default_block; + exp_free_blocks = 1; + break; + case 2: + /* allocate block in the middle */ + exp_free_pages = exp_free_pages - 1; + exp_free_blocks = 2; + break; + case 3: + /* allocate block at the end */ + exp_free_pages = exp_free_pages - 2; + exp_free_blocks = 2; + break; + default: + /* allocate block at the beginning */ + exp_free_pages = exp_free_pages - 1; + exp_free_blocks = 1; + break; + } + break; + default: + exp_free_pages = exp_free_pages - 3 * pages_per_default_block; + exp_used_blocks = 3; + + switch( alloc_variant ) { + case 1: + /* allocate block full space */ + exp_free_blocks = 1; + break; + case 2: + /* allocate block in the middle */ + exp_free_blocks = 3; + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + break; + case 3: + /* allocate block at the end */ + exp_free_blocks = 2; + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + break; + default: + /* allocate block at the beginning */ + exp_free_blocks = 2; + exp_free_pages = exp_free_pages + pages_per_default_block - 1; + } + } + + rtems_test_assert( TestHeap.stats.free_size == exp_free_pages * TestHeap.page_size ); + rtems_test_assert( TestHeap.stats.free_blocks == exp_free_blocks ); + rtems_test_assert( TestHeap.stats.used_blocks == exp_used_blocks ); } -static void test_heap_cases_block_allocate() +static void test_heap_do_block_allocate( int variant, void *p2 ) { + Heap_Block *const block = + _Heap_Block_of_alloc_area( (uintptr_t) p2, test_page_size()); + uintptr_t const alloc_box_begin = _Heap_Alloc_area_of_block( block ); + uintptr_t const alloc_box_size = _Heap_Block_size( block ); + uintptr_t const alloc_box_end = alloc_box_begin + alloc_box_size; uintptr_t alloc_begin = 0; uintptr_t alloc_size = 0; - uintptr_t alloc_box_begin = 0; - uintptr_t alloc_box_end = 0; - uintptr_t alloc_box_size = 0; - - test_heap_init( TEST_DEFAULT_PAGE_SIZE ); - - alloc_box_begin = _Heap_Alloc_area_of_block( TestHeap.first_block ); - alloc_box_size = _Heap_Block_size( TestHeap.first_block ); - alloc_box_end = alloc_box_begin + alloc_box_size; - - puts( "run tests for _Heap_Block_allocate()" ); puts( "\tallocate block at the beginning"); alloc_begin = alloc_box_begin; alloc_size = 0; - test_block_alloc( alloc_begin, alloc_size ); + test_block_alloc( variant, 0, alloc_begin, alloc_size ); puts( "\tallocate block full space"); alloc_begin = alloc_box_begin; alloc_size = alloc_box_size + HEAP_BLOCK_SIZE_OFFSET - HEAP_BLOCK_HEADER_SIZE; - test_block_alloc( alloc_begin, alloc_size ); + test_block_alloc( variant, 1, alloc_begin, alloc_size ); puts( "\tallocate block in the middle"); alloc_begin = alloc_box_begin + TEST_DEFAULT_PAGE_SIZE; alloc_size = 0; - test_block_alloc( alloc_begin, alloc_size ); + test_block_alloc( variant, 2, alloc_begin, alloc_size ); puts( "\tallocate block at the end"); alloc_begin = alloc_box_end - TEST_DEFAULT_PAGE_SIZE; alloc_size = TEST_DEFAULT_PAGE_SIZE + HEAP_BLOCK_SIZE_OFFSET - HEAP_BLOCK_HEADER_SIZE; - test_block_alloc( alloc_begin, alloc_size ); + test_block_alloc( variant, 3, alloc_begin, alloc_size ); } -static void test_heap_extend() +static void test_heap_block_allocate( void ) +{ + void *p2 = NULL; + + puts( "run tests for _Heap_Block_allocate()" ); + + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + test_create_used_block(); + p2 = test_create_used_block(); + + test_heap_do_block_allocate( 0, p2 ); + test_heap_do_block_allocate( 1, p2 ); + test_heap_do_block_allocate( 2, p2 ); + test_heap_do_block_allocate( 3, p2 ); +} + +static void *test_alloc_one_page() +{ + void *alloc_begin_ptr = _Heap_Allocate_aligned_with_boundary( + &TestHeap, + 1, + 0, + 0 + ); + + test_check_alloc_simple( + alloc_begin_ptr, + 1, + 0, + 0 + ); + + rtems_test_assert( alloc_begin_ptr != NULL ); + + return alloc_begin_ptr; +} + +static void *test_alloc_two_pages() +{ + void *alloc_begin_ptr = _Heap_Allocate_aligned_with_boundary( + &TestHeap, + 3 * TestHeap.page_size / 2, + 0, + 0 + ); + + test_check_alloc_simple( + alloc_begin_ptr, + 3 * TestHeap.page_size / 2, + 0, + 0 + ); + + rtems_test_assert( alloc_begin_ptr != NULL ); + + return alloc_begin_ptr; +} + +static void test_simple_resize_block( + void *alloc_pointer, + uintptr_t new_alloc_size, + Heap_Resize_status expected_status +) +{ + uintptr_t old_size = 0; + uintptr_t new_size = 0; + + Heap_Resize_status status = _Heap_Resize_block( + &TestHeap, + alloc_pointer, + new_alloc_size, + &old_size, + &new_size + ); + + rtems_test_assert( status == expected_status ); +} + +static void test_heap_resize_block() +{ + void *p1, *p2, *p3; + uintptr_t new_alloc_size = 0; + uintptr_t old_size = 0; + uintptr_t new_size = 0; + Heap_Block *block = NULL; + + puts( "run tests for _Heap_Resize_Block()" ); + + puts( "\tgive a block outside the heap to the function" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = TestHeap.first_block - TEST_DEFAULT_PAGE_SIZE; + new_alloc_size = 1; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_FATAL_ERROR ); + + puts( "\tincrease size"); + + puts( "\t\tlet the next block be used alredy and try to get a size bigger than the actual block" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_one_page(); + p2 = test_alloc_one_page(); + new_alloc_size = 3 * TEST_DEFAULT_PAGE_SIZE / 2; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_UNSATISFIED ); + + puts( "\t\tnext block not used and try to set the new allocation size between the page-alignments" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_one_page(); + new_alloc_size = 3 * TEST_DEFAULT_PAGE_SIZE / 2; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_SUCCESSFUL ); + + puts( "\t\tlet the block after the next be used and try to allocate more then one pagesize more" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_one_page(); + p2 = test_alloc_one_page(); + p3 = test_alloc_one_page(); + _Heap_Free( &TestHeap, p2 ); + new_alloc_size = 5 * TEST_DEFAULT_PAGE_SIZE / 2; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_UNSATISFIED ); + + puts( "\ttry to resize to the same size" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_one_page(); + block = _Heap_Block_of_alloc_area( (uintptr_t) p1, TestHeap.page_size ); + new_alloc_size = _Heap_Block_size( block ); + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_SUCCESSFUL ); + + puts( "\tdecrease size"); + + puts( "\t\tdecrease a block with two pages to one page" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_two_pages(); + new_alloc_size = 1; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_SUCCESSFUL ); + + puts( "\t\tresize the block to the size 0" ); + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + p1 = test_alloc_one_page(); + new_alloc_size = 0; + test_simple_resize_block( p1, new_alloc_size, HEAP_RESIZE_SUCCESSFUL ); +} + +static void test_heap_extend(void) { void *p1, *p2, *p3, *p4; uint32_t u1, u2; @@ -675,25 +1006,6 @@ static void test_protected_heap_info(void) rtems_test_assert( rc == false ); } -static void test_heap_resize(void) -{ - Heap_Resize_status rc; - void *p1; - intptr_t oldsize; - intptr_t avail; - - puts( "Initialize Test Heap" ); - test_heap_default_init(); - - puts( "Allocate most of heap" ); - p1 = _Heap_Allocate( &TestHeap, TEST_HEAP_SIZE - 32 ); - rtems_test_assert( p1 != NULL ); - - puts( "Resize (shrink) the area to 8 bytes to ensure remainder gets freed" ); - rc = _Heap_Resize_block( &TestHeap, p1, 8, &oldsize, &avail ); - rtems_test_assert( rc == HEAP_RESIZE_SUCCESSFUL ); -} - /* * A simple test of posix_memalign */ @@ -756,14 +1068,15 @@ rtems_task Init( status = rtems_clock_set( &time ); directive_failed( status, "rtems_clock_set" ); - test_heap_cases_2(); - test_heap_cases_block_allocate(); + test_heap_initialize(); + test_heap_block_allocate(); + test_heap_allocate(); + test_heap_resize_block(); test_realloc(); test_heap_cases_1(); test_heap_extend(); test_heap_info(); test_protected_heap_info(); - test_heap_resize(); test_posix_memalign(); |