diff options
Diffstat (limited to 'cpukit/libcsupport/src/malloc.c')
-rw-r--r-- | cpukit/libcsupport/src/malloc.c | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/cpukit/libcsupport/src/malloc.c b/cpukit/libcsupport/src/malloc.c index 22221b6da5..f80e2401cb 100644 --- a/cpukit/libcsupport/src/malloc.c +++ b/cpukit/libcsupport/src/malloc.c @@ -33,6 +33,10 @@ #include <unistd.h> /* sbrk(2) */ +#include <chain.h> + +Chain_Control RTEMS_Malloc_GC_list; + rtems_id RTEMS_Malloc_Heap; size_t RTEMS_Malloc_Sbrk_amount; @@ -71,6 +75,11 @@ void RTEMS_Malloc_Initialize( rtems_unsigned32 u32_address; /* + * Initialize the garbage collection list to start with nothing on it. + */ + Chain_Initialize_empty(&RTEMS_Malloc_GC_list); + + /* * 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. @@ -150,6 +159,7 @@ void *malloc( rtems_unsigned32 the_size; rtems_unsigned32 sbrk_amount; rtems_status_code status; + Chain_Node *to_be_freed; MSBUMP(malloc_calls, 1); @@ -157,6 +167,22 @@ void *malloc( return (void *) 0; /* + * Do not attempt to allocate memory if in a critical section or ISR. + */ + + if (_Thread_Dispatch_disable_level > 0) + return (void *) 0; + + if (_ISR_Nest_level > 0) + return (void *) 0; + + /* + * If some free's have been deferred, then do them now. + */ + while ((to_be_freed = Chain_Get(&RTEMS_Malloc_GC_list)) != NULL) + free(to_be_freed); + + /* * Try to give a segment in the current region if there is not * enough space then try to grow the region using rtems_region_extend(). * If this fails then return a NULL pointer. @@ -267,6 +293,19 @@ void *realloc( MSBUMP(realloc_calls, 1); + /* + * Do not attempt to allocate memory if in a critical section or ISR. + */ + + if (_Thread_Dispatch_disable_level > 0) + return (void *) 0; + + if (_ISR_Nest_level > 0) + return (void *) 0; + + /* + * Continue with calloc(). + */ if ( !ptr ) return malloc( size ); @@ -313,6 +352,15 @@ void free( if ( !ptr ) return; + /* + * Do not attempt to free memory if in a critical section or ISR. + */ + + if ((_Thread_Dispatch_disable_level > 0) || (_ISR_Nest_level > 0)) { + Chain_Append(&RTEMS_Malloc_GC_list, (Chain_Node *)ptr); + return; + } + #ifdef MALLOC_STATS { unsigned32 size; |