diff options
-rw-r--r-- | cpukit/libcsupport/Makefile.am | 3 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/malloc.h | 18 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rtems_heap_greedy.c | 37 | ||||
-rw-r--r-- | cpukit/score/Makefile.am | 3 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/heap.h | 23 | ||||
-rw-r--r-- | cpukit/score/src/heapgreedy.c | 62 |
6 files changed, 144 insertions, 2 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index ec06f901a1..15e55a1e51 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -107,7 +107,8 @@ MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \ src/malloc_statistics_helpers.c src/posix_memalign.c \ src/rtems_memalign.c src/malloc_deferred.c src/malloc_sbrk_helpers.c \ src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \ - src/rtems_heap_extend.c + src/rtems_heap_extend.c \ + src/rtems_heap_greedy.c PASSWORD_GROUP_C_FILES = src/getpwent.c diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h index e1dfb08445..a8eb434d3b 100644 --- a/cpukit/libcsupport/include/rtems/malloc.h +++ b/cpukit/libcsupport/include/rtems/malloc.h @@ -184,6 +184,24 @@ rtems_status_code rtems_heap_extend( uintptr_t area_size ); +/** + * @brief Greedy allocate that empties the heap. + * + * Afterward the heap has at most @a remaining_free_space free space left in + * one free block. All other blocks are used. + * + * @see rtems_heap_greedy_free(). + */ +void *rtems_heap_greedy_allocate( size_t remaining_free_space ); + +/** + * @brief Frees space of a greedy allocation. + * + * The @a opaque argument must be the return value of + * rtems_heap_greedy_allocate(). + */ +void rtems_heap_greedy_free( void *opaque ); + #ifdef __cplusplus } #endif diff --git a/cpukit/libcsupport/src/rtems_heap_greedy.c b/cpukit/libcsupport/src/rtems_heap_greedy.c new file mode 100644 index 0000000000..d363fe4d3b --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_greedy.c @@ -0,0 +1,37 @@ +/* + * 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 "malloc_p.h" + +void *rtems_heap_greedy_allocate( size_t remaining_free_space ) +{ + void *opaque; + + _RTEMS_Lock_allocator(); + opaque = _Heap_Greedy_allocate( RTEMS_Malloc_Heap, remaining_free_space ); + _RTEMS_Unlock_allocator(); + + return opaque; +} + +void rtems_heap_greedy_free( void *opaque ) +{ + _RTEMS_Lock_allocator(); + _Heap_Greedy_free( RTEMS_Malloc_Heap, opaque ); + _RTEMS_Unlock_allocator(); +} diff --git a/cpukit/score/Makefile.am b/cpukit/score/Makefile.am index 13c31826b9..597da3e0cc 100644 --- a/cpukit/score/Makefile.am +++ b/cpukit/score/Makefile.am @@ -181,7 +181,8 @@ endif ## HEAP_C_FILES 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/heapgetfreeinfo.c src/heapresizeblock.c src/heapiterate.c \ + src/heapgreedy.c ## OBJECT_C_FILES libscore_a_SOURCES += src/objectallocate.c src/objectclose.c \ diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h index 1996fb80ff..8f508c9874 100644 --- a/cpukit/score/include/rtems/score/heap.h +++ b/cpukit/score/include/rtems/score/heap.h @@ -549,6 +549,29 @@ void _Heap_Iterate( ); /** + * @brief Greedy allocate that empties the heap. + * + * Afterward the heap has at most @a remaining_free_space free space left in + * one free block. All other blocks are used. + * + * @see _Heap_Greedy_free(). + */ +Heap_Block *_Heap_Greedy_allocate( + Heap_Control *heap, + uintptr_t remaining_free_space +); + +/** + * @brief Frees blocks of a greedy allocation. + * + * The @a blocks must be the return value of _Heap_Greedy_allocate(). + */ +void _Heap_Greedy_free( + Heap_Control *heap, + Heap_Block *blocks +); + +/** * @brief Returns information about used and free blocks for the heap @a heap * in @a info. */ diff --git a/cpukit/score/src/heapgreedy.c b/cpukit/score/src/heapgreedy.c new file mode 100644 index 0000000000..4b38b7858a --- /dev/null +++ b/cpukit/score/src/heapgreedy.c @@ -0,0 +1,62 @@ +/* + * 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> + +Heap_Block *_Heap_Greedy_allocate( + Heap_Control *heap, + uintptr_t remaining_free_space +) +{ + void *free_space = remaining_free_space > 0 ? + _Heap_Allocate( heap, remaining_free_space ) + : NULL; + Heap_Block *const free_list_tail = _Heap_Free_list_tail( heap ); + Heap_Block *current = _Heap_Free_list_first( heap ); + Heap_Block *blocks = NULL; + + while ( current != free_list_tail ) { + _Heap_Block_allocate( + heap, + current, + _Heap_Alloc_area_of_block( current ), + _Heap_Block_size( current ) - HEAP_BLOCK_HEADER_SIZE + ); + + current->next = blocks; + blocks = current; + current = _Heap_Free_list_first( heap ); + } + + _Heap_Free( heap, free_space ); + + return blocks; +} + +void _Heap_Greedy_free( + Heap_Control *heap, + Heap_Block *blocks +) +{ + while ( blocks != NULL ) { + Heap_Block *current = blocks; + + blocks = blocks->next; + _Heap_Free( heap, (void *) _Heap_Alloc_area_of_block( current ) ); + } +} |