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 | |
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')
-rw-r--r-- | cpukit/libcsupport/Makefile.am | 4 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/libcsupport.h | 6 | ||||
-rw-r--r-- | cpukit/libcsupport/include/rtems/malloc.h | 45 | ||||
-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 | ||||
-rw-r--r-- | cpukit/libmisc/monitor/mon-config.c | 1 | ||||
-rw-r--r-- | cpukit/sapi/include/confdefs.h | 9 | ||||
-rw-r--r-- | cpukit/sapi/include/rtems/config.h | 10 | ||||
-rw-r--r-- | cpukit/sapi/src/exinit.c | 6 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/heap.h | 30 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/interr.h | 3 | ||||
-rw-r--r-- | cpukit/score/include/rtems/score/wkspace.h | 14 | ||||
-rw-r--r-- | cpukit/score/inline/rtems/score/heap.inl | 14 | ||||
-rw-r--r-- | cpukit/score/src/wkspace.c | 67 |
19 files changed, 270 insertions, 261 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am index 04d2455dfd..703ef60199 100644 --- a/cpukit/libcsupport/Makefile.am +++ b/cpukit/libcsupport/Makefile.am @@ -98,8 +98,10 @@ MALLOC_C_FILES = src/malloc_initialize.c src/calloc.c src/malloc.c \ src/mallocinfo.c src/malloc_walk.c src/malloc_get_statistics.c \ src/malloc_report_statistics.c src/malloc_report_statistics_plugin.c \ src/malloc_statistics_helpers.c src/posix_memalign.c \ - src/rtems_memalign.c src/malloc_deferred.c src/malloc_sbrk_helpers.c \ + src/rtems_memalign.c src/malloc_deferred.c \ src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \ + src/rtems_heap_extend_via_sbrk.c \ + src/rtems_heap_null_extend.c \ src/rtems_heap_extend.c \ src/rtems_heap_greedy.c diff --git a/cpukit/libcsupport/include/rtems/libcsupport.h b/cpukit/libcsupport/include/rtems/libcsupport.h index d2640476df..919b41eea3 100644 --- a/cpukit/libcsupport/include/rtems/libcsupport.h +++ b/cpukit/libcsupport/include/rtems/libcsupport.h @@ -27,12 +27,6 @@ extern "C" { #endif -void RTEMS_Malloc_Initialize( - void *heap_begin, - uintptr_t heap_size, - size_t sbrk_amount -); - extern void malloc_dump(void); extern bool malloc_walk(int source, bool printf_enabled); void malloc_set_heap_pointer(Heap_Control *new_heap); diff --git a/cpukit/libcsupport/include/rtems/malloc.h b/cpukit/libcsupport/include/rtems/malloc.h index d195b9fef1..9d475d33b1 100644 --- a/cpukit/libcsupport/include/rtems/malloc.h +++ b/cpukit/libcsupport/include/rtems/malloc.h @@ -26,6 +26,20 @@ extern "C" { #endif +/** + * @brief C program heap control. + * + * This is the pointer to the heap control structure used to manage the C + * program heap. + */ +extern Heap_Control *RTEMS_Malloc_Heap; + +void RTEMS_Malloc_Initialize( + const Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +); + /* * Malloc Statistics Structure */ @@ -54,16 +68,29 @@ extern rtems_malloc_statistics_functions_t rtems_malloc_statistics_helpers_table; extern rtems_malloc_statistics_functions_t *rtems_malloc_statistics_helpers; -/* - * Malloc Heap Extension (sbrk) plugin - */ -typedef struct { - void *(*initialize)(void *, size_t); - void *(*extend)(size_t); -} rtems_malloc_sbrk_functions_t; +extern ptrdiff_t RTEMS_Malloc_Sbrk_amount; + +static inline void rtems_heap_set_sbrk_amount( ptrdiff_t sbrk_amount ) +{ + RTEMS_Malloc_Sbrk_amount = sbrk_amount; +} + +typedef void *(*rtems_heap_extend_handler)( + Heap_Control *heap, + size_t alloc_size +); + +void *rtems_heap_extend_via_sbrk( + Heap_Control *heap, + size_t alloc_size +); + +void *rtems_heap_null_extend( + Heap_Control *heap, + size_t alloc_size +); -extern rtems_malloc_sbrk_functions_t rtems_malloc_sbrk_helpers_table; -extern rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers; +extern const rtems_heap_extend_handler rtems_malloc_extend_handler; /* * Malloc Plugin to Dirty Memory at Allocation Time 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; +} diff --git a/cpukit/libmisc/monitor/mon-config.c b/cpukit/libmisc/monitor/mon-config.c index 0df87d625f..b5bc31ce9d 100644 --- a/cpukit/libmisc/monitor/mon-config.c +++ b/cpukit/libmisc/monitor/mon-config.c @@ -33,7 +33,6 @@ rtems_monitor_config_canonical( rtems_configuration_table *c = (rtems_configuration_table *) config_void; rtems_api_configuration_table *r = &Configuration_RTEMS_API; - canonical_config->work_space_start = c->work_space_start; canonical_config->work_space_size = c->work_space_size; canonical_config->maximum_tasks = r->maximum_tasks; canonical_config->maximum_timers = r->maximum_timers; diff --git a/cpukit/sapi/include/confdefs.h b/cpukit/sapi/include/confdefs.h index d4f21ca376..09edc97770 100644 --- a/cpukit/sapi/include/confdefs.h +++ b/cpukit/sapi/include/confdefs.h @@ -901,11 +901,11 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * RAM to the malloc family implementation so sbrk()'ing to get * more memory would always fail anyway. */ - rtems_malloc_sbrk_functions_t *rtems_malloc_sbrk_helpers = - #ifndef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK - NULL; + const rtems_heap_extend_handler rtems_malloc_extend_handler = + #ifdef CONFIGURE_MALLOC_BSP_SUPPORTS_SBRK + rtems_heap_extend_via_sbrk; #else - &rtems_malloc_sbrk_helpers_table; + rtems_heap_null_extend; #endif #endif @@ -2318,7 +2318,6 @@ rtems_fs_init_functions_t rtems_fs_init_helper = * This is the primary Configuration Table for this application. */ rtems_configuration_table Configuration = { - NULL, /* filled in by BSP */ CONFIGURE_EXECUTIVE_RAM_SIZE, /* required RTEMS workspace */ CONFIGURE_STACK_SPACE_SIZE, /* required stack space */ CONFIGURE_MAXIMUM_USER_EXTENSIONS, /* maximum dynamic extensions */ diff --git a/cpukit/sapi/include/rtems/config.h b/cpukit/sapi/include/rtems/config.h index 58b350da76..d0e181c781 100644 --- a/cpukit/sapi/include/rtems/config.h +++ b/cpukit/sapi/include/rtems/config.h @@ -124,10 +124,6 @@ typedef void (*rtems_stack_free_hook)( void *addr ); * + required number of each object type for each API configured */ typedef struct { - /** This field specifies the base address of the RTEMS Workspace. - */ - void *work_space_start; - /** This field specifies the size in bytes of the RTEMS Workspace. */ uintptr_t work_space_size; @@ -266,12 +262,6 @@ extern rtems_configuration_table Configuration; #define rtems_configuration_set_stack_space_size( _size ) \ do { Configuration.stack_space_size = (_size); } while (0) -#define rtems_configuration_get_work_space_start() \ - (Configuration.work_space_start) - -#define rtems_configuration_set_work_space_start( _start ) \ - do { Configuration.work_space_start = (_start); } while (0) - #define rtems_configuration_get_work_space_size() \ (Configuration.work_space_size + \ (rtems_configuration_get_stack_allocator_avoids_work_space() ? \ diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index 82e853a142..1aa7e544bb 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -111,12 +111,6 @@ void rtems_initialize_data_structures(void) _Thread_Dispatch_initialization(); - /* - * Before this is called, we are not allowed to allocate memory - * from the Workspace because it is not initialized. - */ - _Workspace_Handler_initialization(); - #if defined(RTEMS_SMP) _SMP_Handler_initialize(); #endif diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h index 964386a36f..36ef48f3b6 100644 --- a/cpukit/score/include/rtems/score/heap.h +++ b/cpukit/score/include/rtems/score/heap.h @@ -675,6 +675,36 @@ Heap_Resize_status _Heap_Resize_block( uintptr_t *new_size ); +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up( + uintptr_t value, + uintptr_t alignment +) +{ + uintptr_t remainder = value % alignment; + + if ( remainder != 0 ) { + return value - remainder + alignment; + } else { + return value; + } +} + +/** + * @brief Returns the worst case overhead to manage a memory area. + */ +RTEMS_INLINE_ROUTINE uintptr_t _Heap_Area_overhead( + uintptr_t page_size +) +{ + if ( page_size != 0 ) { + page_size = _Heap_Align_up( page_size, CPU_ALIGNMENT ); + } else { + page_size = CPU_ALIGNMENT; + } + + return 2 * (page_size - 1) + HEAP_BLOCK_HEADER_SIZE; +} + #if !defined(__RTEMS_APPLICATION__) #include <rtems/score/heap.inl> diff --git a/cpukit/score/include/rtems/score/interr.h b/cpukit/score/include/rtems/score/interr.h index 19342a3db8..2a21fe01eb 100644 --- a/cpukit/score/include/rtems/score/interr.h +++ b/cpukit/score/include/rtems/score/interr.h @@ -72,7 +72,8 @@ typedef enum { INTERNAL_ERROR_UNLIMITED_AND_MAXIMUM_IS_0, INTERNAL_ERROR_SHUTDOWN_WHEN_NOT_UP, INTERNAL_ERROR_GXX_KEY_ADD_FAILED, - INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED + INTERNAL_ERROR_GXX_MUTEX_INIT_FAILED, + INTERNAL_ERROR_NO_MEMORY_FOR_HEAP } Internal_errors_Core_list; typedef uint32_t Internal_errors_t; diff --git a/cpukit/score/include/rtems/score/wkspace.h b/cpukit/score/include/rtems/score/wkspace.h index 10b80ccaab..db6eb38f96 100644 --- a/cpukit/score/include/rtems/score/wkspace.h +++ b/cpukit/score/include/rtems/score/wkspace.h @@ -36,19 +36,23 @@ extern "C" { #include <rtems/score/interr.h> /** - * @brief Executive Workspace Control + * @brief Executive workspace control. * - * The is the heap control structure that used to manage the - * RTEMS Executive Workspace. + * This is the heap control structure used to manage the RTEMS Executive + * Workspace. */ -SCORE_EXTERN Heap_Control _Workspace_Area; /* executive heap header */ +SCORE_EXTERN Heap_Control _Workspace_Area; /** * @brief Workspace Handler Initialization * * This routine performs the initialization necessary for this handler. */ -void _Workspace_Handler_initialization(void); +void _Workspace_Handler_initialization( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +); /** * @brief Allocate Memory from Workspace diff --git a/cpukit/score/inline/rtems/score/heap.inl b/cpukit/score/inline/rtems/score/heap.inl index b9553714c4..59bdd7b142 100644 --- a/cpukit/score/inline/rtems/score/heap.inl +++ b/cpukit/score/inline/rtems/score/heap.inl @@ -108,20 +108,6 @@ RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned( return (value % alignment) == 0; } -RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_up( - uintptr_t value, - uintptr_t alignment -) -{ - uintptr_t remainder = value % alignment; - - if ( remainder != 0 ) { - return value - remainder + alignment; - } else { - return value; - } -} - RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down( uintptr_t value, uintptr_t alignment diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c index 842cade81b..7e58585173 100644 --- a/cpukit/score/src/wkspace.c +++ b/cpukit/score/src/wkspace.c @@ -28,28 +28,69 @@ /* * _Workspace_Handler_initialization */ -void _Workspace_Handler_initialization(void) +void _Workspace_Handler_initialization( + Heap_Area *areas, + size_t area_count, + Heap_Initialization_or_extend_handler extend +) { - uintptr_t memory_available = 0; - void *starting_address = rtems_configuration_get_work_space_start(); - uintptr_t size = rtems_configuration_get_work_space_size(); + Heap_Initialization_or_extend_handler init_or_extend = _Heap_Initialize; + uintptr_t remaining = rtems_configuration_get_work_space_size(); + bool do_zero = rtems_configuration_get_do_zero_of_workspace(); + bool unified = rtems_configuration_get_unified_work_area(); + uintptr_t page_size = CPU_HEAP_ALIGNMENT; + uintptr_t overhead = _Heap_Area_overhead( page_size ); + size_t i; + + for (i = 0; i < area_count; ++i) { + Heap_Area *area = &areas [i]; + + if ( do_zero ) { + memset( area->begin, 0, area->size ); + } + + if ( area->size > overhead ) { + uintptr_t space_available; + uintptr_t size; + + if ( unified ) { + size = area->size; + } else { + if ( remaining > 0 ) { + size = remaining < area->size - overhead ? + remaining + overhead : area->size; + } else { + size = 0; + } + } + + space_available = (*init_or_extend)( + &_Workspace_Area, + area->begin, + size, + page_size + ); + + area->begin = (char *) area->begin + size; + area->size -= size; - if ( rtems_configuration_get_do_zero_of_workspace() ) - memset( starting_address, 0, size ); + if ( space_available < remaining ) { + remaining -= space_available; + } else { + remaining = 0; + } - memory_available = _Heap_Initialize( - &_Workspace_Area, - starting_address, - size, - CPU_HEAP_ALIGNMENT - ); + init_or_extend = extend; + } + } - if ( memory_available == 0 ) + if ( remaining > 0 ) { _Internal_error_Occurred( INTERNAL_ERROR_CORE, true, INTERNAL_ERROR_TOO_LITTLE_WORKSPACE ); + } } /* |