diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-08-09 16:48:00 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2012-10-25 14:54:06 +0200 |
commit | 47a3cd8f73780bad3eff5135f0eb58e8c98af91d (patch) | |
tree | 8acdfc6ebe5d596f9c6b974e6c460dc69e824e3c /cpukit/libcsupport/src | |
parent | score: Append to free list in _Heap_Extend() (diff) | |
download | rtems-47a3cd8f73780bad3eff5135f0eb58e8c98af91d.tar.bz2 |
score: Work area initialization API change
The work areas (RTEMS work space and C program heap) will be initialized
now in a separate step and are no longer part of
rtems_initialize_data_structures(). Initialization is performed with
tables of Heap_Area entries. This allows usage of scattered memory
areas present on various small scale micro-controllers.
The sbrk() support API changes also. The bsp_sbrk_init() must now deal
with a minimum size for the first memory chunk to take the configured
work space size into account.
Diffstat (limited to 'cpukit/libcsupport/src')
-rw-r--r-- | cpukit/libcsupport/src/malloc.c | 3 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc_initialize.c | 115 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc_p.h | 5 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc_sbrk_helpers.c | 108 | ||||
-rw-r--r-- | cpukit/libcsupport/src/mallocinfo.c | 6 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c | 58 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rtems_heap_null_extend.c | 27 |
7 files changed, 132 insertions, 190 deletions
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c index 0fff1d011c..dea6f8f3c7 100644 --- a/cpukit/libcsupport/src/malloc.c +++ b/cpukit/libcsupport/src/malloc.c @@ -55,8 +55,7 @@ void *malloc( return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); if ( !return_this ) { - if (rtems_malloc_sbrk_helpers) - return_this = (*rtems_malloc_sbrk_helpers->extend)( size ); + return_this = (*rtems_malloc_extend_handler)( RTEMS_Malloc_Heap, size ); if ( !return_this ) { errno = ENOMEM; return (void *) 0; diff --git a/cpukit/libcsupport/src/malloc_initialize.c b/cpukit/libcsupport/src/malloc_initialize.c index fccddd1368..06263bda82 100644 --- a/cpukit/libcsupport/src/malloc_initialize.c +++ b/cpukit/libcsupport/src/malloc_initialize.c @@ -1,11 +1,11 @@ /** * @file * - * @brief Malloc initialization implementation. + * @brief RTEMS_Malloc_Initialize() implementation. */ /* - * COPYRIGHT (c) 1989-2007. + * COPYRIGHT (c) 1989-2012. * On-Line Applications Research Corporation (OAR). * * The license and distribution terms for this file may be @@ -14,93 +14,68 @@ */ #if HAVE_CONFIG_H -#include "config.h" + #include "config.h" #endif -#include <rtems.h> #include <rtems/malloc.h> -#include <rtems/score/wkspace.h> + #include "malloc_p.h" -/* FIXME: Dummy function */ -#ifndef RTEMS_NEWLIB -void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount -) -{ -} -#else +#ifdef RTEMS_NEWLIB rtems_malloc_statistics_t rtems_malloc_statistics; void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount + const Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend ) { - bool separate_areas = !rtems_configuration_get_unified_work_area(); - /* - * If configured, initialize the statistics support - */ - if ( rtems_malloc_statistics_helpers != NULL ) { - (*rtems_malloc_statistics_helpers->initialize)(); - } + Heap_Control *heap = RTEMS_Malloc_Heap; - /* - * Initialize the optional sbrk support for extending the heap - */ - if ( rtems_malloc_sbrk_helpers != NULL ) { - void *new_heap_begin = (*rtems_malloc_sbrk_helpers->initialize)( - heap_begin, - sbrk_amount - ); - - heap_size -= (uintptr_t) new_heap_begin - (uintptr_t) heap_begin; - heap_begin = new_heap_begin; - } + if ( !rtems_configuration_get_unified_work_area() ) { + Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize; + uintptr_t page_size = CPU_HEAP_ALIGNMENT; + size_t i; - /* - * If this system is configured to use the same heap for - * the RTEMS Workspace and C Program Heap, then we need to - * be very very careful about destroying the initialization - * that has already been done. - */ + for (i = 0; i < area_count; ++i) { + const Heap_Area *area = &areas [i]; + uintptr_t space_available = (*init_or_extend)( + heap, + area->begin, + area->size, + page_size + ); - /* - * If the BSP is not clearing out the workspace, then it is most likely - * not clearing out the initial memory for the heap. There is no - * standard supporting zeroing out the heap memory. But much code - * with UNIX history seems to assume that memory malloc'ed during - * initialization (before any free's) is zero'ed. This is true most - * of the time under UNIX because zero'ing memory when it is first - * given to a process eliminates the chance of a process seeing data - * left over from another process. This would be a security violation. - */ + if ( space_available > 0 ) { + init_or_extend = extend; + } + } - if ( separate_areas && rtems_configuration_get_do_zero_of_workspace() ) { - memset( heap_begin, 0, heap_size ); + if ( init_or_extend == _Heap_Initialize ) { + _Internal_error_Occurred( + INTERNAL_ERROR_CORE, + true, + INTERNAL_ERROR_NO_MEMORY_FOR_HEAP + ); + } } /* - * Unfortunately we cannot use assert if this fails because if this - * has failed we do not have a heap and if we do not have a heap - * STDIO cannot work because there will be no buffers. + * If configured, initialize the statistics support */ - - if ( separate_areas ) { - uintptr_t status = _Protected_heap_Initialize( - RTEMS_Malloc_Heap, - heap_begin, - heap_size, - CPU_HEAP_ALIGNMENT - ); - if ( status == 0 ) { - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - } + if ( rtems_malloc_statistics_helpers != NULL ) { + (*rtems_malloc_statistics_helpers->initialize)(); } - MSBUMP( space_available, _Protected_heap_Get_size(RTEMS_Malloc_Heap) ); + MSBUMP( space_available, _Protected_heap_Get_size( heap ) ); +} +#else +void RTEMS_Malloc_Initialize( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +) +{ + /* FIXME: Dummy function */ } #endif diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h index ea0709f0e7..6bd9a495f7 100644 --- a/cpukit/libcsupport/src/malloc_p.h +++ b/cpukit/libcsupport/src/malloc_p.h @@ -23,11 +23,6 @@ #include <rtems/chain.h> /* - * Basic management data - */ -extern Heap_Control *RTEMS_Malloc_Heap; - -/* * Malloc Statistics Structure */ extern rtems_malloc_statistics_t rtems_malloc_statistics; diff --git a/cpukit/libcsupport/src/malloc_sbrk_helpers.c b/cpukit/libcsupport/src/malloc_sbrk_helpers.c deleted file mode 100644 index 64572a154e..0000000000 --- a/cpukit/libcsupport/src/malloc_sbrk_helpers.c +++ /dev/null @@ -1,108 +0,0 @@ -/* - * RTEMS Malloc -- SBRK Support Plugin - * - * COPYRIGHT (c) 1989-2007. - * On-Line Applications Research Corporation (OAR). - * - * 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 <unistd.h> /* sbrk */ - -#include <rtems.h> -#include <rtems/malloc.h> -#include "malloc_p.h" - -#include <errno.h> - -size_t RTEMS_Malloc_Sbrk_amount; - -static void *malloc_sbrk_initialize( - void *starting_address, - size_t length -) -{ - uintptr_t old_address; - uintptr_t uaddress; - - RTEMS_Malloc_Sbrk_amount = length; - - /* - * If the starting address is 0 then we are to attempt to - * get length worth of memory using sbrk. Make sure we - * align the address that we get back. - */ - - if (!starting_address) { - uaddress = (uintptr_t)sbrk(length); - - if (uaddress == (uintptr_t) -1) { - rtems_fatal_error_occurred( RTEMS_NO_MEMORY ); - /* DOES NOT RETURN!!! */ - } - - if (uaddress & (CPU_HEAP_ALIGNMENT-1)) { - old_address = uaddress; - uaddress = (uaddress + CPU_HEAP_ALIGNMENT) & ~(CPU_HEAP_ALIGNMENT-1); - - /* - * adjust the length by whatever we aligned by - */ - length -= uaddress - old_address; - } - - starting_address = (void *)uaddress; - } - return starting_address; -} - -static void *malloc_sbrk_extend_and_allocate( - size_t size -) -{ - uint32_t sbrk_amount; - void *starting_address; - uint32_t the_size; - void *return_this; - - /* - * Round to the "requested sbrk amount" so hopefully we won't have - * to grow again for a while. This effectively does sbrk() calls - * in "page" amounts. - */ - - sbrk_amount = RTEMS_Malloc_Sbrk_amount; - - if ( sbrk_amount == 0 ) - return (void *) 0; - - the_size = ((size + sbrk_amount) / sbrk_amount * sbrk_amount); - - starting_address = (void *) sbrk(the_size); - if ( starting_address == (void*) -1 ) - return (void *) 0; - - if ( !_Protected_heap_Extend( - RTEMS_Malloc_Heap, starting_address, the_size) ) { - sbrk(-the_size); - errno = ENOMEM; - return (void *) 0; - } - - MSBUMP(space_available, the_size); - - return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size ); - return return_this; -} - - -rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table = { - malloc_sbrk_initialize, - malloc_sbrk_extend_and_allocate -}; diff --git a/cpukit/libcsupport/src/mallocinfo.c b/cpukit/libcsupport/src/mallocinfo.c index 47aefc3ff4..1532608420 100644 --- a/cpukit/libcsupport/src/mallocinfo.c +++ b/cpukit/libcsupport/src/mallocinfo.c @@ -14,13 +14,9 @@ #include "config.h" #endif -#define __RTEMS_VIOLATE_KERNEL_VISIBILITY__ -#include <rtems.h> -#include <rtems/libcsupport.h> +#include <rtems/malloc.h> #include <rtems/score/protectedheap.h> -extern Heap_Control *RTEMS_Malloc_Heap; - /* * Find amount of free heap remaining */ diff --git a/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c new file mode 100644 index 0000000000..831626b3d5 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c @@ -0,0 +1,58 @@ +/* + * 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 <unistd.h> + +#include <rtems/malloc.h> + +#include "malloc_p.h" + +ptrdiff_t RTEMS_Malloc_Sbrk_amount; + +void *rtems_heap_extend_via_sbrk( + Heap_Control *heap, + size_t alloc_size +) +{ + ptrdiff_t sbrk_amount = RTEMS_Malloc_Sbrk_amount; + ptrdiff_t sbrk_size = (ptrdiff_t) alloc_size; + ptrdiff_t misaligned = sbrk_size % sbrk_amount; + void *return_this = NULL; + + if ( misaligned != 0 ) { + sbrk_size += sbrk_amount - misaligned; + } + + if ( sbrk_size > 0 && sbrk_amount > 0 ) { + void *area_begin = sbrk( sbrk_size ); + + if ( area_begin != (void *) -1 ) { + bool ok = _Protected_heap_Extend( heap, area_begin, sbrk_size ); + + if ( ok ) { + MSBUMP( space_available, sbrk_size ); + + return_this = _Protected_heap_Allocate( heap, alloc_size ); + } else { + sbrk( -sbrk_size ); + } + } + } + + return return_this; +} diff --git a/cpukit/libcsupport/src/rtems_heap_null_extend.c b/cpukit/libcsupport/src/rtems_heap_null_extend.c new file mode 100644 index 0000000000..a821ef48f9 --- /dev/null +++ b/cpukit/libcsupport/src/rtems_heap_null_extend.c @@ -0,0 +1,27 @@ +/* + * 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/malloc.h> + +void *rtems_heap_null_extend( + Heap_Control *heap __attribute__((unused)), + size_t alloc_size __attribute__((unused)) +) +{ + return NULL; +} |