diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-02-25 09:02:43 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-02-25 11:35:54 +0100 |
commit | 9d1f39434585e8d3f8897d95a2bfe1ddccb79aec (patch) | |
tree | 2d3a0868f410cff137871f5ce493df4f27a22b1a /cpukit/libcsupport | |
parent | malloc: Use dedicated lock for deferred frees (diff) | |
download | rtems-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.am | 2 | ||||
-rw-r--r-- | cpukit/libcsupport/src/free.c | 8 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc.c | 33 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc_deferred.c | 68 | ||||
-rw-r--r-- | cpukit/libcsupport/src/malloc_p.h | 15 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rtems_malloc.c | 51 | ||||
-rw-r--r-- | cpukit/libcsupport/src/rtems_memalign.c | 17 |
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; |