summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/Makefile.am4
-rw-r--r--cpukit/libcsupport/include/rtems/libcsupport.h6
-rw-r--r--cpukit/libcsupport/include/rtems/malloc.h45
-rw-r--r--cpukit/libcsupport/src/malloc.c3
-rw-r--r--cpukit/libcsupport/src/malloc_initialize.c115
-rw-r--r--cpukit/libcsupport/src/malloc_p.h5
-rw-r--r--cpukit/libcsupport/src/malloc_sbrk_helpers.c108
-rw-r--r--cpukit/libcsupport/src/mallocinfo.c6
-rw-r--r--cpukit/libcsupport/src/rtems_heap_extend_via_sbrk.c58
-rw-r--r--cpukit/libcsupport/src/rtems_heap_null_extend.c27
10 files changed, 171 insertions, 206 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;
+}