forked from Imagelibrary/rtems
score: Change _Heap_Extend() API
The _Heap_Extend() has now the same signature as _Heap_Initialize(). The 4th parameter is ignored (page size in _Heap_Initialize()). Add Heap_Area and Heap_Initialization_or_extend_handler. Add and test _Heap_No_extend(). This helps to do a table based heap initialization and extension. Create a table of Heap_Area elements and iterate through it. Set the handler to _Heap_Initialize() in the first iteration and then to _Heap_Extend().
This commit is contained in:
@@ -46,7 +46,6 @@ rtems_status_code rtems_region_extend(
|
||||
)
|
||||
{
|
||||
uintptr_t amount_extended;
|
||||
bool extend_ok;
|
||||
Objects_Locations location;
|
||||
rtems_status_code return_status;
|
||||
Region_Control *the_region;
|
||||
@@ -61,14 +60,14 @@ rtems_status_code rtems_region_extend(
|
||||
|
||||
case OBJECTS_LOCAL:
|
||||
|
||||
extend_ok = _Heap_Extend(
|
||||
amount_extended = _Heap_Extend(
|
||||
&the_region->Memory,
|
||||
starting_address,
|
||||
length,
|
||||
&amount_extended
|
||||
0
|
||||
);
|
||||
|
||||
if ( extend_ok ) {
|
||||
if ( amount_extended > 0 ) {
|
||||
the_region->length += amount_extended;
|
||||
the_region->maximum_segment_size += amount_extended;
|
||||
return_status = RTEMS_SUCCESSFUL;
|
||||
|
||||
@@ -178,7 +178,7 @@ endif
|
||||
libscore_a_SOURCES += src/heap.c src/heapallocate.c src/heapextend.c \
|
||||
src/heapfree.c src/heapsizeofuserarea.c src/heapwalk.c src/heapgetinfo.c \
|
||||
src/heapgetfreeinfo.c src/heapresizeblock.c src/heapiterate.c \
|
||||
src/heapgreedy.c
|
||||
src/heapgreedy.c src/heapnoextend.c
|
||||
|
||||
## OBJECT_C_FILES
|
||||
libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \
|
||||
|
||||
@@ -387,6 +387,33 @@ typedef enum {
|
||||
HEAP_RESIZE_FATAL_ERROR
|
||||
} Heap_Resize_status;
|
||||
|
||||
/**
|
||||
* @brief Heap area structure for table based heap initialization and
|
||||
* extension.
|
||||
*
|
||||
* @see Heap_Initialization_or_extend_handler.
|
||||
*/
|
||||
typedef struct {
|
||||
void *begin;
|
||||
uintptr_t size;
|
||||
} Heap_Area;
|
||||
|
||||
/**
|
||||
* @brief Heap initialization and extend handler type.
|
||||
*
|
||||
* This helps to do a table based heap initialization and extension. Create a
|
||||
* table of Heap_Area elements and iterate through it. Set the handler to
|
||||
* _Heap_Initialize() in the first iteration and then to _Heap_Extend().
|
||||
*
|
||||
* @see Heap_Area, _Heap_Initialize(), _Heap_Extend(), or _Heap_No_extend().
|
||||
*/
|
||||
typedef uintptr_t (*Heap_Initialization_or_extend_handler)(
|
||||
Heap_Control *heap,
|
||||
void *area_begin,
|
||||
uintptr_t area_size,
|
||||
uintptr_t page_size_or_unused
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Gets the first and last block for the heap area with begin
|
||||
* @a heap_area_begin and size @a heap_area_size.
|
||||
@@ -419,6 +446,8 @@ bool _Heap_Get_first_and_last_block(
|
||||
* @c CPU_ALIGNMENT, it is aligned up to the nearest @c CPU_ALIGNMENT boundary.
|
||||
*
|
||||
* Returns the maximum memory available, or zero in case of failure.
|
||||
*
|
||||
* @see Heap_Initialization_or_extend_handler.
|
||||
*/
|
||||
uintptr_t _Heap_Initialize(
|
||||
Heap_Control *heap,
|
||||
@@ -431,22 +460,40 @@ uintptr_t _Heap_Initialize(
|
||||
* @brief Extends the memory available for the heap @a heap using the memory
|
||||
* area starting at @a area_begin of size @a area_size bytes.
|
||||
*
|
||||
* The extended space available for allocation will be returned in
|
||||
* @a amount_extended. This pointer may be @c NULL.
|
||||
*
|
||||
* There are no alignment requirements. The memory area must be big enough to
|
||||
* contain some maintainance blocks. It must not overlap parts of the current
|
||||
* heap areas. Disconnected subordinate heap areas will lead to used blocks
|
||||
* which cover the gaps. Extending with an inappropriate memory area will
|
||||
* corrupt the heap.
|
||||
*
|
||||
* Returns @c true in case of success, and @c false otherwise.
|
||||
* The unused fourth parameter is provided to have the same signature as
|
||||
* _Heap_Initialize().
|
||||
*
|
||||
* Returns the extended space available for allocation, or zero in case of failure.
|
||||
*
|
||||
* @see Heap_Initialization_or_extend_handler.
|
||||
*/
|
||||
bool _Heap_Extend(
|
||||
uintptr_t _Heap_Extend(
|
||||
Heap_Control *heap,
|
||||
void *area_begin,
|
||||
uintptr_t area_size,
|
||||
uintptr_t *amount_extended
|
||||
uintptr_t unused
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief This function returns always zero.
|
||||
*
|
||||
* This function only returns zero and does nothing else.
|
||||
*
|
||||
* Returns always zero.
|
||||
*
|
||||
* @see Heap_Initialization_or_extend_handler.
|
||||
*/
|
||||
uintptr_t _Heap_No_extend(
|
||||
Heap_Control *unused_0,
|
||||
void *unused_1,
|
||||
uintptr_t unused_2,
|
||||
uintptr_t unused_3
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -108,11 +108,11 @@ static void _Heap_Link_above(
|
||||
last_block->size_and_flag |= HEAP_PREV_BLOCK_USED;
|
||||
}
|
||||
|
||||
bool _Heap_Extend(
|
||||
uintptr_t _Heap_Extend(
|
||||
Heap_Control *heap,
|
||||
void *extend_area_begin_ptr,
|
||||
uintptr_t extend_area_size,
|
||||
uintptr_t *extended_size_ptr
|
||||
uintptr_t unused __attribute__((unused))
|
||||
)
|
||||
{
|
||||
Heap_Statistics *const stats = &heap->stats;
|
||||
@@ -134,7 +134,7 @@ bool _Heap_Extend(
|
||||
bool extend_area_ok = false;
|
||||
|
||||
if ( extend_area_end < extend_area_begin ) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
extend_area_ok = _Heap_Get_first_and_last_block(
|
||||
@@ -147,7 +147,7 @@ bool _Heap_Extend(
|
||||
);
|
||||
if (!extend_area_ok ) {
|
||||
/* For simplicity we reject extend areas that are too small */
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -160,7 +160,7 @@ bool _Heap_Extend(
|
||||
if (
|
||||
sub_area_end > extend_area_begin && extend_area_end > sub_area_begin
|
||||
) {
|
||||
return false;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( extend_area_end == sub_area_begin ) {
|
||||
@@ -234,8 +234,5 @@ bool _Heap_Extend(
|
||||
/* Statistics */
|
||||
stats->size += extended_size;
|
||||
|
||||
if ( extended_size_ptr != NULL )
|
||||
*extended_size_ptr = extended_size;
|
||||
|
||||
return true;
|
||||
return extended_size;
|
||||
}
|
||||
|
||||
37
cpukit/score/src/heapnoextend.c
Normal file
37
cpukit/score/src/heapnoextend.c
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
* @file
|
||||
*
|
||||
* @ingroup ScoreHeap
|
||||
*
|
||||
* @brief Heap Handler implementation.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 2012 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Obere Lagerstr. 30
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <rtems@embedded-brains.de>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <rtems/score/heap.h>
|
||||
|
||||
uintptr_t _Heap_No_extend(
|
||||
Heap_Control *unused_0 __attribute__((unused)),
|
||||
void *unused_1 __attribute__((unused)),
|
||||
uintptr_t unused_2 __attribute__((unused)),
|
||||
uintptr_t unused_3 __attribute__((unused))
|
||||
)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -28,12 +28,11 @@ bool _Protected_heap_Extend(
|
||||
uintptr_t size
|
||||
)
|
||||
{
|
||||
bool extend_ok;
|
||||
uintptr_t amount_extended;
|
||||
|
||||
_RTEMS_Lock_allocator();
|
||||
extend_ok = _Heap_Extend(the_heap, starting_address, size, &amount_extended);
|
||||
amount_extended = _Heap_Extend( the_heap, starting_address, size, 0 );
|
||||
_RTEMS_Unlock_allocator();
|
||||
return extend_ok;
|
||||
}
|
||||
|
||||
return amount_extended != 0;
|
||||
}
|
||||
|
||||
@@ -984,6 +984,12 @@ static void test_heap_extend(void)
|
||||
test_heap_assert( ret, true );
|
||||
}
|
||||
|
||||
static void test_heap_no_extend(void)
|
||||
{
|
||||
uintptr_t extended_space = _Heap_No_extend( NULL, 0, 0, 0 );
|
||||
rtems_test_assert( extended_space == 0 );
|
||||
}
|
||||
|
||||
static void test_heap_info(void)
|
||||
{
|
||||
size_t s1, s2;
|
||||
@@ -1142,6 +1148,7 @@ rtems_task Init(
|
||||
test_realloc();
|
||||
test_heap_cases_1();
|
||||
test_heap_extend();
|
||||
test_heap_no_extend();
|
||||
test_heap_info();
|
||||
test_protected_heap_info();
|
||||
test_rtems_heap_allocate_aligned_with_boundary();
|
||||
|
||||
Reference in New Issue
Block a user