summaryrefslogtreecommitdiffstats
path: root/cpukit/libcsupport
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-02-25 09:02:43 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-02-25 11:35:54 +0100
commit9d1f39434585e8d3f8897d95a2bfe1ddccb79aec (patch)
tree2d3a0868f410cff137871f5ce493df4f27a22b1a /cpukit/libcsupport
parentmalloc: Use dedicated lock for deferred frees (diff)
downloadrtems-9d1f39434585e8d3f8897d95a2bfe1ddccb79aec.tar.bz2
malloc: Add _Malloc_System_state()
Replace malloc_is_system_state_OK() with _Malloc_System_state() to allow early allocations, e.g. in bsp_start(). Here the _Thread_Executing is NULL, thus an _API_Mutex_Lock() would lead to a NULL pointer access. Move malloc() support code to general case rtems_heap_allocate_aligned_with_boundary(). Use rtems_heap_allocate_aligned_with_boundary() to avoid duplicated code.
Diffstat (limited to 'cpukit/libcsupport')
-rw-r--r--cpukit/libcsupport/Makefile.am2
-rw-r--r--cpukit/libcsupport/src/free.c8
-rw-r--r--cpukit/libcsupport/src/malloc.c33
-rw-r--r--cpukit/libcsupport/src/malloc_deferred.c68
-rw-r--r--cpukit/libcsupport/src/malloc_p.h15
-rw-r--r--cpukit/libcsupport/src/rtems_malloc.c51
-rw-r--r--cpukit/libcsupport/src/rtems_memalign.c17
7 files changed, 79 insertions, 115 deletions
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 0b2607f2b9..eee9da7586 100644
--- a/cpukit/libcsupport/Makefile.am
+++ b/cpukit/libcsupport/Makefile.am
@@ -87,7 +87,7 @@ MALLOC_C_FILES = src/malloc_initialize.c src/malloc.c \
src/mallocinfo.c src/malloc_walk.c \
src/posix_memalign.c \
src/rtems_memalign.c src/malloc_deferred.c \
- src/malloc_dirtier.c src/malloc_p.h src/rtems_malloc.c \
+ src/malloc_dirtier.c src/malloc_p.h \
src/rtems_heap_extend_via_sbrk.c \
src/rtems_heap_null_extend.c \
src/rtems_heap_extend.c \
diff --git a/cpukit/libcsupport/src/free.c b/cpukit/libcsupport/src/free.c
index 63eb7b8037..f3d4cb824b 100644
--- a/cpukit/libcsupport/src/free.c
+++ b/cpukit/libcsupport/src/free.c
@@ -22,10 +22,6 @@
#include "malloc_p.h"
#include <stdlib.h>
-#include <rtems/score/sysstate.h>
-
-#include "malloc_p.h"
-
void free(
void *ptr
)
@@ -36,8 +32,8 @@ void free(
/*
* Do not attempt to free memory if in a critical section or ISR.
*/
- if ( !malloc_is_system_state_OK() ) {
- malloc_deferred_free(ptr);
+ if ( _Malloc_System_state() != MALLOC_SYSTEM_STATE_NORMAL ) {
+ _Malloc_Deferred_free(ptr);
return;
}
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c
index 73203e5b1c..03e2208ef4 100644
--- a/cpukit/libcsupport/src/malloc.c
+++ b/cpukit/libcsupport/src/malloc.c
@@ -31,44 +31,17 @@ void *malloc(
void *return_this;
/*
- * If some free's have been deferred, then do them now.
- */
- malloc_deferred_frees_process();
-
- /*
* Validate the parameters
*/
if ( !size )
return (void *) 0;
- /*
- * Do not attempt to allocate memory if not in correct system state.
- */
- if ( !malloc_is_system_state_OK() )
- return NULL;
-
- /*
- * Try to give a segment in the current heap if there is not
- * enough space then try to grow the heap.
- * If this fails then return a NULL pointer.
- */
-
- return_this = _Protected_heap_Allocate( RTEMS_Malloc_Heap, size );
-
+ return_this = rtems_heap_allocate_aligned_with_boundary( size, 0, 0 );
if ( !return_this ) {
- return_this = (*rtems_malloc_extend_handler)( RTEMS_Malloc_Heap, size );
- if ( !return_this ) {
- errno = ENOMEM;
- return (void *) 0;
- }
+ errno = ENOMEM;
+ return (void *) 0;
}
- /*
- * If the user wants us to dirty the allocated memory, then do it.
- */
- if ( rtems_malloc_dirty_helper )
- (*rtems_malloc_dirty_helper)( return_this, size );
-
return return_this;
}
diff --git a/cpukit/libcsupport/src/malloc_deferred.c b/cpukit/libcsupport/src/malloc_deferred.c
index 395ed64d34..e781a05bd5 100644
--- a/cpukit/libcsupport/src/malloc_deferred.c
+++ b/cpukit/libcsupport/src/malloc_deferred.c
@@ -34,10 +34,21 @@ static RTEMS_CHAIN_DEFINE_EMPTY( _Malloc_GC_list );
RTEMS_INTERRUPT_LOCK_DEFINE( static, _Malloc_GC_lock, "Malloc GC" )
-bool malloc_is_system_state_OK(void)
+Malloc_System_state _Malloc_System_state( void )
{
- return !_System_state_Is_up( _System_state_Get() )
- || _Thread_Dispatch_is_enabled();
+ System_state_Codes state = _System_state_Get();
+
+ if ( _System_state_Is_up( state ) ) {
+ if ( _Thread_Dispatch_is_enabled() ) {
+ return MALLOC_SYSTEM_STATE_NORMAL;
+ } else {
+ return MALLOC_SYSTEM_STATE_NO_ALLOCATION;
+ }
+ } else if ( _System_state_Is_before_multitasking( state ) ) {
+ return MALLOC_SYSTEM_STATE_NORMAL;
+ } else {
+ return MALLOC_SYSTEM_STATE_NO_PROTECTION;
+ }
}
static void *_Malloc_Get_deferred_free( void )
@@ -52,7 +63,7 @@ static void *_Malloc_Get_deferred_free( void )
return p;
}
-void malloc_deferred_frees_process( void )
+static void _Malloc_Process_deferred_frees( void )
{
rtems_chain_node *to_be_freed;
@@ -64,7 +75,54 @@ void malloc_deferred_frees_process( void )
}
}
-void malloc_deferred_free( void *p )
+void *rtems_heap_allocate_aligned_with_boundary(
+ uintptr_t size,
+ uintptr_t alignment,
+ uintptr_t boundary
+)
+{
+ Heap_Control *heap = RTEMS_Malloc_Heap;
+ void *p;
+
+ switch ( _Malloc_System_state() ) {
+ case MALLOC_SYSTEM_STATE_NORMAL:
+ _Malloc_Process_deferred_frees();
+ p = _Protected_heap_Allocate_aligned_with_boundary(
+ heap,
+ size,
+ alignment,
+ boundary
+ );
+ break;
+ case MALLOC_SYSTEM_STATE_NO_PROTECTION:
+ p = _Heap_Allocate_aligned_with_boundary(
+ heap,
+ size,
+ alignment,
+ boundary
+ );
+ break;
+ default:
+ /*
+ * Do not attempt to allocate memory if not in correct system state.
+ */
+ return NULL;
+ }
+
+ if ( p == NULL && alignment == 0 && boundary == 0 ) {
+ p = (*rtems_malloc_extend_handler)( heap, size );
+ }
+
+ /*
+ * If the user wants us to dirty the allocated memory, then do it.
+ */
+ if ( p != NULL && rtems_malloc_dirty_helper != NULL )
+ (*rtems_malloc_dirty_helper)( p, size );
+
+ return p;
+}
+
+void _Malloc_Deferred_free( void *p )
{
rtems_interrupt_lock_context lock_context;
diff --git a/cpukit/libcsupport/src/malloc_p.h b/cpukit/libcsupport/src/malloc_p.h
index 6609526fa8..127f22bac4 100644
--- a/cpukit/libcsupport/src/malloc_p.h
+++ b/cpukit/libcsupport/src/malloc_p.h
@@ -17,12 +17,15 @@
extern "C" {
#endif /* __cplusplus */
-/*
- * Process deferred free operations
- */
-bool malloc_is_system_state_OK(void);
-void malloc_deferred_frees_process(void);
-void malloc_deferred_free(void *);
+typedef enum {
+ MALLOC_SYSTEM_STATE_NORMAL,
+ MALLOC_SYSTEM_STATE_NO_PROTECTION,
+ MALLOC_SYSTEM_STATE_NO_ALLOCATION
+} Malloc_System_state;
+
+Malloc_System_state _Malloc_System_state( void );
+
+void _Malloc_Deferred_free( void * );
#ifdef __cplusplus
}
diff --git a/cpukit/libcsupport/src/rtems_malloc.c b/cpukit/libcsupport/src/rtems_malloc.c
deleted file mode 100644
index 9eaa1df60e..0000000000
--- a/cpukit/libcsupport/src/rtems_malloc.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/**
- * @file
- *
- * @ingroup libcsupport
- *
- * @brief rtems_malloc() implementation.
- */
-
-/*
- * Copyright (c) 2009
- * embedded brains GmbH
- * Obere Lagerstr. 30
- * D-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.org/license/LICENSE.
- */
-
-#if HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef RTEMS_NEWLIB
-#include "malloc_p.h"
-
-void *rtems_heap_allocate_aligned_with_boundary(
- size_t size,
- uintptr_t alignment,
- uintptr_t boundary
-)
-{
- if ( !malloc_is_system_state_OK() ) {
- return NULL;
- }
-
- malloc_deferred_frees_process();
-
- /* FIXME: Statistics, boundary checks */
-
- return _Protected_heap_Allocate_aligned_with_boundary(
- RTEMS_Malloc_Heap,
- size,
- alignment,
- boundary
- );
-}
-
-#endif
diff --git a/cpukit/libcsupport/src/rtems_memalign.c b/cpukit/libcsupport/src/rtems_memalign.c
index 5755fa0b3c..8e3363ebf3 100644
--- a/cpukit/libcsupport/src/rtems_memalign.c
+++ b/cpukit/libcsupport/src/rtems_memalign.c
@@ -41,24 +41,9 @@ int rtems_memalign(
*pointer = NULL;
/*
- * Do not attempt to allocate memory if not in correct system state.
- */
- if ( !malloc_is_system_state_OK() )
- return EINVAL;
-
- /*
- * If some free's have been deferred, then do them now.
- */
- malloc_deferred_frees_process();
-
- /*
* Perform the aligned allocation requested
*/
- return_this = _Protected_heap_Allocate_aligned(
- RTEMS_Malloc_Heap,
- size,
- alignment
- );
+ return_this = rtems_heap_allocate_aligned_with_boundary( size, alignment, 0 );
if ( !return_this )
return ENOMEM;