From f6a41d2ea1c8ffd02d195fc090bcc382b445668f Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Sun, 6 Sep 2009 15:24:56 +0000 Subject: 2009-09-03 Christian Mauderer * malloctest/init.c: New test cases. Update for heap API changes. * stackchk/blow.c: Update for heap API changes. --- testsuites/libtests/ChangeLog | 5 + testsuites/libtests/malloctest/init.c | 475 ++++++++++++++++++++++++++++++++-- testsuites/libtests/stackchk/blow.c | 2 +- 3 files changed, 456 insertions(+), 26 deletions(-) (limited to 'testsuites/libtests') diff --git a/testsuites/libtests/ChangeLog b/testsuites/libtests/ChangeLog index 6d3cbcb2a6..7e9e68d4d0 100644 --- a/testsuites/libtests/ChangeLog +++ b/testsuites/libtests/ChangeLog @@ -1,3 +1,8 @@ +2009-09-03 Christian Mauderer + + * malloctest/init.c: New test cases. Update for heap API changes. + * stackchk/blow.c: Update for heap API changes. + 2009-08-19 Sebastian Huber * heapwalk/init.c, stackchk/blow.c: Update for heap API changes. diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c index b4a9873a14..1f49cd64de 100644 --- a/testsuites/libtests/malloctest/init.c +++ b/testsuites/libtests/malloctest/init.c @@ -26,6 +26,7 @@ #include "system.h" #include +#include #include #include #include @@ -33,10 +34,10 @@ /* * A simple test of realloc */ -void test_realloc(void) +static void test_realloc(void) { void *p1, *p2, *p3, *p4; - int i; + size_t i; int sc; /* Test growing reallocation "in place" */ @@ -45,7 +46,7 @@ void test_realloc(void) p2 = realloc(p1, i); if (p2 != p1) printf( "realloc - failed grow in place: " - "%p != realloc(%p,%d)\n", p1, p2, i ); + "%p != realloc(%p,%d)\n", p1, p2, i); p1 = p2; } free(p1); @@ -56,7 +57,7 @@ void test_realloc(void) p2 = realloc(p1, i); if (p2 != p1) printf( "realloc - failed shrink in place: " - "%p != realloc(%p,%d)\n", p1, p2, i ); + "%p != realloc(%p,%d)\n", p1, p2, i); p1 = p2; } free(p1); @@ -69,7 +70,7 @@ void test_realloc(void) p3 = realloc(p1, 64); if (p3 == p1 || p3 == NULL) printf( - "realloc - failed non-in place: realloc(%p,%d) = %p\n", p1, 64, p3 ); + "realloc - failed non-in place: realloc(%p,%d) = %p\n", p1, 64, p3); free(p3); free(p2); @@ -108,15 +109,23 @@ void test_realloc(void) } #define TEST_HEAP_SIZE 1024 + uint8_t TestHeapMemory[TEST_HEAP_SIZE]; + Heap_Control TestHeap; -void test_heap_init() +static void test_heap_default_init() { + memset( &TestHeapMemory, 0x7f, TEST_HEAP_SIZE ); _Heap_Initialize( &TestHeap, TestHeapMemory, TEST_HEAP_SIZE, 0 ); } -void test_heap_cases_1() +static void test_free( void *addr ) +{ + rtems_test_assert( _Heap_Free( &TestHeap, addr ) ); +} + +static void test_heap_cases_1() { void *p1, *p2, *p3, *p4; intptr_t u1, u2; @@ -128,28 +137,28 @@ void test_heap_cases_1() * 32-bit CPU when CPU_ALIGNMENT = 4 (most targets have 8) with the * code like this: */ - test_heap_init(); + test_heap_default_init(); p1 = _Heap_Allocate( &TestHeap, 12 ); p2 = _Heap_Allocate( &TestHeap, 32 ); p3 = _Heap_Allocate( &TestHeap, 32 ); - _Heap_Free( &TestHeap, p2 ); + test_free( p2 ); p2 = _Heap_Allocate_aligned( &TestHeap, 8, 28 ); - _Heap_Free( &TestHeap, p1 ); - _Heap_Free( &TestHeap, p2 ); - _Heap_Free( &TestHeap, p3 ); + test_free( p1 ); + test_free( p2 ); + test_free( p3 ); /* * Odd case in resizing a block. Again test case outline per Sergei */ - test_heap_init(); + test_heap_default_init(); p1 = _Heap_Allocate( &TestHeap, 32 ); p2 = _Heap_Allocate( &TestHeap, 8 ); p3 = _Heap_Allocate( &TestHeap, 32 ); - _Heap_Free( &TestHeap, p2 ); + test_free( p2 ); rsc = _Heap_Resize_block( &TestHeap, p1, 41, &u1, &u2 ); /* XXX what should we expect */ - _Heap_Free( &TestHeap, p3 ); - _Heap_Free( &TestHeap, p1 ); + test_free( p3 ); + test_free( p1 ); /* * To tackle a special case of resizing a block in order to cover the @@ -158,7 +167,7 @@ void test_heap_cases_1() * Re-initialise the heap, so that the blocks created from now on * are contiguous. */ - test_heap_init(); + test_heap_default_init(); puts( "Heap Initialized" ); p1 = _Heap_Allocate( &TestHeap, 500 ); rtems_test_assert( p1 != NULL ); @@ -166,11 +175,425 @@ void test_heap_cases_1() rtems_test_assert( p2 != NULL ); rsc = _Heap_Resize_block( &TestHeap, p1, 256, &u1, &u2 ); rtems_test_assert( rsc == HEAP_RESIZE_SUCCESSFUL ); - _Heap_Free( &TestHeap, p1 ); - _Heap_Free( &TestHeap, p2 ); + test_free( p1 ); + test_free( p2 ); +} + +#define TEST_DEFAULT_PAGE_SIZE 128 + +static void test_heap_init(uintptr_t page_size ) +{ + uintptr_t rv = 0; + + memset( &TestHeapMemory, 0x7f, TEST_HEAP_SIZE ); + + rv = _Heap_Initialize( &TestHeap, TestHeapMemory, TEST_HEAP_SIZE, page_size ); + rtems_test_assert( rv > 0 ); +} + +static void test_check_alloc( + void *alloc_begin_ptr, + void *expected_alloc_begin_ptr, + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary +) +{ + uintptr_t const min_block_size = TestHeap.min_block_size; + uintptr_t const page_size = TestHeap.page_size; + + rtems_test_assert( alloc_begin_ptr == expected_alloc_begin_ptr ); + + if( expected_alloc_begin_ptr != NULL ) { + uintptr_t const alloc_begin = (uintptr_t ) alloc_begin_ptr; + uintptr_t const alloc_end = alloc_begin + alloc_size; + + uintptr_t const alloc_area_begin = _Heap_Align_down( alloc_begin, page_size ); + uintptr_t const alloc_area_offset = alloc_begin - alloc_area_begin; + uintptr_t const alloc_area_size = alloc_area_offset + alloc_size; + + Heap_Block *block = _Heap_Block_of_alloc_area( alloc_area_begin, page_size ); + uintptr_t const block_begin = (uintptr_t ) block; + uintptr_t const block_size = _Heap_Block_size( block ); + uintptr_t const block_end = block_begin + block_size; + + rtems_test_assert( block_size >= min_block_size ); + rtems_test_assert( block_begin < block_end ); + rtems_test_assert( + _Heap_Is_aligned( block_begin + HEAP_BLOCK_HEADER_SIZE, page_size ) + ); + rtems_test_assert( + _Heap_Is_aligned( block_size, page_size ) + ); + + rtems_test_assert( alloc_end <= block_end + HEAP_BLOCK_SIZE_OFFSET ); + rtems_test_assert( alloc_area_begin > block_begin ); + rtems_test_assert( alloc_area_offset < page_size ); + + rtems_test_assert( _Heap_Is_aligned( alloc_area_begin, page_size ) ); + if ( alignment == 0 ) { + rtems_test_assert( alloc_begin == alloc_area_begin ); + } else { + rtems_test_assert( _Heap_Is_aligned( alloc_begin, alignment ) ); + } + + if ( boundary != 0 ) { + uintptr_t boundary_line = _Heap_Align_down( alloc_end, boundary ); + + rtems_test_assert( alloc_size <= boundary ); + rtems_test_assert( + boundary_line <= alloc_begin + || alloc_end <= boundary_line + ); + } + } + + rtems_test_assert( + page_size < CPU_ALIGNMENT + || _Heap_Walk( &TestHeap, 0, false ) + ); +} + +static void test_check_alloc_simple( + void *alloc_begin_ptr, + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary +) +{ + test_check_alloc( + alloc_begin_ptr, + alloc_begin_ptr, + alloc_size, + alignment, + boundary + ); +} + +static void *test_alloc( + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary, + void *expected_alloc_begin_ptr +) +{ + void *alloc_begin_ptr = _Heap_Allocate_aligned_with_boundary( + &TestHeap, + alloc_size, + alignment, + boundary + ); + + test_check_alloc( + alloc_begin_ptr, + expected_alloc_begin_ptr, + alloc_size, + alignment, + boundary + ); + + return alloc_begin_ptr; +} + +static void *test_alloc_simple( + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary +) +{ + void *alloc_begin_ptr = _Heap_Allocate_aligned_with_boundary( + &TestHeap, + alloc_size, + alignment, + boundary + ); + + test_check_alloc_simple( + alloc_begin_ptr, + alloc_size, + alignment, + boundary + ); + + rtems_test_assert( alloc_begin_ptr != NULL ); + + return alloc_begin_ptr; +} + +static void *test_init_and_alloc( + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary, + void *expected_alloc_begin_ptr +) +{ + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + return test_alloc( + alloc_size, + alignment, + boundary, + expected_alloc_begin_ptr + ); +} + +static void *test_init_and_alloc_simple( + uintptr_t alloc_size, + uintptr_t alignment, + uintptr_t boundary +) +{ + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + return test_alloc_simple( + alloc_size, + alignment, + boundary + ); +} + +static uintptr_t test_page_size(void) +{ + return TestHeap.page_size; +} + +static void test_heap_cases_2() +{ + void *p1 = NULL; + void *p2 = NULL; + void *p3 = NULL; + uintptr_t alloc_size = 0; + uintptr_t alignment = 0; + uintptr_t boundary = 0; + uintptr_t page_size = 0; + uintptr_t first_page_begin = 0; + uintptr_t previous_last_block_begin = 0; + uintptr_t previous_last_page_begin = 0; + + uintptr_t first_block_begin = 0; + + uintptr_t last_block_begin = 0; + uintptr_t last_alloc_begin = 0; + + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + first_block_begin = (uintptr_t) TestHeap.first_block; + + last_block_begin = (uintptr_t) TestHeap.last_block; + last_alloc_begin = _Heap_Alloc_area_of_block( TestHeap.last_block ); + + puts( "run tests for _Heap_Allocate_aligned_with_boundary()"); + + puts( "\tcheck if NULL will be returned if size causes integer overflow" ); + + alloc_size = (uintptr_t ) -1; + alignment = 0; + boundary = 0; + test_init_and_alloc( alloc_size, alignment, boundary, NULL ); + + puts( "\ttry to allocate more space than the one which fits in the boundary" ); + + alloc_size = 2; + alignment = 0; + boundary = alloc_size - 1; + test_init_and_alloc( alloc_size, alignment, boundary, NULL ); + + puts( "\tcheck if alignment will be set to page size if only a boundary is given" ); + + alloc_size = 1; + boundary = 1; + + alignment = 0; + p1 = test_init_and_alloc_simple( alloc_size, alignment, boundary ); + + alignment = test_page_size(); + test_init_and_alloc( alloc_size, alignment, boundary, p1 ); + + puts( "\tcreate a block which is bigger then the first free space" ); + + alignment = 0; + boundary = 0; + + alloc_size = test_page_size(); + p1 = test_init_and_alloc_simple( alloc_size, alignment, boundary ); + p2 = test_alloc_simple( alloc_size, alignment, boundary ); + test_free( p1 ); + + alloc_size = 2 * alloc_size; + p3 = test_alloc_simple( alloc_size, alignment, boundary ); + rtems_test_assert( p1 != p3 ); + + puts( "\tset boundary before allocation begin" ); + + alloc_size = 1; + alignment = 0; + boundary = last_alloc_begin - test_page_size(); + p1 = test_init_and_alloc_simple( alloc_size, alignment, boundary ); + rtems_test_assert( (uintptr_t ) p1 >= boundary ); + + puts( "\tset boundary between allocation begin and end" ); + alloc_size = test_page_size(); + alignment = 0; + boundary = last_alloc_begin - alloc_size / 2; + p1 = test_init_and_alloc_simple( alloc_size, alignment, boundary ); + rtems_test_assert( (uintptr_t ) p1 + alloc_size <= boundary ); + + puts( "\tset boundary after allocation end" ); + alloc_size = 1; + alignment = 0; + boundary = last_alloc_begin; + p1 = test_init_and_alloc_simple( alloc_size, alignment, boundary ); + rtems_test_assert( (uintptr_t ) p1 + alloc_size < boundary ); + + puts( "\tset boundary on allocation end" ); + alloc_size = TEST_DEFAULT_PAGE_SIZE - HEAP_BLOCK_HEADER_SIZE; + alignment = 0; + boundary = last_block_begin; + p1 = (void *) (last_alloc_begin - TEST_DEFAULT_PAGE_SIZE); + test_init_and_alloc( alloc_size, alignment, boundary, p1); + + puts( "\talign the allocation to different positions in the block header" ); + + page_size = sizeof(uintptr_t); + alloc_size = 1; + boundary = 0; + + test_heap_init( page_size ); + + /* Force the page size to a small enough value */ + TestHeap.page_size = page_size; + + alignment = first_page_begin - sizeof(uintptr_t); + p1 = test_alloc( alloc_size, alignment, boundary, NULL ); + + first_page_begin = ((uintptr_t) TestHeap.first_block ) + HEAP_BLOCK_HEADER_SIZE; + alignment = first_page_begin + sizeof(uintptr_t); + p1 = test_alloc( alloc_size, alignment, boundary, NULL ); + + first_page_begin = ((uintptr_t) TestHeap.first_block ) + + HEAP_BLOCK_HEADER_SIZE; + alignment = first_page_begin; + p1 = test_alloc_simple( alloc_size, alignment, boundary ); + + puts( "\tallocate last block with different boundarys" ); + page_size = TEST_DEFAULT_PAGE_SIZE; + test_heap_init( page_size ); + previous_last_block_begin = ((uintptr_t) TestHeap.last_block ) + - TestHeap.min_block_size; + previous_last_page_begin = previous_last_block_begin + + HEAP_BLOCK_HEADER_SIZE; + alloc_size = TestHeap.page_size - HEAP_BLOCK_HEADER_SIZE; + alignment = sizeof(uintptr_t); + boundary = 0; + p1 = test_alloc( alloc_size, alignment, boundary, (void *) (previous_last_page_begin + sizeof(uintptr_t))); + + test_heap_init( page_size ); + boundary = ((uintptr_t) TestHeap.last_block ); + p1 = test_alloc( alloc_size, alignment, boundary, (void *) previous_last_page_begin ); + + puts( "\tbreak the boundaries and aligns more than one time" ); + + page_size = CPU_ALIGNMENT * 20; + alloc_size = page_size / 4; + alignment = page_size / 5; + boundary = page_size / 4; + test_heap_init( page_size ); + p1 = (void *) (_Heap_Alloc_area_of_block( TestHeap.last_block ) - page_size ); + test_alloc( alloc_size, alignment, boundary, p1); + + puts( "\tdifferent combinations, so that there is no valid block at the end" ); + + page_size = sizeof(uintptr_t); + + test_heap_init( 0 ); + + /* Force the page size to a small enough value */ + TestHeap.page_size = page_size; + + alloc_size = 1; + alignment = (uintptr_t) TestHeap.last_block; + boundary = 0; + p1 = test_alloc( alloc_size, alignment, boundary, NULL ); + + boundary = (uintptr_t) TestHeap.last_block; + p1 = test_alloc( alloc_size, alignment, boundary, NULL ); + + alloc_size = 0; + p1 = test_alloc( alloc_size, alignment, boundary, NULL ); + + alloc_size = 1; + alignment = sizeof(uintptr_t); + boundary = 0; + p1 = test_alloc_simple( alloc_size, alignment, boundary ); + + puts( "\ttry to create a block, which is not possible because of the alignment and boundary" ); + + alloc_size = 2; + boundary = _Heap_Alloc_area_of_block( TestHeap.first_block ) + + _Heap_Block_size( TestHeap.first_block ) / 2; + alignment = boundary - 1; + p1 = test_init_and_alloc( alloc_size, alignment, boundary, NULL ); + + alloc_size = 2; + alignment = _Heap_Alloc_area_of_block( TestHeap.first_block ); + boundary = alignment + 1; + p1 = test_init_and_alloc( alloc_size, alignment, boundary, NULL ); +} + +static void test_block_alloc( uintptr_t alloc_begin, uintptr_t alloc_size ) +{ + test_heap_init( TEST_DEFAULT_PAGE_SIZE ); + + _Heap_Block_allocate( + &TestHeap, + TestHeap.first_block, + alloc_begin, + alloc_size + ); + + test_check_alloc_simple( (void *) alloc_begin, alloc_size, 0, 0 ); +} + +static void test_heap_cases_block_allocate() +{ + 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 ); + + 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 ); + + 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 ); + + 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 ); } -void test_heap_extend() +static void test_heap_extend() { void *p1, *p2, *p3, *p4; uint32_t u1, u2; @@ -191,7 +614,7 @@ void test_heap_extend() rtems_test_assert( ret == true ); } -void test_heap_info(void) +static void test_heap_info(void) { size_t s1, s2; void *p1; @@ -237,7 +660,7 @@ void test_heap_info(void) rtems_test_assert( s1 == the_info.Free.largest ); } -void test_protected_heap_info(void) +static void test_protected_heap_info(void) { Heap_Control heap; Heap_Information_block info; @@ -252,7 +675,7 @@ void test_protected_heap_info(void) rtems_test_assert( rc == false ); } -void test_heap_resize(void) +static void test_heap_resize(void) { Heap_Resize_status rc; void *p1; @@ -260,7 +683,7 @@ void test_heap_resize(void) intptr_t avail; puts( "Initialize Test Heap" ); - test_heap_init(); + test_heap_default_init(); puts( "Allocate most of heap" ); p1 = _Heap_Allocate( &TestHeap, TEST_HEAP_SIZE - 32 ); @@ -274,7 +697,7 @@ void test_heap_resize(void) /* * A simple test of posix_memalign */ -void test_posix_memalign(void) +static void test_posix_memalign(void) { void *p1, *p2; int i; @@ -333,6 +756,8 @@ rtems_task Init( status = rtems_clock_set( &time ); directive_failed( status, "rtems_clock_set" ); + test_heap_cases_2(); + test_heap_cases_block_allocate(); test_realloc(); test_heap_cases_1(); test_heap_extend(); diff --git a/testsuites/libtests/stackchk/blow.c b/testsuites/libtests/stackchk/blow.c index 66daebf692..07b7585a66 100644 --- a/testsuites/libtests/stackchk/blow.c +++ b/testsuites/libtests/stackchk/blow.c @@ -30,7 +30,7 @@ b(); area = (unsigned char *)_Thread_Executing->Start.Initial_stack.area; - low = (volatile uint32_t *) (area + HEAP_LAST_BLOCK_OVERHEAD); + low = (volatile uint32_t *) (area + HEAP_BLOCK_HEADER_SIZE); high = (volatile uint32_t *) (area + _Thread_Executing->Start.Initial_stack.size - 16); -- cgit v1.2.3