* 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.
This commit is contained in:
Joel Sherrill
2009-09-09 14:59:09 +00:00
parent 518c2aeba2
commit 809fb589fc
7 changed files with 1717 additions and 1173 deletions

View File

@@ -1,3 +1,9 @@
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.
2009-09-03 Christian Mauderer <christian.mauderer@embedded-brains.de>
* malloctest/init.c: New test cases. Update for heap API changes.

View File

@@ -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 ***

View File

@@ -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 );
}
static void *test_allocate_block(void)
{
return _Heap_Allocate_aligned_with_boundary( &TestHeap, 1, 0, 0 );
}
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 );
}
static void *test_fill_heap()
{
void *p1 = NULL;
void *p2 = NULL;
do {
p2 = p1;
p1 = test_allocate_block();
}while( p1 != NULL );
return p2;
}
static void test_system_not_up(void)
{
rtems_interrupt_level level;
puts( "start with a system state != SYSTEM_STATE_UP" );
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_check_control(void)
{
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 );
/*
* Now corrupt all non-zero values
* 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.
*/
for (i=0 ; i<TEST_HEAP_SIZE ; i++) {
original = TestHeapMemory[i];
if ( original == 0 )
continue;
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 );
/* mark it free -- may or may not have already been */
TestHeapMemory[i] &= ~0x01U;
_Heap_Walk( &TestHeap, source, do_dump );
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 );
/* mark it used -- may or may not have already been */
TestHeapMemory[i] |= 0x01;
_Heap_Walk( &TestHeap, source, do_dump );
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 );
/* 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 );
}
/* try 0 and see what that does */
TestHeapMemory[i] = 0x00;
_Heap_Walk( &TestHeap, source, do_dump );
/* try 0xffffffff and see what that does */
TestHeapMemory[i] = 0xffffffff;
_Heap_Walk( &TestHeap, source, do_dump );
TestHeapMemory[i] = original;
}
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_walk_freshly_initialized(void)
static void test_check_free_list(void)
{
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_freshly_initialized(void)
{
puts( "Walk freshly initialized heap" );
test_heap_init();
test_heap_walk(1);
test_heap_init_default();
test_call_heap_walk( true );
}
static void test_negative_source_value(void)
static void test_main_loop(void)
{
/*
* Passing a negative value for source so that
* the control enters the if block on line 67
*/
puts( "Passing negative value for source" );
test_heap_init();
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_prev_block_flag_check(void)
static void test_check_free_block(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 );
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" );
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_not_aligned(void)
static void test_output(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 );
}
static void test_first_block_not_aligned(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 );
}
static void test_not_in_free_list(void)
{
void *p1, *p2, *p3;
/*
* 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( "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);

View File

@@ -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();

File diff suppressed because it is too large Load Diff

View File

@@ -30,7 +30,8 @@ b();
area = (unsigned char *)_Thread_Executing->Start.Initial_stack.area;
low = (volatile uint32_t *) (area + HEAP_BLOCK_HEADER_SIZE);
/* Look in the stack checker implementation for this magic offset */
low = (volatile uint32_t *) (area + sizeof(Heap_Block) - HEAP_BLOCK_HEADER_SIZE);
high = (volatile uint32_t *)
(area + _Thread_Executing->Start.Initial_stack.size - 16);

View File

@@ -1,12 +1,15 @@
*** TEST STACK CHECKER ***
TA1 - rtems_clock_get - 09:00:00 12/31/1988
TA2 - rtems_clock_get - 09:00:00 12/31/1988
TA3 - rtems_clock_get - 09:00:00 12/31/1988
TA1 - rtems_clock_get - 09:00:05 12/31/1988
TA1 - rtems_clock_get - 09:00:10 12/31/1988
TA2 - rtems_clock_get - 09:00:10 12/31/1988
TA1 - rtems_clock_get - 09:00:15 12/31/1988
---> error indication similar to:
BLOWN STACK!!! Offending task(0x23EE7A0): id=0x0A010002; name=0x54413120
stack covers range 0x23F1BD0 - 0x23F4BDF (12304 bytes)
Damaged pattern begins at 0x023F1BD8 and is 16 bytes long
TA1 - rtems_clock_get_tod - 09:00:00 12/31/1988
TA2 - rtems_clock_get_tod - 09:00:00 12/31/1988
TA3 - rtems_clock_get_tod - 09:00:00 12/31/1988
TA1 - rtems_clock_get_tod - 09:00:05 12/31/1988
TA1 - rtems_clock_get_tod - 09:00:10 12/31/1988
TA2 - rtems_clock_get_tod - 09:00:10 12/31/1988
TA1 - rtems_clock_get_tod - 09:00:15 12/31/1988
BLOWN STACK!!!
task control block: 0x????????
task ID: 0x0A010002
task name: 0x????????
task name string: TA1
task stack area (????? Bytes): 0x???????? .. 0x????????
damaged pattern area (16 Bytes): 0x???????? .. 0x????????