diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-08-26 12:00:24 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 2009-08-26 12:00:24 +0000 |
commit | 371cea31d3cffb1e1d2ae2e865d1e9a462a3fbd6 (patch) | |
tree | c407c96dda4ebe8580df10d35a12bc20dd8bc221 /cpukit/score/src | |
parent | Add mpfr_provided for openSUSE 11.0 + 11.1 (diff) | |
download | rtems-371cea31d3cffb1e1d2ae2e865d1e9a462a3fbd6.tar.bz2 |
2009-08-24 Sebastian Huber <Sebastian.Huber@embedded-brains.de>
* libmisc/stackchk/check.c, rtems/src/regionreturnsegment.c,
rtems/src/regiongetsegmentsize.c, src/heapalignupuptr.c,
src/heapallocatealigned.c, src/heapallocate.c, src/heap.c,
src/heapextend.c, src/heapfree.c, src/heapgetfreeinfo.c,
src/heapgetinfo.c, src/heapresizeblock.c, src/heapsizeofuserarea.c,
src/heapwalk.c, src/pheapgetblocksize.c, inline/rtems/score/heap.inl,
include/rtems/score/heap.h: Overall cleanup. Changed all types for
addresses, sizes, offsets and alignments to uintptr_t. Reformatted.
Added variables for clarity. Renamed various objects. Enabled
_HAssert() for all instances. More changes follow.
Diffstat (limited to 'cpukit/score/src')
-rw-r--r-- | cpukit/score/src/heap.c | 242 | ||||
-rw-r--r-- | cpukit/score/src/heapalignupuptr.c | 22 | ||||
-rw-r--r-- | cpukit/score/src/heapallocate.c | 79 | ||||
-rw-r--r-- | cpukit/score/src/heapallocatealigned.c | 78 | ||||
-rw-r--r-- | cpukit/score/src/heapextend.c | 85 | ||||
-rw-r--r-- | cpukit/score/src/heapfree.c | 130 | ||||
-rw-r--r-- | cpukit/score/src/heapgetfreeinfo.c | 4 | ||||
-rw-r--r-- | cpukit/score/src/heapgetinfo.c | 4 | ||||
-rw-r--r-- | cpukit/score/src/heapresizeblock.c | 116 | ||||
-rw-r--r-- | cpukit/score/src/heapsizeofuserarea.c | 91 | ||||
-rw-r--r-- | cpukit/score/src/heapwalk.c | 18 | ||||
-rw-r--r-- | cpukit/score/src/pheapgetblocksize.c | 2 |
12 files changed, 390 insertions, 481 deletions
diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c index df194a6dca..208197d5a3 100644 --- a/cpukit/score/src/heap.c +++ b/cpukit/score/src/heap.c @@ -27,8 +27,8 @@ static uint32_t instance = 0; * This kernel routine initializes a heap. * * Input parameters: - * the_heap - pointer to heap header - * starting_address - starting address of heap + * heap - pointer to heap header + * area_begin - starting address of heap * size - size of heap * page_size - allocatable unit of memory * @@ -39,7 +39,7 @@ static uint32_t instance = 0; * This is what a heap looks like in memory immediately after initialization: * * - * +--------------------------------+ <- begin = starting_address + * +--------------------------------+ <- begin = area_begin * | unused space due to alignment | * | size < page_size | * 0 +--------------------------------+ <- first block @@ -72,7 +72,7 @@ static uint32_t instance = 0; * be split so that upper part of it will become used block (see * 'heapallocatealigned.c' for details).] * - * +--------------------------------+ <- begin = starting_address + * +--------------------------------+ <- begin = area_begin * | unused space due to alignment | * | size < page_size | * 0 +--------------------------------+ <- used block @@ -111,76 +111,68 @@ static uint32_t instance = 0; * */ -uint32_t _Heap_Initialize( - Heap_Control *the_heap, - void *starting_address, - intptr_t size, - uint32_t page_size +uintptr_t _Heap_Initialize( + Heap_Control *heap, + void *area_begin, + uintptr_t area_size, + uintptr_t page_size ) { - Heap_Block *the_block; - uint32_t the_size; - _H_uptr_t start; - _H_uptr_t aligned_start; - uint32_t overhead; - Heap_Statistics *const stats = &the_heap->stats; + Heap_Statistics * const stats = &heap->stats; + uintptr_t heap_area_begin = (uintptr_t) area_begin; + uintptr_t heap_area_end = heap_area_begin + area_size; + uintptr_t alloc_area_begin = heap_area_begin + HEAP_BLOCK_ALLOC_AREA_OFFSET; + uintptr_t alloc_area_size = 0; + uintptr_t overhead = 0; + Heap_Block *first_block = NULL; + Heap_Block *second_block = NULL; - if (page_size == 0) + if ( page_size == 0 ) { page_size = CPU_ALIGNMENT; - else - _Heap_Align_up( &page_size, CPU_ALIGNMENT ); - - /* Calculate aligned_start so that aligned_start + HEAP_BLOCK_USER_OFFSET - (value of user pointer) is aligned on 'page_size' boundary. Make sure - resulting 'aligned_start' is not below 'starting_address'. */ - start = _H_p2u(starting_address); - aligned_start = start + HEAP_BLOCK_USER_OFFSET; - _Heap_Align_up_uptr ( &aligned_start, page_size ); - aligned_start -= HEAP_BLOCK_USER_OFFSET; - - /* Calculate 'min_block_size'. It's HEAP_MIN_BLOCK_SIZE aligned up to the - nearest multiple of 'page_size'. */ - the_heap->min_block_size = HEAP_MIN_BLOCK_SIZE; - _Heap_Align_up ( &the_heap->min_block_size, page_size ); + } else { + page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT ); + } - /* Calculate 'the_size' -- size of the first block so that there is enough - space at the end for the permanent last block. It is equal to 'size' - minus total overhead aligned down to the nearest multiple of - 'page_size'. */ - overhead = HEAP_OVERHEAD + (aligned_start - start); - if ( size < overhead ) - return 0; /* Too small area for the heap */ - the_size = size - overhead; - _Heap_Align_down ( &the_size, page_size ); - if ( the_size == 0 ) - return 0; /* Too small area for the heap */ + heap->min_block_size = _Heap_Align_up( sizeof( Heap_Block ), page_size ); - the_heap->page_size = page_size; - the_heap->begin = starting_address; - the_heap->end = starting_address + size; + alloc_area_begin = _Heap_Align_up( alloc_area_begin, page_size ); + overhead = HEAP_LAST_BLOCK_OVERHEAD + + (alloc_area_begin - HEAP_BLOCK_ALLOC_AREA_OFFSET - heap_area_begin); + alloc_area_size = _Heap_Align_down ( area_size - overhead, page_size ); - the_block = (Heap_Block *) aligned_start; + if ( + heap_area_end < heap_area_begin + || area_size < overhead + || alloc_area_size == 0 + ) { + /* Invalid area or area too small */ + return 0; + } - the_block->prev_size = page_size; - the_block->size = the_size | HEAP_PREV_USED; - the_block->next = _Heap_Tail( the_heap ); - the_block->prev = _Heap_Head( the_heap ); - _Heap_Head(the_heap)->next = the_block; - _Heap_Tail(the_heap)->prev = the_block; - the_heap->start = the_block; + heap->page_size = page_size; + heap->begin = heap_area_begin; + heap->end = heap_area_end; - _HAssert(_Heap_Is_aligned(the_heap->page_size, CPU_ALIGNMENT)); - _HAssert(_Heap_Is_aligned(the_heap->min_block_size, page_size)); - _HAssert(_Heap_Is_aligned_ptr(_Heap_User_area(the_block), page_size)); + /* First block */ + first_block = _Heap_Block_of_alloc_area( alloc_area_begin, page_size ); + first_block->prev_size = page_size; + first_block->size_and_flag = alloc_area_size | HEAP_PREV_BLOCK_USED; + first_block->next = _Heap_Free_list_tail( heap ); + first_block->prev = _Heap_Free_list_head( heap ); + _Heap_Free_list_head( heap )->next = first_block; + _Heap_Free_list_tail( heap )->prev = first_block; + heap->start = first_block; - the_block = _Heap_Block_at( the_block, the_size ); - the_heap->final = the_block; /* Permanent final block of the heap */ - the_block->prev_size = the_size; /* Previous block is free */ - the_block->size = page_size; + /* Second and last block */ + second_block = _Heap_Block_at( first_block, alloc_area_size ); + second_block->prev_size = alloc_area_size; + second_block->size_and_flag = page_size | HEAP_PREV_BLOCK_FREE; + heap->final = second_block; - stats->size = size; - stats->free_size = the_size; - stats->min_free_size = the_size; + /* Statistics */ + stats->size = area_size; + stats->free_size = alloc_area_size; + stats->min_free_size = alloc_area_size; stats->free_blocks = 1; stats->max_free_blocks = 1; stats->used_blocks = 0; @@ -191,78 +183,82 @@ uint32_t _Heap_Initialize( stats->resizes = 0; stats->instance = instance++; - return ( the_size - HEAP_BLOCK_USED_OVERHEAD ); -} + _HAssert( _Heap_Is_aligned( CPU_ALIGNMENT, 4 )); + _HAssert( _Heap_Is_aligned( heap->page_size, CPU_ALIGNMENT )); + _HAssert( _Heap_Is_aligned( heap->min_block_size, page_size )); + _HAssert( + _Heap_Is_aligned( _Heap_Alloc_area_of_block( first_block ), page_size ) + ); + _HAssert( + _Heap_Is_aligned( _Heap_Alloc_area_of_block( second_block ), page_size ) + ); -/*PAGE - * - * Internal routines shared by _Heap_Allocate() and _Heap_Allocate_aligned(). - * - * Note: there is no reason to put them into a separate file(s) as they are - * always required for heap to be useful. - */ + return alloc_area_size; +} -/* - * Convert user requested 'size' of memory block to the block size. - * Return block size on success, 0 if overflow occured - */ -size_t _Heap_Calc_block_size( - size_t size, - uint32_t page_size, - uint32_t min_size) +uintptr_t _Heap_Calc_block_size( + uintptr_t alloc_size, + uintptr_t page_size, + uintptr_t min_block_size) { - uint32_t block_size = size + HEAP_BLOCK_USED_OVERHEAD; - _Heap_Align_up(&block_size, page_size); - if (block_size < min_size) block_size = min_size; - /* 'block_size' becomes <= 'size' if and only if overflow occured. */ - return (block_size > size) ? block_size : 0; + uintptr_t block_size = + _Heap_Align_up( alloc_size + HEAP_BLOCK_USED_OVERHEAD, page_size ); + + if (block_size < min_block_size) { + block_size = min_block_size; + } + + if (block_size > alloc_size) { + return block_size; + } else { + /* Integer overflow occured */ + return 0; + } } -/* - * Allocate block of size 'alloc_size' from 'the_block' belonging to - * 'the_heap'. Split 'the_block' if possible, otherwise allocate it entirely. - * When split, make the lower part used, and leave the upper part free. - * Return the size of allocated block. - */ -uint32_t _Heap_Block_allocate( - Heap_Control* the_heap, - Heap_Block* the_block, - uint32_t alloc_size +uintptr_t _Heap_Block_allocate( + Heap_Control *heap, + Heap_Block *block, + uintptr_t alloc_size ) { - Heap_Statistics *const stats = &the_heap->stats; - uint32_t const block_size = _Heap_Block_size(the_block); - uint32_t const the_rest = block_size - alloc_size; + Heap_Statistics * const stats = &heap->stats; + uintptr_t const block_size = _Heap_Block_size( block ); + uintptr_t const unused_size = block_size - alloc_size; + Heap_Block *next_block = _Heap_Block_at( block, block_size ); - _HAssert(_Heap_Is_aligned(block_size, the_heap->page_size)); - _HAssert(_Heap_Is_aligned(alloc_size, the_heap->page_size)); - _HAssert(alloc_size <= block_size); - _HAssert(_Heap_Is_prev_used(the_block)); + _HAssert( _Heap_Is_aligned( block_size, heap->page_size )); + _HAssert( _Heap_Is_aligned( alloc_size, heap->page_size )); + _HAssert( alloc_size <= block_size ); + _HAssert( _Heap_Is_prev_used( block )); - if(the_rest >= the_heap->min_block_size) { - /* Split the block so that upper part is still free, and lower part - becomes used. This is slightly less optimal than leaving lower part - free as it requires replacing block in the free blocks list, but it - makes it possible to reuse this code in the _Heap_Resize_block(). */ - Heap_Block *next_block = _Heap_Block_at(the_block, alloc_size); - _Heap_Block_replace(the_block, next_block); - the_block->size = alloc_size | HEAP_PREV_USED; - next_block->size = the_rest | HEAP_PREV_USED; - _Heap_Block_at(next_block, the_rest)->prev_size = the_rest; - } - else { - /* Don't split the block as remainder is either zero or too small to be - used as a separate free block. Change 'alloc_size' to the size of the - block and remove the block from the list of free blocks. */ - _Heap_Block_remove(the_block); + if (unused_size >= heap->min_block_size) { + /* + * Split the block so that the upper part is still free, and the lower part + * becomes used. This is slightly less optimal than leaving the lower part + * free as it requires replacing block in the free blocks list, but it + * makes it possible to reuse this code in the _Heap_Resize_block(). + */ + Heap_Block *new_block = _Heap_Block_at( block, alloc_size ); + block->size_and_flag = alloc_size | HEAP_PREV_BLOCK_USED; + new_block->size_and_flag = unused_size | HEAP_PREV_BLOCK_USED; + next_block->prev_size = unused_size; + _Heap_Block_replace_in_free_list( block, new_block ); + } else { + next_block->size_and_flag |= HEAP_PREV_BLOCK_USED; alloc_size = block_size; - _Heap_Block_at(the_block, alloc_size)->size |= HEAP_PREV_USED; - stats->free_blocks -= 1; + _Heap_Block_remove_from_free_list( block ); + + /* Statistics */ + --stats->free_blocks; } - /* Update statistics */ + + /* Statistics */ + ++stats->used_blocks; stats->free_size -= alloc_size; - if(stats->min_free_size > stats->free_size) + if(stats->min_free_size > stats->free_size) { stats->min_free_size = stats->free_size; - stats->used_blocks += 1; + } + return alloc_size; } diff --git a/cpukit/score/src/heapalignupuptr.c b/cpukit/score/src/heapalignupuptr.c index dbfe0f83cb..966d5d8649 100644 --- a/cpukit/score/src/heapalignupuptr.c +++ b/cpukit/score/src/heapalignupuptr.c @@ -1,3 +1,4 @@ +#if 0 /* * Heap Handler * @@ -23,18 +24,17 @@ * path explosion where it is used. This makes full test coverage more * difficult. */ -void _Heap_Align_up_uptr ( - _H_uptr_t *value, - uint32_t alignment +uintptr_t _Heap_Align_up( + uintptr_t value, + uintptr_t alignment ) { - _H_uptr_t remainder; - _H_uptr_t v = *value; + uintptr_t remainder = value % alignment; - remainder = v % alignment; - - if ( remainder ) - *value = v - remainder + alignment; + if ( remainder != 0 ) { + return value - remainder + alignment; + } else { + return value; + } } - - +#endif diff --git a/cpukit/score/src/heapallocate.c b/cpukit/score/src/heapallocate.c index 86164d209c..7c9e78f31e 100644 --- a/cpukit/score/src/heapallocate.c +++ b/cpukit/score/src/heapallocate.c @@ -19,63 +19,48 @@ #include <rtems/score/sysstate.h> #include <rtems/score/heap.h> -/*PAGE - * - * _Heap_Allocate - * - * This kernel routine allocates the requested size of memory - * from the specified heap. - * - * Input parameters: - * the_heap - pointer to heap header. - * size - size in bytes of the memory block to allocate. - * - * Output parameters: - * returns - starting address of memory block allocated - */ - -void *_Heap_Allocate( - Heap_Control *the_heap, - intptr_t size -) +void *_Heap_Allocate( Heap_Control *heap, uintptr_t size ) { - uint32_t the_size; - uint32_t search_count; - Heap_Block *the_block; - void *ptr = NULL; - Heap_Statistics *const stats = &the_heap->stats; - Heap_Block *const tail = _Heap_Tail(the_heap); + Heap_Statistics *const stats = &heap->stats; + Heap_Block * const tail = _Heap_Free_list_tail( heap ); + Heap_Block *block = _Heap_First_free_block( heap ); + uint32_t search_count = 0; + void *alloc_area_begin_ptr = NULL; - the_size = - _Heap_Calc_block_size(size, the_heap->page_size, the_heap->min_block_size); - if(the_size == 0) + size = _Heap_Calc_block_size( size, heap->page_size, heap->min_block_size ); + if( size == 0 ) { return NULL; + } - /* Find large enough free block. */ - for(the_block = _Heap_First(the_heap), search_count = 0; - the_block != tail; - the_block = the_block->next, ++search_count) - { - /* As we always coalesce free blocks, prev block must have been used. */ - _HAssert(_Heap_Is_prev_used(the_block)); + /* + * Find large enough free block. + * + * Do not bother to mask out the HEAP_PREV_BLOCK_USED bit as it will not + * change the result of the size comparison. + */ + while (block != tail && block->size_and_flag < size) { + _HAssert( _Heap_Is_prev_used( block )); - /* Don't bother to mask out the HEAP_PREV_USED bit as it won't change the - result of the comparison. */ - if(the_block->size >= the_size) { - (void)_Heap_Block_allocate(the_heap, the_block, the_size ); + block = block->next; + ++search_count; + } - ptr = _Heap_User_area(the_block); + if (block != tail) { + _Heap_Block_allocate( heap, block, size ); - stats->allocs += 1; - stats->searches += search_count + 1; + alloc_area_begin_ptr = (void *) _Heap_Alloc_area_of_block( block ); - _HAssert(_Heap_Is_aligned_ptr(ptr, the_heap->page_size)); - break; - } + _HAssert( _Heap_Is_aligned( (uintptr_t) alloc_area_begin_ptr, heap->page_size )); + + /* Statistics */ + ++stats->allocs; + stats->searches += search_count; } - if(stats->max_search < search_count) + /* Statistics */ + if (stats->max_search < search_count) { stats->max_search = search_count; + } - return ptr; + return alloc_area_begin_ptr; } diff --git a/cpukit/score/src/heapallocatealigned.c b/cpukit/score/src/heapallocatealigned.c index b0d63f9880..935c3509aa 100644 --- a/cpukit/score/src/heapallocatealigned.c +++ b/cpukit/score/src/heapallocatealigned.c @@ -25,19 +25,19 @@ static void check_result( Heap_Control *the_heap, Heap_Block *the_block, - _H_uptr_t user_addr, - _H_uptr_t aligned_user_addr, - intptr_t size + uintptr_t user_addr, + uintptr_t aligned_user_addr, + uintptr_t size ) { - _H_uptr_t const user_area = _H_p2u(_Heap_User_area(the_block)); - _H_uptr_t const block_end = _H_p2u(the_block) - + _Heap_Block_size(the_block) + HEAP_BLOCK_HEADER_OFFSET; - _H_uptr_t const user_end = aligned_user_addr + size; - _H_uptr_t const heap_start = _H_p2u(the_heap->start) + HEAP_OVERHEAD; - _H_uptr_t const heap_end = _H_p2u(the_heap->final) - + HEAP_BLOCK_HEADER_OFFSET; - uint32_t const page_size = the_heap->page_size; + uintptr_t const user_area = _Heap_Alloc_area_of_block(the_block); + uintptr_t const block_end = the_block + + _Heap_Block_size(the_block) + HEAP_BLOCK_SIZE_OFFSET; + uintptr_t const user_end = aligned_user_addr + size; + uintptr_t const heap_start = (uintptr_t) the_heap->start + HEAP_LAST_BLOCK_OVERHEAD; + uintptr_t const heap_end = (uintptr_t) the_heap->final + + HEAP_BLOCK_SIZE_OFFSET; + uintptr_t const page_size = the_heap->page_size; _HAssert(user_addr == user_area); _HAssert(aligned_user_addr - user_area < page_size); @@ -74,12 +74,12 @@ static Heap_Block *block_allocate( Heap_Control *the_heap, Heap_Block *the_block, - intptr_t alloc_size + uintptr_t alloc_size ) { Heap_Statistics *const stats = &the_heap->stats; - uint32_t const block_size = _Heap_Block_size(the_block); - uint32_t const the_rest = block_size - alloc_size; + uintptr_t const block_size = _Heap_Block_size(the_block); + uintptr_t const the_rest = block_size - alloc_size; _HAssert(_Heap_Is_aligned(block_size, the_heap->page_size)); _HAssert(_Heap_Is_aligned(alloc_size, the_heap->page_size)); @@ -89,20 +89,20 @@ Heap_Block *block_allocate( if (the_rest >= the_heap->min_block_size) { /* Split the block so that lower part is still free, and upper part becomes used. */ - the_block->size = the_rest | HEAP_PREV_USED; + the_block->size_and_flag = the_rest | HEAP_PREV_BLOCK_USED; the_block = _Heap_Block_at(the_block, the_rest); the_block->prev_size = the_rest; - the_block->size = alloc_size; + the_block->size_and_flag = alloc_size; } else { /* Don't split the block as remainder is either zero or too small to be used as a separate free block. Change 'alloc_size' to the size of the block and remove the block from the list of free blocks. */ - _Heap_Block_remove(the_block); + _Heap_Block_remove_from_free_list(the_block); alloc_size = block_size; stats->free_blocks -= 1; } /* Mark the block as used (in the next block). */ - _Heap_Block_at(the_block, alloc_size)->size |= HEAP_PREV_USED; + _Heap_Block_at(the_block, alloc_size)->size_and_flag |= HEAP_PREV_BLOCK_USED; /* Update statistics */ stats->free_size -= alloc_size; if (stats->min_free_size > stats->free_size) @@ -132,21 +132,21 @@ Heap_Block *block_allocate( void *_Heap_Allocate_aligned( Heap_Control *the_heap, - intptr_t size, - uint32_t alignment + uintptr_t size, + uintptr_t alignment ) { - uint32_t search_count; + uintptr_t search_count; Heap_Block *the_block; void *user_ptr = NULL; - uint32_t const page_size = the_heap->page_size; + uintptr_t const page_size = the_heap->page_size; Heap_Statistics *const stats = &the_heap->stats; - Heap_Block *const tail = _Heap_Tail(the_heap); + Heap_Block *const tail = _Heap_Free_list_tail(the_heap); - uint32_t const end_to_user_offs = size - HEAP_BLOCK_HEADER_OFFSET; + uintptr_t const end_to_user_offs = size - HEAP_BLOCK_SIZE_OFFSET; - uint32_t const the_size = + uintptr_t const the_size = _Heap_Calc_block_size(size, page_size, the_heap->min_block_size); if (the_size == 0) @@ -157,35 +157,34 @@ void *_Heap_Allocate_aligned( /* Find large enough free block that satisfies the alignment requirements. */ - for (the_block = _Heap_First(the_heap), search_count = 0; + for (the_block = _Heap_First_free_block(the_heap), search_count = 0; the_block != tail; the_block = the_block->next, ++search_count) { - uint32_t const block_size = _Heap_Block_size(the_block); + uintptr_t const block_size = _Heap_Block_size(the_block); /* As we always coalesce free blocks, prev block must have been used. */ _HAssert(_Heap_Is_prev_used(the_block)); if (block_size >= the_size) { /* the_block is large enough. */ - _H_uptr_t user_addr; - _H_uptr_t aligned_user_addr; - _H_uptr_t const user_area = _H_p2u(_Heap_User_area(the_block)); + uintptr_t user_addr; + uintptr_t aligned_user_addr; + uintptr_t const user_area = _Heap_Alloc_area_of_block(the_block); /* Calculate 'aligned_user_addr' that will become the user pointer we return. It should be at least 'end_to_user_offs' bytes less than the the 'block_end' and should be aligned on 'alignment' boundary. Calculations are from the 'block_end' as we are going to split free block so that the upper part of the block becomes used block. */ - _H_uptr_t const block_end = _H_p2u(the_block) + block_size; - aligned_user_addr = block_end - end_to_user_offs; - _Heap_Align_down_uptr(&aligned_user_addr, alignment); + uintptr_t const block_end = (uintptr_t) the_block + block_size; + aligned_user_addr = + _Heap_Align_down(block_end - end_to_user_offs, alignment); /* 'user_addr' is the 'aligned_user_addr' further aligned down to the 'page_size' boundary. We need it as blocks' user areas should begin only at 'page_size' aligned addresses */ - user_addr = aligned_user_addr; - _Heap_Align_down_uptr(&user_addr, page_size); + user_addr = _Heap_Align_down(aligned_user_addr, page_size); /* Make sure 'user_addr' calculated didn't run out of 'the_block'. */ if (user_addr >= user_area) { @@ -210,8 +209,7 @@ void *_Heap_Allocate_aligned( /* The user pointer will be too far from 'user_addr'. See if we can make 'aligned_user_addr' to be close enough to the 'user_addr'. */ - aligned_user_addr = user_addr; - _Heap_Align_up_uptr(&aligned_user_addr, alignment); + aligned_user_addr = _Heap_Align_up(user_addr, alignment); if (aligned_user_addr - user_addr >= page_size) { /* No, we can't use the block */ continue; @@ -221,10 +219,10 @@ void *_Heap_Allocate_aligned( /* The block is indeed acceptable: calculate the size of the block to be allocated and perform allocation. */ - uint32_t const alloc_size = - block_end - user_addr + HEAP_BLOCK_USER_OFFSET; + uintptr_t const alloc_size = + block_end - user_addr + HEAP_BLOCK_ALLOC_AREA_OFFSET; - _HAssert(_Heap_Is_aligned_ptr((void*)aligned_user_addr, alignment)); + _HAssert(_Heap_Is_aligned(aligned_user_addr, alignment)); the_block = block_allocate(the_heap, the_block, alloc_size); diff --git a/cpukit/score/src/heapextend.c b/cpukit/score/src/heapextend.c index 340fc84db2..bb3f301235 100644 --- a/cpukit/score/src/heapextend.c +++ b/cpukit/score/src/heapextend.c @@ -19,38 +19,21 @@ #include <rtems/score/sysstate.h> #include <rtems/score/heap.h> -/*PAGE - * - * _Heap_Extend - * - * This routine grows the_heap memory area using the size bytes which - * begin at starting_address. - * - * Input parameters: - * the_heap - pointer to heap header. - * starting_address - pointer to the memory area. - * size - size in bytes of the memory block to allocate. - * - * Output parameters: - * *amount_extended - amount of memory added to the_heap - */ - Heap_Extend_status _Heap_Extend( - Heap_Control *the_heap, - void *starting_address, - intptr_t size, - intptr_t *amount_extended + Heap_Control *heap, + void *area_begin_ptr, + uintptr_t area_size, + uintptr_t *amount_extended ) { - uint32_t the_size; - Heap_Statistics *const stats = &the_heap->stats; - - /* - * The overhead was taken from the original heap memory. - */ - - Heap_Block *old_final; - Heap_Block *new_final; + Heap_Statistics *const stats = &heap->stats; + uintptr_t const area_begin = (uintptr_t) area_begin_ptr; + uintptr_t const heap_area_begin = heap->begin; + uintptr_t const heap_area_end = heap->end; + uintptr_t const new_heap_area_end = heap_area_end + area_size; + uintptr_t extend_size = 0; + Heap_Block *const old_final = heap->final; + Heap_Block *new_final = NULL; /* * There are five possibilities for the location of starting @@ -65,13 +48,11 @@ Heap_Extend_status _Heap_Extend( * As noted, this code only supports (4). */ - if ( starting_address >= the_heap->begin && /* case 3 */ - starting_address < the_heap->end - ) - return HEAP_EXTEND_ERROR; - - if ( starting_address != the_heap->end ) - return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1, 2, and 5 */ + if ( area_begin >= heap_area_begin && area_begin < heap_area_end ) { + return HEAP_EXTEND_ERROR; /* case 3 */ + } else if ( area_begin != heap_area_end ) { + return HEAP_EXTEND_NOT_IMPLEMENTED; /* cases 1, 2, and 5 */ + } /* * Currently only case 4 should make it to this point. @@ -79,26 +60,28 @@ Heap_Extend_status _Heap_Extend( * block and free it. */ - old_final = the_heap->final; - the_heap->end = _Addresses_Add_offset( the_heap->end, size ); - the_size = _Addresses_Subtract( the_heap->end, old_final ) - HEAP_OVERHEAD; - _Heap_Align_down( &the_size, the_heap->page_size ); + heap->end = new_heap_area_end; + + extend_size = new_heap_area_end + - (uintptr_t) old_final - HEAP_LAST_BLOCK_OVERHEAD; + extend_size = _Heap_Align_down( extend_size, heap->page_size ); - *amount_extended = size; + *amount_extended = extend_size; - if( the_size < the_heap->min_block_size ) - return HEAP_EXTEND_SUCCESSFUL; + if( extend_size >= heap->min_block_size ) { + old_final->size_and_flag = extend_size + | (old_final->size_and_flag & HEAP_PREV_BLOCK_USED); + new_final = _Heap_Block_at( old_final, extend_size ); + new_final->size_and_flag = heap->page_size | HEAP_PREV_BLOCK_USED; - old_final->size = the_size | (old_final->size & HEAP_PREV_USED); - new_final = _Heap_Block_at( old_final, the_size ); - new_final->size = HEAP_PREV_USED; - the_heap->final = new_final; + heap->final = new_final; - stats->size += size; - stats->used_blocks += 1; - stats->frees -= 1; /* Don't count subsequent call as actual free() */ + stats->size += area_size; + ++stats->used_blocks; + --stats->frees; /* Do not count subsequent call as actual free() */ - _Heap_Free( the_heap, _Heap_User_area( old_final ) ); + _Heap_Free( heap, (void *) _Heap_Alloc_area_of_block( old_final )); + } return HEAP_EXTEND_SUCCESSFUL; } diff --git a/cpukit/score/src/heapfree.c b/cpukit/score/src/heapfree.c index 09bdd9d1eb..9d5be9e290 100644 --- a/cpukit/score/src/heapfree.c +++ b/cpukit/score/src/heapfree.c @@ -19,69 +19,51 @@ #include <rtems/score/sysstate.h> #include <rtems/score/heap.h> -/*PAGE - * - * _Heap_Free - * - * This kernel routine returns the memory designated by the - * given heap and given starting address to the memory pool. - * - * Input parameters: - * the_heap - pointer to heap header - * starting_address - starting address of the memory block to free. - * - * Output parameters: - * true - if starting_address is valid heap address - * false - if starting_address is invalid heap address - */ - -bool _Heap_Free( - Heap_Control *the_heap, - void *starting_address -) +bool _Heap_Free( Heap_Control *heap, void *alloc_area_begin_ptr ) { - Heap_Block *the_block; - Heap_Block *next_block; - uint32_t the_size; - uint32_t next_size; - Heap_Statistics *const stats = &the_heap->stats; - bool next_is_free; - - if ( !_Addresses_Is_in_range( - starting_address, (void *)the_heap->start, (void *)the_heap->final ) ) { - _HAssert(starting_address != NULL); - return( false ); + Heap_Statistics *const stats = &heap->stats; + uintptr_t alloc_area_begin = (uintptr_t) alloc_area_begin_ptr; + Heap_Block *block = + _Heap_Block_of_alloc_area( alloc_area_begin, heap->page_size ); + Heap_Block *next_block = NULL; + uintptr_t block_size = 0; + uintptr_t next_block_size = 0; + bool next_is_free = false; + + if ( + !_Addresses_Is_in_range( alloc_area_begin_ptr, heap->start, heap->final) + ) { + _HAssert( alloc_area_begin_ptr != NULL ); + return false; } - _Heap_Start_of_block( the_heap, starting_address, &the_block ); - - if ( !_Heap_Is_block_in( the_heap, the_block ) ) { + if ( !_Heap_Is_block_in_heap( heap, block ) ) { _HAssert( false ); - return( false ); + return false; } - the_size = _Heap_Block_size( the_block ); - next_block = _Heap_Block_at( the_block, the_size ); + block_size = _Heap_Block_size( block ); + next_block = _Heap_Block_at( block, block_size ); - if ( !_Heap_Is_block_in( the_heap, next_block ) ) { + if ( !_Heap_Is_block_in_heap( heap, next_block ) ) { _HAssert( false ); - return( false ); + return false; } if ( !_Heap_Is_prev_used( next_block ) ) { _HAssert( false ); - return( false ); + return false; } - next_size = _Heap_Block_size( next_block ); - next_is_free = next_block < the_heap->final && - !_Heap_Is_prev_used(_Heap_Block_at(next_block, next_size)); + next_block_size = _Heap_Block_size( next_block ); + next_is_free = next_block != heap->final + && !_Heap_Is_prev_used( _Heap_Block_at( next_block, next_block_size )); - if ( !_Heap_Is_prev_used( the_block ) ) { - uint32_t const prev_size = the_block->prev_size; - Heap_Block *const prev_block = _Heap_Block_at( the_block, -prev_size ); + if ( !_Heap_Is_prev_used( block ) ) { + uintptr_t const prev_size = block->prev_size; + Heap_Block * const prev_block = _Heap_Block_at( block, -prev_size ); - if ( !_Heap_Is_block_in( the_heap, prev_block ) ) { + if ( !_Heap_Is_block_in_heap( heap, prev_block ) ) { _HAssert( false ); return( false ); } @@ -94,44 +76,44 @@ bool _Heap_Free( } if ( next_is_free ) { /* coalesce both */ - uint32_t const size = the_size + prev_size + next_size; - _Heap_Block_remove( next_block ); + uintptr_t const size = block_size + prev_size + next_block_size; + _Heap_Block_remove_from_free_list( next_block ); stats->free_blocks -= 1; - prev_block->size = size | HEAP_PREV_USED; + prev_block->size_and_flag = size | HEAP_PREV_BLOCK_USED; next_block = _Heap_Block_at( prev_block, size ); _HAssert(!_Heap_Is_prev_used( next_block)); next_block->prev_size = size; - } - else { /* coalesce prev */ - uint32_t const size = the_size + prev_size; - prev_block->size = size | HEAP_PREV_USED; - next_block->size &= ~HEAP_PREV_USED; + } else { /* coalesce prev */ + uintptr_t const size = block_size + prev_size; + prev_block->size_and_flag = size | HEAP_PREV_BLOCK_USED; + next_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED; next_block->prev_size = size; } - } - else if ( next_is_free ) { /* coalesce next */ - uint32_t const size = the_size + next_size; - _Heap_Block_replace( next_block, the_block ); - the_block->size = size | HEAP_PREV_USED; - next_block = _Heap_Block_at( the_block, size ); + } else if ( next_is_free ) { /* coalesce next */ + uintptr_t const size = block_size + next_block_size; + _Heap_Block_replace_in_free_list( next_block, block ); + block->size_and_flag = size | HEAP_PREV_BLOCK_USED; + next_block = _Heap_Block_at( block, size ); next_block->prev_size = size; - } - else { /* no coalesce */ - /* Add 'the_block' to the head of the free blocks list as it tends to + } else { /* no coalesce */ + /* Add 'block' to the head of the free blocks list as it tends to produce less fragmentation than adding to the tail. */ - _Heap_Block_insert_after( _Heap_Head( the_heap), the_block ); - the_block->size = the_size | HEAP_PREV_USED; - next_block->size &= ~HEAP_PREV_USED; - next_block->prev_size = the_size; - - stats->free_blocks += 1; - if ( stats->max_free_blocks < stats->free_blocks ) + _Heap_Block_insert_after( _Heap_Free_list_head( heap), block ); + block->size_and_flag = block_size | HEAP_PREV_BLOCK_USED; + next_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED; + next_block->prev_size = block_size; + + /* Statistics */ + ++stats->free_blocks; + if ( stats->max_free_blocks < stats->free_blocks ) { stats->max_free_blocks = stats->free_blocks; + } } - stats->used_blocks -= 1; - stats->free_size += the_size; - stats->frees += 1; + /* Statistics */ + --stats->used_blocks; + ++stats->frees; + stats->free_size += block_size; return( true ); } diff --git a/cpukit/score/src/heapgetfreeinfo.c b/cpukit/score/src/heapgetfreeinfo.c index b53931414b..a288529cad 100644 --- a/cpukit/score/src/heapgetfreeinfo.c +++ b/cpukit/score/src/heapgetfreeinfo.c @@ -40,13 +40,13 @@ void _Heap_Get_free_information( ) { Heap_Block *the_block; - Heap_Block *const tail = _Heap_Tail(the_heap); + Heap_Block *const tail = _Heap_Free_list_tail(the_heap); info->number = 0; info->largest = 0; info->total = 0; - for(the_block = _Heap_First(the_heap); + for(the_block = _Heap_First_free_block(the_heap); the_block != tail; the_block = the_block->next) { diff --git a/cpukit/score/src/heapgetinfo.c b/cpukit/score/src/heapgetinfo.c index eb06e0af69..7f907170b9 100644 --- a/cpukit/score/src/heapgetinfo.c +++ b/cpukit/score/src/heapgetinfo.c @@ -41,7 +41,7 @@ Heap_Get_information_status _Heap_Get_information( Heap_Block *the_block = the_heap->start; Heap_Block *const end = the_heap->final; - _HAssert(the_block->prev_size == HEAP_PREV_USED); + _HAssert(the_block->prev_size == the_heap->page_size); _HAssert(_Heap_Is_prev_used(the_block)); the_info->Free.number = 0; @@ -74,7 +74,7 @@ Heap_Get_information_status _Heap_Get_information( * "used" as client never allocated it. Make 'Used.total' contain this * blocks' overhead though. */ - the_info->Used.total += HEAP_OVERHEAD; + the_info->Used.total += HEAP_LAST_BLOCK_OVERHEAD; return HEAP_GET_INFORMATION_SUCCESSFUL; } diff --git a/cpukit/score/src/heapresizeblock.c b/cpukit/score/src/heapresizeblock.c index c744d4ff88..8916bbe12c 100644 --- a/cpukit/score/src/heapresizeblock.c +++ b/cpukit/score/src/heapresizeblock.c @@ -19,103 +19,79 @@ #include <rtems/score/sysstate.h> #include <rtems/score/heap.h> -/* - * _Heap_Resize_block - * - * DESCRIPTION: - * - * This routine tries to resize in place the block that is pointed to by the - * 'starting_address' to the new 'size'. - * - * Input parameters: - * the_heap - pointer to heap header - * starting_address - starting address of the memory block - * size - new size - * - * Output parameters: - * 'old_mem_size' - the size of the user memory area of the block before - * resizing. - * 'avail_mem_size' - the size of the user memory area of the free block - * that has been enlarged or created due to resizing, - * 0 if none. - * Returns - * HEAP_RESIZE_SUCCESSFUL - if success - * HEAP_RESIZE_UNSATISFIED - if the block can't be resized in place - * HEAP_RESIZE_FATAL_ERROR - if failure - */ - Heap_Resize_status _Heap_Resize_block( - Heap_Control *the_heap, - void *starting_address, - intptr_t size, - intptr_t *old_mem_size, - intptr_t *avail_mem_size + Heap_Control *heap, + void *alloc_area_begin_ptr, + uintptr_t size, + uintptr_t *old_mem_size, + uintptr_t *avail_mem_size ) { - Heap_Block *the_block; + uintptr_t alloc_area_begin = (uintptr_t) alloc_area_begin_ptr; + Heap_Block *block; Heap_Block *next_block; - uint32_t next_block_size; + uintptr_t next_block_size; bool next_is_used; Heap_Block *next_next_block; - uint32_t old_block_size; - uint32_t old_user_size; - uint32_t prev_used_flag; - Heap_Statistics *const stats = &the_heap->stats; - uint32_t const min_block_size = the_heap->min_block_size; - uint32_t const page_size = the_heap->page_size; + uintptr_t old_block_size; + uintptr_t old_user_size; + uintptr_t prev_used_flag; + Heap_Statistics *const stats = &heap->stats; + uintptr_t const min_block_size = heap->min_block_size; + uintptr_t const page_size = heap->page_size; *old_mem_size = 0; *avail_mem_size = 0; - _Heap_Start_of_block(the_heap, starting_address, &the_block); - _HAssert(_Heap_Is_block_in(the_heap, the_block)); - if (!_Heap_Is_block_in(the_heap, the_block)) + block = _Heap_Block_of_alloc_area(alloc_area_begin, heap->page_size); + _HAssert(_Heap_Is_block_in_heap(heap, block)); + if (!_Heap_Is_block_in_heap(heap, block)) return HEAP_RESIZE_FATAL_ERROR; - prev_used_flag = the_block->size & HEAP_PREV_USED; - old_block_size = _Heap_Block_size(the_block); - next_block = _Heap_Block_at(the_block, old_block_size); + prev_used_flag = block->size_and_flag & HEAP_PREV_BLOCK_USED; + old_block_size = _Heap_Block_size(block); + next_block = _Heap_Block_at(block, old_block_size); - _HAssert(_Heap_Is_block_in(the_heap, next_block)); + _HAssert(_Heap_Is_block_in_heap(heap, next_block)); _HAssert(_Heap_Is_prev_used(next_block)); - if ( !_Heap_Is_block_in(the_heap, next_block) || + if ( !_Heap_Is_block_in_heap(heap, next_block) || !_Heap_Is_prev_used(next_block)) return HEAP_RESIZE_FATAL_ERROR; next_block_size = _Heap_Block_size(next_block); next_next_block = _Heap_Block_at(next_block, next_block_size); - next_is_used = (next_block == the_heap->final) || + next_is_used = (next_block == heap->final) || _Heap_Is_prev_used(next_next_block); - /* See _Heap_Size_of_user_area() source for explanations */ - old_user_size = _Addresses_Subtract(next_block, starting_address) - + HEAP_BLOCK_HEADER_OFFSET; + /* See _Heap_Size_of_alloc_area() source for explanations */ + old_user_size = (uintptr_t) next_block - alloc_area_begin + + HEAP_BLOCK_SIZE_OFFSET; *old_mem_size = old_user_size; if (size > old_user_size) { /* Need to extend the block: allocate part of the next block and then - merge 'the_block' and allocated block together. */ + merge 'block' and allocated block together. */ if (next_is_used) /* Next block is in use, -- no way to extend */ return HEAP_RESIZE_UNSATISFIED; else { - uint32_t add_block_size = size - old_user_size; - _Heap_Align_up(&add_block_size, page_size); + uintptr_t add_block_size = + _Heap_Align_up(size - old_user_size, page_size); if (add_block_size < min_block_size) add_block_size = min_block_size; if (add_block_size > next_block_size) return HEAP_RESIZE_UNSATISFIED; /* Next block is too small or none. */ add_block_size = - _Heap_Block_allocate(the_heap, next_block, add_block_size); + _Heap_Block_allocate(heap, next_block, add_block_size); /* Merge two subsequent blocks */ - the_block->size = (old_block_size + add_block_size) | prev_used_flag; + block->size_and_flag = (old_block_size + add_block_size) | prev_used_flag; --stats->used_blocks; } } else { /* Calculate how much memory we could free */ - uint32_t free_block_size = old_user_size - size; - _Heap_Align_down(&free_block_size, page_size); + uintptr_t free_block_size = + _Heap_Align_down(old_user_size - size, page_size); if (free_block_size > 0) { @@ -123,10 +99,10 @@ Heap_Resize_status _Heap_Resize_block( can hold 'size' user bytes and still remain not shorter than 'min_block_size'. */ - uint32_t new_block_size = old_block_size - free_block_size; + uintptr_t new_block_size = old_block_size - free_block_size; if (new_block_size < min_block_size) { - uint32_t delta = min_block_size - new_block_size; + uintptr_t delta = min_block_size - new_block_size; _HAssert(free_block_size >= delta); free_block_size -= delta; if (free_block_size == 0) { @@ -144,25 +120,25 @@ Heap_Resize_status _Heap_Resize_block( if (!next_is_used) { /* Extend the next block to the low addresses by 'free_block_size' */ Heap_Block *const new_next_block = - _Heap_Block_at(the_block, new_block_size); - uint32_t const new_next_block_size = + _Heap_Block_at(block, new_block_size); + uintptr_t const new_next_block_size = next_block_size + free_block_size; - _HAssert(_Heap_Is_block_in(the_heap, next_next_block)); - the_block->size = new_block_size | prev_used_flag; - new_next_block->size = new_next_block_size | HEAP_PREV_USED; + _HAssert(_Heap_Is_block_in_heap(heap, next_next_block)); + block->size_and_flag = new_block_size | prev_used_flag; + new_next_block->size_and_flag = new_next_block_size | HEAP_PREV_BLOCK_USED; next_next_block->prev_size = new_next_block_size; - _Heap_Block_replace(next_block, new_next_block); - the_heap->stats.free_size += free_block_size; + _Heap_Block_replace_in_free_list(next_block, new_next_block); + heap->stats.free_size += free_block_size; *avail_mem_size = new_next_block_size - HEAP_BLOCK_USED_OVERHEAD; } else if (free_block_size >= min_block_size) { /* Split the block into 2 used parts, then free the second one. */ - the_block->size = new_block_size | prev_used_flag; - next_block = _Heap_Block_at(the_block, new_block_size); - next_block->size = free_block_size | HEAP_PREV_USED; + block->size_and_flag = new_block_size | prev_used_flag; + next_block = _Heap_Block_at(block, new_block_size); + next_block->size_and_flag = free_block_size | HEAP_PREV_BLOCK_USED; ++stats->used_blocks; /* We have created used block */ --stats->frees; /* Don't count next call in stats */ - _Heap_Free(the_heap, _Heap_User_area(next_block)); + _Heap_Free(heap, (void *) _Heap_Alloc_area_of_block(next_block)); *avail_mem_size = free_block_size - HEAP_BLOCK_USED_OVERHEAD; } } diff --git a/cpukit/score/src/heapsizeofuserarea.c b/cpukit/score/src/heapsizeofuserarea.c index a9a276fabc..be51255eee 100644 --- a/cpukit/score/src/heapsizeofuserarea.c +++ b/cpukit/score/src/heapsizeofuserarea.c @@ -19,69 +19,54 @@ #include <rtems/score/sysstate.h> #include <rtems/score/heap.h> -/*PAGE - * - * _Heap_Size_of_user_area - * - * This kernel routine sets '*size' to the size of the block of memory - * which begins at 'starting_address'. - * It returns true if the 'starting_address' is in the heap, and false - * otherwise. - * - * Input parameters: - * the_heap - pointer to heap header - * starting_address - starting address of the memory block - * size - pointer to size of area - * - * Output parameters: - * size - size of area filled in - * true - if starting_address is valid heap address - * false - if starting_address is invalid heap address - */ - -bool _Heap_Size_of_user_area( - Heap_Control *the_heap, - void *starting_address, - intptr_t *size +bool _Heap_Size_of_alloc_area( + Heap_Control *heap, + void *alloc_area_begin_ptr, + uintptr_t *size ) { - Heap_Block *the_block; - Heap_Block *next_block; - uint32_t the_size; + uintptr_t alloc_area_begin = (uintptr_t) alloc_area_begin_ptr; + Heap_Block *block = + _Heap_Block_of_alloc_area( alloc_area_begin, heap->page_size ); + Heap_Block *next_block = NULL; + uintptr_t block_size = 0; - if ( !_Addresses_Is_in_range( - starting_address, (void *)the_heap->start, (void *)the_heap->final ) ) - return( false ); + if ( + !_Addresses_Is_in_range( alloc_area_begin_ptr, heap->start, heap->final ) + ) { + return false; + } - _Heap_Start_of_block( the_heap, starting_address, &the_block ); - _HAssert(_Heap_Is_block_in( the_heap, the_block )); - if ( !_Heap_Is_block_in( the_heap, the_block ) ) - return( false ); + _HAssert(_Heap_Is_block_in_heap( heap, block )); + if ( !_Heap_Is_block_in_heap( heap, block ) ) { + return false; + } - the_size = _Heap_Block_size( the_block ); - next_block = _Heap_Block_at( the_block, the_size ); + block_size = _Heap_Block_size( block ); + next_block = _Heap_Block_at( block, block_size ); - _HAssert(_Heap_Is_block_in( the_heap, next_block )); - _HAssert(_Heap_Is_prev_used( next_block )); + _HAssert( _Heap_Is_block_in_heap( heap, next_block )); + _HAssert( _Heap_Is_prev_used( next_block )); if ( - !_Heap_Is_block_in( the_heap, next_block ) || + !_Heap_Is_block_in_heap( heap, next_block ) || !_Heap_Is_prev_used( next_block ) - ) - return( false ); - - /* 'starting_address' could be greater than 'the_block' address plus - HEAP_BLOCK_USER_OFFSET as _Heap_Allocate_aligned() may produce such user - pointers. To get rid of this offset we calculate user size as difference - between the end of 'the_block' (='next_block') and 'starting_address' - and then add correction equal to the offset of the 'size' field of the - 'Heap_Block' structure. The correction is due to the fact that - 'prev_size' field of the next block is actually used as user accessible - area of 'the_block'. */ + ) { + return false; + } - *size = _Addresses_Subtract ( next_block, starting_address ) - + HEAP_BLOCK_HEADER_OFFSET; + /* + * 'alloc_area_begin' could be greater than 'block' address plus + * HEAP_BLOCK_ALLOC_AREA_OFFSET as _Heap_Allocate_aligned() may produce such + * user pointers. To get rid of this offset we calculate user size as + * difference between the end of 'block' (='next_block') and + * 'alloc_area_begin' and then add correction equal to the offset of the + * 'size' field of the 'Heap_Block' structure. The correction is due to the + * fact that 'prev_size' field of the next block is actually used as user + * accessible area of 'block'. + */ + *size = (uintptr_t) next_block - alloc_area_begin + HEAP_BLOCK_SIZE_OFFSET; - return( true ); + return true; } diff --git a/cpukit/score/src/heapwalk.c b/cpukit/score/src/heapwalk.c index 69782bf4e8..a6628df0b3 100644 --- a/cpukit/score/src/heapwalk.c +++ b/cpukit/score/src/heapwalk.c @@ -60,11 +60,14 @@ bool _Heap_Walk( { Heap_Block *the_block = the_heap->start; Heap_Block *const end = the_heap->final; - Heap_Block *const tail = _Heap_Tail(the_heap); + Heap_Block *const tail = _Heap_Free_list_tail(the_heap); int error = 0; int passes = 0; + /* FIXME: Why is this disabled? */ do_dump = false; + + /* FIXME: Why is this disabled? */ /* * We don't want to allow walking the heap until we have * transferred control to the user task so we watch the @@ -76,13 +79,14 @@ bool _Heap_Walk( return true; */ + /* FIXME: Reason for this? */ if (source < 0) - source = the_heap->stats.instance; + source = (int) the_heap->stats.instance; - if (do_dump == true) + if (do_dump) printk("\nPASS: %d start %p final %p first %p last %p begin %p end %p\n", source, the_block, end, - _Heap_First(the_heap), _Heap_Last(the_heap), + _Heap_First_free_block(the_heap), _Heap_Last_free_block(the_heap), the_heap->begin, the_heap->end); /* @@ -90,7 +94,7 @@ bool _Heap_Walk( */ if (!_Heap_Is_prev_used(the_block)) { - printk("PASS: %d !HEAP_PREV_USED flag of 1st block isn't set\n", source); + printk("PASS: %d !HEAP_PREV_BLOCK_USED flag of 1st block isn't set\n", source); error = 1; } @@ -136,7 +140,7 @@ bool _Heap_Walk( } { /* Check if 'the_block' is in the free block list */ - Heap_Block* block = _Heap_First(the_heap); + Heap_Block* block = _Heap_First_free_block(the_heap); if (!_Addresses_Is_aligned(block) ) { printk( "PASS: %d first free block %p is not aligned\n", source, block); @@ -150,7 +154,7 @@ bool _Heap_Walk( error = 1; break; } - if (!_Heap_Is_block_in(the_heap, block)) { + if (!_Heap_Is_block_in_heap(the_heap, block)) { printk("PASS: %d a free block %p is not in heap\n", source, block); error = 1; break; diff --git a/cpukit/score/src/pheapgetblocksize.c b/cpukit/score/src/pheapgetblocksize.c index 0e6cd80ea5..21727d77ac 100644 --- a/cpukit/score/src/pheapgetblocksize.c +++ b/cpukit/score/src/pheapgetblocksize.c @@ -25,7 +25,7 @@ bool _Protected_heap_Get_block_size( bool status; _RTEMS_Lock_allocator(); - status = _Heap_Size_of_user_area( the_heap, starting_address, size ); + status = _Heap_Size_of_alloc_area( the_heap, starting_address, size ); _RTEMS_Unlock_allocator(); return status; } |