[rtems commit] malloc: Add _Malloc_System_state()
Sebastian Huber
sebh at rtems.org
Thu Feb 25 10:55:09 UTC 2016
Module: rtems
Branch: master
Commit: 9d1f39434585e8d3f8897d95a2bfe1ddccb79aec
Changeset: http://git.rtems.org/rtems/commit/?id=9d1f39434585e8d3f8897d95a2bfe1ddccb79aec
Author: Sebastian Huber <sebastian.huber at embedded-brains.de>
Date: Thu Feb 25 09:02:43 2016 +0100
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.
---
cpukit/libcsupport/Makefile.am | 2 +-
cpukit/libcsupport/src/free.c | 8 +---
cpukit/libcsupport/src/malloc.c | 33 ++--------------
cpukit/libcsupport/src/malloc_deferred.c | 68 +++++++++++++++++++++++++++++---
cpukit/libcsupport/src/malloc_p.h | 15 ++++---
cpukit/libcsupport/src/rtems_malloc.c | 51 ------------------------
cpukit/libcsupport/src/rtems_memalign.c | 17 +-------
testsuites/libtests/malloctest/init.c | 27 ++++++++++++-
8 files changed, 105 insertions(+), 116 deletions(-)
diff --git a/cpukit/libcsupport/Makefile.am b/cpukit/libcsupport/Makefile.am
index 0b2607f..eee9da7 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 63eb7b8..f3d4cb8 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 73203e5..03e2208 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 395ed64..e781a05 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 6609526..127f22b 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 9eaa1df..0000000
--- 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 at 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 5755fa0..8e3363e 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;
diff --git a/testsuites/libtests/malloctest/init.c b/testsuites/libtests/malloctest/init.c
index 7e1728d..acf25d7 100644
--- a/testsuites/libtests/malloctest/init.c
+++ b/testsuites/libtests/malloctest/init.c
@@ -2,7 +2,7 @@
* COPYRIGHT (c) 1989-2011, 2014.
* On-Line Applications Research Corporation (OAR).
*
- * Copyright (c) 2009, 2010 embedded brains GmbH.
+ * Copyright (c) 2009, 2016 embedded brains GmbH.
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
@@ -22,6 +22,7 @@
#include <errno.h>
#include <rtems/score/protectedheap.h>
#include <rtems/malloc.h>
+#include <rtems/sysinit.h>
const char rtems_test_name[] = "MALLOCTEST";
@@ -1369,3 +1370,27 @@ rtems_task Init(
status = rtems_task_delete( RTEMS_SELF );
directive_failed( status, "rtems_task_delete of RTEMS_SELF" );
}
+
+static void test_early_malloc( void )
+{
+ void *p;
+ char *q;
+
+ p = malloc( 1 );
+ rtems_test_assert( p != NULL );
+
+ free( p );
+
+ q = calloc( 1, 1 );
+ rtems_test_assert( q != NULL );
+ rtems_test_assert( p != q );
+ rtems_test_assert( q[0] == 0 );
+
+ free( q );
+}
+
+RTEMS_SYSINIT_ITEM(
+ test_early_malloc,
+ RTEMS_SYSINIT_INITIAL_EXTENSIONS,
+ RTEMS_SYSINIT_ORDER_FIRST
+);
More information about the vc
mailing list