This prevents that asynchronous thread deletion can lead to an unusable allocator or once mutex. --- .../arm/altera-cyclone-v/startup/nocache-heap.c | 10 ++-- c/src/lib/libbsp/shared/src/irq-generic.c | 47 ++++++++++------- cpukit/libcsupport/src/malloc_get_statistics.c | 8 ++- cpukit/libcsupport/src/rtems_heap_greedy.c | 16 ++++-- cpukit/rtems/src/regioncreate.c | 6 ++- cpukit/rtems/src/regiondelete.c | 6 ++- cpukit/score/include/rtems/score/apimutex.h | 56 ++++++++++--------- cpukit/score/src/apimutexlock.c | 11 +++-- cpukit/score/src/apimutexunlock.c | 6 ++- cpukit/score/src/once.c | 4 +- cpukit/score/src/pheapallocate.c | 5 +- cpukit/score/src/pheapextend.c | 5 +- cpukit/score/src/pheapfree.c | 8 ++- cpukit/score/src/pheapgetblocksize.c | 6 ++- cpukit/score/src/pheapgetfreeinfo.c | 4 +- cpukit/score/src/pheapgetinfo.c | 6 ++- cpukit/score/src/pheapiterate.c | 4 +- cpukit/score/src/pheapresizeblock.c | 6 ++- cpukit/score/src/pheapwalk.c | 4 +- 19 files changed, 129 insertions(+), 89 deletions(-)
diff --git a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c index 0f01989..bf85c8f 100644 --- a/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c +++ b/c/src/lib/libbsp/arm/altera-cyclone-v/startup/nocache-heap.c @@ -62,10 +62,11 @@ void altera_cyclone_v_nocache_init_heap( void ) void *altera_cyclone_v_nocache_malloc( const size_t size ) { void* ret = NULL; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); ret = _Heap_Allocate( &nocache_heap, size ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return ret; } @@ -79,10 +80,11 @@ void altera_cyclone_v_nocache_free( void *ptr ) { if ( ptr != NULL ) { bool ok; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); ok = _Heap_Free( &nocache_heap, ptr ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); assert( ok ); } diff --git a/c/src/lib/libbsp/shared/src/irq-generic.c b/c/src/lib/libbsp/shared/src/irq-generic.c index e30372d..777454d 100644 --- a/c/src/lib/libbsp/shared/src/irq-generic.c +++ b/c/src/lib/libbsp/shared/src/irq-generic.c @@ -153,17 +153,23 @@ static void bsp_interrupt_free_handler_entry(bsp_interrupt_handler_entry *e) #endif } -static void bsp_interrupt_lock(void) +static bool bsp_interrupt_lock(void) { + bool previous_thread_life_protection; + if (_System_state_Is_up(_System_state_Get())) { - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); + } else { + previous_thread_life_protection = false; } + + return previous_thread_life_protection; } -static void bsp_interrupt_unlock(void) +static void bsp_interrupt_unlock(bool previous_thread_life_protection) { if (_System_state_Is_up(_System_state_Get())) { - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator(previous_thread_life_protection); } } @@ -208,6 +214,7 @@ static rtems_status_code bsp_interrupt_handler_install( ) { rtems_status_code sc = RTEMS_SUCCESSFUL; + bool previous_thread_life_protection; rtems_interrupt_level level; rtems_vector_number index = 0; bsp_interrupt_handler_entry *head = NULL; @@ -226,7 +233,7 @@ static rtems_status_code bsp_interrupt_handler_install( } /* Lock */ - bsp_interrupt_lock(); + previous_thread_life_protection = bsp_interrupt_lock(); /* Get handler table index */ index = bsp_interrupt_handler_index(vector); @@ -237,7 +244,7 @@ static rtems_status_code bsp_interrupt_handler_install( if (bsp_interrupt_is_empty_handler_entry(head)) { if (replace) { /* No handler to replace exists */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_UNSATISFIED; } @@ -257,7 +264,7 @@ static rtems_status_code bsp_interrupt_handler_install( bsp_interrupt_handler_table [index].info = info; } else { /* Handler table is full */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_NO_MEMORY; } @@ -278,7 +285,7 @@ static rtems_status_code bsp_interrupt_handler_install( * Tried to install a unique handler on a not empty * list or there is already a unique handler installed. */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_RESOURCE_IN_USE; } @@ -301,7 +308,7 @@ static rtems_status_code bsp_interrupt_handler_install( if (replace) { /* Ensure that a handler to replace exists */ if (match == NULL) { - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_UNSATISFIED; } @@ -311,7 +318,7 @@ static rtems_status_code bsp_interrupt_handler_install( /* Ensure the handler is not already installed */ if (match != NULL) { /* The handler is already installed */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_TOO_MANY; } @@ -319,7 +326,7 @@ static rtems_status_code bsp_interrupt_handler_install( current = bsp_interrupt_allocate_handler_entry(); if (current == NULL) { /* Not enough memory */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_NO_MEMORY; } } @@ -348,13 +355,13 @@ static rtems_status_code bsp_interrupt_handler_install( if (enable_vector) { sc = bsp_interrupt_vector_enable(vector); if (sc != RTEMS_SUCCESSFUL) { - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return sc; } } /* Unlock */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_SUCCESSFUL; } @@ -376,6 +383,7 @@ static rtems_status_code bsp_interrupt_handler_remove( ) { rtems_status_code sc = RTEMS_SUCCESSFUL; + bool previous_thread_life_protection; rtems_interrupt_level level; rtems_vector_number index = 0; bsp_interrupt_handler_entry *head = NULL; @@ -395,7 +403,7 @@ static rtems_status_code bsp_interrupt_handler_remove( } /* Lock */ - bsp_interrupt_lock(); + previous_thread_life_protection = bsp_interrupt_lock(); /* Get handler table index */ index = bsp_interrupt_handler_index(vector); @@ -461,7 +469,7 @@ static rtems_status_code bsp_interrupt_handler_remove( /* Check status code */ if (sc != RTEMS_SUCCESSFUL) { - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return sc; } } else { @@ -478,12 +486,12 @@ static rtems_status_code bsp_interrupt_handler_remove( } } else { /* No matching entry found */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_UNSATISFIED; } /* Unlock */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_SUCCESSFUL; } @@ -504,6 +512,7 @@ static rtems_status_code bsp_interrupt_handler_iterate( void *arg ) { + bool previous_thread_life_protection; bsp_interrupt_handler_entry *current = NULL; rtems_option options = 0; rtems_vector_number index = 0; @@ -518,7 +527,7 @@ static rtems_status_code bsp_interrupt_handler_iterate( } /* Lock */ - bsp_interrupt_lock(); + previous_thread_life_protection = bsp_interrupt_lock(); /* Interate */ index = bsp_interrupt_handler_index(vector); @@ -533,7 +542,7 @@ static rtems_status_code bsp_interrupt_handler_iterate( } /* Unlock */ - bsp_interrupt_unlock(); + bsp_interrupt_unlock(previous_thread_life_protection); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/libcsupport/src/malloc_get_statistics.c b/cpukit/libcsupport/src/malloc_get_statistics.c index a54a4c1..039baca 100644 --- a/cpukit/libcsupport/src/malloc_get_statistics.c +++ b/cpukit/libcsupport/src/malloc_get_statistics.c @@ -25,11 +25,15 @@ int malloc_get_statistics( rtems_malloc_statistics_t *stats ) { + bool previous_thread_life_protection; + if ( !stats ) return -1; - _RTEMS_Lock_allocator(); + + previous_thread_life_protection = _RTEMS_Lock_allocator(); *stats = rtems_malloc_statistics; - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return 0; } diff --git a/cpukit/libcsupport/src/rtems_heap_greedy.c b/cpukit/libcsupport/src/rtems_heap_greedy.c index 9a55e39..083a8e4 100644 --- a/cpukit/libcsupport/src/rtems_heap_greedy.c +++ b/cpukit/libcsupport/src/rtems_heap_greedy.c @@ -31,10 +31,11 @@ void *rtems_heap_greedy_allocate( ) { void *opaque; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); opaque = _Heap_Greedy_allocate( RTEMS_Malloc_Heap, block_sizes, block_count ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return opaque; } @@ -44,20 +45,23 @@ void *rtems_heap_greedy_allocate_all_except_largest( ) { void *opaque; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); opaque = _Heap_Greedy_allocate_all_except_largest( RTEMS_Malloc_Heap, allocatable_size ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return opaque; } void rtems_heap_greedy_free( void *opaque ) { - _RTEMS_Lock_allocator(); + bool previous_thread_life_protection; + + previous_thread_life_protection = _RTEMS_Lock_allocator(); _Heap_Greedy_free( RTEMS_Malloc_Heap, opaque ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); } diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c index 3b4325e..23d42fc 100644 --- a/cpukit/rtems/src/regioncreate.c +++ b/cpukit/rtems/src/regioncreate.c @@ -56,6 +56,7 @@ rtems_status_code rtems_region_create( { rtems_status_code return_status; Region_Control *the_region; + bool previous_thread_life_protection; if ( !rtems_is_name_valid( name ) ) return RTEMS_INVALID_NAME; @@ -66,7 +67,7 @@ rtems_status_code rtems_region_create( if ( !id ) return RTEMS_INVALID_ADDRESS; - _RTEMS_Lock_allocator(); /* to prevent deletion */ + previous_thread_life_protection = _RTEMS_Lock_allocator(); the_region = _Region_Allocate(); @@ -111,6 +112,7 @@ rtems_status_code rtems_region_create( } } - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return return_status; } diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c index 5144db0..b793dc6 100644 --- a/cpukit/rtems/src/regiondelete.c +++ b/cpukit/rtems/src/regiondelete.c @@ -33,8 +33,9 @@ rtems_status_code rtems_region_delete( Objects_Locations location; rtems_status_code return_status; Region_Control *the_region; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); the_region = _Region_Get( id, &location ); switch ( location ) { @@ -61,6 +62,7 @@ rtems_status_code rtems_region_delete( break; } - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return return_status; } diff --git a/cpukit/score/include/rtems/score/apimutex.h b/cpukit/score/include/rtems/score/apimutex.h index 380f054..80ccabb 100644 --- a/cpukit/score/include/rtems/score/apimutex.h +++ b/cpukit/score/include/rtems/score/apimutex.h @@ -66,20 +66,26 @@ void _API_Mutex_Initialization( uint32_t maximum_mutexes ); void _API_Mutex_Allocate( API_Mutex_Control **mutex ); /** - * @brief Acquires the specified API mutex. + * @brief Acquires the specified API mutex. + * + * @param[in] mutex The API mutex. + * + * @return The previous life protection of the executing thread. */ -void _API_Mutex_Lock( - API_Mutex_Control *mutex - ); +bool _API_Mutex_Lock( API_Mutex_Control *mutex ); /** - * @brief Releases the specified API mutex. + * @brief Releases the specified API mutex. * - * Releases the specified @a mutex. - * - * @param[in] mutex is the mutex to be removed. + * @param[in] mutex The API mutex. + * @param[in] previous_thread_life_protection The previous life protection of + * the executing thread. Must be the value returned by the corresponding + * _API_Mutex_Lock() call. */ -void _API_Mutex_Unlock( API_Mutex_Control *mutex ); +void _API_Mutex_Unlock( + API_Mutex_Control *mutex, + bool previous_thread_life_protection +); /** @} */ @@ -104,32 +110,28 @@ void _API_Mutex_Unlock( API_Mutex_Control *mutex ); */ SCORE_EXTERN API_Mutex_Control *_RTEMS_Allocator_Mutex; -/** - * @brief Macro to ease locking the allocator mutex. - * - * This macro makes it explicit that one is locking the allocator mutex. - */ -#define _RTEMS_Lock_allocator() \ - _API_Mutex_Lock( _RTEMS_Allocator_Mutex ) +static inline bool _RTEMS_Lock_allocator( void ) +{ + return _API_Mutex_Lock( _RTEMS_Allocator_Mutex ); +} -/** - * @brief Macro to ease unlocking the allocator mutex. - * - * This macro makes it explicit that one is unlocking the allocator mutex. - */ -#define _RTEMS_Unlock_allocator() \ - _API_Mutex_Unlock( _RTEMS_Allocator_Mutex ) +static inline void _RTEMS_Unlock_allocator( + bool previous_thread_life_protection +) +{ + _API_Mutex_Unlock( _RTEMS_Allocator_Mutex, previous_thread_life_protection ); +} SCORE_EXTERN API_Mutex_Control *_Once_Mutex; -static inline void _Once_Lock( void ) +static inline bool _Once_Lock( void ) { - _API_Mutex_Lock( _Once_Mutex ); + return _API_Mutex_Lock( _Once_Mutex ); } -static inline void _Once_Unlock( void ) +static inline void _Once_Unlock( bool previous_thread_life_protection ) { - _API_Mutex_Unlock( _Once_Mutex ); + _API_Mutex_Unlock( _Once_Mutex, previous_thread_life_protection ); } /** @} */ diff --git a/cpukit/score/src/apimutexlock.c b/cpukit/score/src/apimutexlock.c index d943bdd..e506245 100644 --- a/cpukit/score/src/apimutexlock.c +++ b/cpukit/score/src/apimutexlock.c @@ -19,16 +19,17 @@ #include "config.h" #endif -#include <rtems/system.h> #include <rtems/score/apimutex.h> #include <rtems/score/coremuteximpl.h> +#include <rtems/score/threadimpl.h> -void _API_Mutex_Lock( - API_Mutex_Control *the_mutex -) +bool _API_Mutex_Lock( API_Mutex_Control *the_mutex ) { + bool previous_thread_life_protection; ISR_Level level; + previous_thread_life_protection = _Thread_Set_life_protection( true ); + #if defined(RTEMS_SMP) _Thread_Disable_dispatch(); #endif @@ -47,4 +48,6 @@ void _API_Mutex_Lock( #if defined(RTEMS_SMP) _Thread_Enable_dispatch(); #endif + + return previous_thread_life_protection; } diff --git a/cpukit/score/src/apimutexunlock.c b/cpukit/score/src/apimutexunlock.c index 43bdfe8..3814004 100644 --- a/cpukit/score/src/apimutexunlock.c +++ b/cpukit/score/src/apimutexunlock.c @@ -19,12 +19,12 @@ #include "config.h" #endif -#include <rtems/system.h> #include <rtems/score/apimutex.h> #include <rtems/score/coremuteximpl.h> void _API_Mutex_Unlock( - API_Mutex_Control *the_mutex + API_Mutex_Control *the_mutex, + bool previous_thread_life_protection ) { _Thread_Disable_dispatch(); @@ -34,4 +34,6 @@ void _API_Mutex_Unlock( NULL ); _Thread_Enable_dispatch(); + + _Thread_Set_life_protection( previous_thread_life_protection ); } diff --git a/cpukit/score/src/once.c b/cpukit/score/src/once.c index 60ae7a7..e51719c 100644 --- a/cpukit/score/src/once.c +++ b/cpukit/score/src/once.c @@ -25,7 +25,7 @@ int _Once( int *once_state, void ( *init_routine )( void ) ) int eno = 0; if ( *once_state != ONCE_STATE_COMPLETE ) { - _Once_Lock(); + bool previous_thread_life_protection = _Once_Lock(); /* * Getting to here means the once_control is locked so we have: @@ -49,7 +49,7 @@ int _Once( int *once_state, void ( *init_routine )( void ) ) break; } - _Once_Unlock(); + _Once_Unlock( previous_thread_life_protection ); } return eno; diff --git a/cpukit/score/src/pheapallocate.c b/cpukit/score/src/pheapallocate.c index 4fefb85..057c2e9 100644 --- a/cpukit/score/src/pheapallocate.c +++ b/cpukit/score/src/pheapallocate.c @@ -30,15 +30,16 @@ void *_Protected_heap_Allocate_aligned_with_boundary( ) { void *p; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); p = _Heap_Allocate_aligned_with_boundary( heap, size, alignment, boundary ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return p; } diff --git a/cpukit/score/src/pheapextend.c b/cpukit/score/src/pheapextend.c index 18f1992..89c44c4 100644 --- a/cpukit/score/src/pheapextend.c +++ b/cpukit/score/src/pheapextend.c @@ -29,10 +29,11 @@ bool _Protected_heap_Extend( ) { uintptr_t amount_extended; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); amount_extended = _Heap_Extend( the_heap, starting_address, size, 0 ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return amount_extended != 0; } diff --git a/cpukit/score/src/pheapfree.c b/cpukit/score/src/pheapfree.c index f87b824..f98fc77 100644 --- a/cpukit/score/src/pheapfree.c +++ b/cpukit/score/src/pheapfree.c @@ -27,10 +27,12 @@ bool _Protected_heap_Free( void *start_address ) { - bool status; + bool status; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); status = _Heap_Free( the_heap, start_address ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return status; } diff --git a/cpukit/score/src/pheapgetblocksize.c b/cpukit/score/src/pheapgetblocksize.c index 5a6f703..367e8a3 100644 --- a/cpukit/score/src/pheapgetblocksize.c +++ b/cpukit/score/src/pheapgetblocksize.c @@ -29,9 +29,11 @@ bool _Protected_heap_Get_block_size( ) { bool status; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); status = _Heap_Size_of_alloc_area( the_heap, starting_address, size ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return status; } diff --git a/cpukit/score/src/pheapgetfreeinfo.c b/cpukit/score/src/pheapgetfreeinfo.c index e442ba9..72bdb3e 100644 --- a/cpukit/score/src/pheapgetfreeinfo.c +++ b/cpukit/score/src/pheapgetfreeinfo.c @@ -31,9 +31,9 @@ bool _Protected_heap_Get_free_information( * TBD: _Heap_Get_free_information does not error check or return status. */ - _RTEMS_Lock_allocator(); + bool previous_thread_life_protection = _RTEMS_Lock_allocator(); _Heap_Get_free_information( the_heap, info ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return true; } diff --git a/cpukit/score/src/pheapgetinfo.c b/cpukit/score/src/pheapgetinfo.c index 6ece4e4..a0d0a3e 100644 --- a/cpukit/score/src/pheapgetinfo.c +++ b/cpukit/score/src/pheapgetinfo.c @@ -27,15 +27,17 @@ bool _Protected_heap_Get_information( Heap_Information_block *the_info ) { + bool previous_thread_life_protection; + if ( !the_heap ) return false; if ( !the_info ) return false; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); _Heap_Get_information( the_heap, the_info ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); return true; } diff --git a/cpukit/score/src/pheapiterate.c b/cpukit/score/src/pheapiterate.c index 9b6d945..6bea29f 100644 --- a/cpukit/score/src/pheapiterate.c +++ b/cpukit/score/src/pheapiterate.c @@ -32,7 +32,7 @@ void _Protected_heap_Iterate( void *visitor_arg ) { - _RTEMS_Lock_allocator(); + bool previous_thread_life_protection = _RTEMS_Lock_allocator(); _Heap_Iterate( heap, visitor, visitor_arg ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); } diff --git a/cpukit/score/src/pheapresizeblock.c b/cpukit/score/src/pheapresizeblock.c index c733ddc..416485e 100644 --- a/cpukit/score/src/pheapresizeblock.c +++ b/cpukit/score/src/pheapresizeblock.c @@ -31,11 +31,13 @@ bool _Protected_heap_Resize_block( Heap_Resize_status status; uintptr_t old_mem_size; uintptr_t avail_mem_size; + bool previous_thread_life_protection; - _RTEMS_Lock_allocator(); + previous_thread_life_protection = _RTEMS_Lock_allocator(); status = _Heap_Resize_block( the_heap, starting_address, size, &old_mem_size, &avail_mem_size ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); + return (status == HEAP_RESIZE_SUCCESSFUL); } diff --git a/cpukit/score/src/pheapwalk.c b/cpukit/score/src/pheapwalk.c index 5605470..6b18c77 100644 --- a/cpukit/score/src/pheapwalk.c +++ b/cpukit/score/src/pheapwalk.c @@ -38,9 +38,9 @@ bool _Protected_heap_Walk( * NOTE: Dispatching is also disabled during initialization. */ if ( _Thread_Dispatch_is_enabled() ) { - _RTEMS_Lock_allocator(); + bool previous_thread_life_protection = _RTEMS_Lock_allocator(); status = _Heap_Walk( the_heap, source, do_dump ); - _RTEMS_Unlock_allocator(); + _RTEMS_Unlock_allocator( previous_thread_life_protection ); } else { status = _Heap_Walk( the_heap, source, do_dump ); } -- 1.7.7 _______________________________________________ rtems-devel mailing list rtems-devel@rtems.org http://www.rtems.org/mailman/listinfo/rtems-devel