From 5f104eefb12c3fceb4bfc2ae7715aca20f3a9561 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 25 Mar 2014 08:53:33 +0100 Subject: [PATCH] score: Fix heap protection Partially revert commit 2a713e3b944625c45154f0ea7f5703e918de758. --- cpukit/score/src/heapfree.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/cpukit/score/src/heapfree.c b/cpukit/score/src/heapfree.c index e577e1313a..c45c294f3f 100644 --- a/cpukit/score/src/heapfree.c +++ b/cpukit/score/src/heapfree.c @@ -20,6 +20,7 @@ #endif #include +#include #ifndef HEAP_PROTECTION #define _Heap_Protection_determine_block_free( heap, block ) true @@ -82,13 +83,26 @@ bool do_free = true; Heap_Block *const next = block->Protection_begin.next_delayed_free_block; - if ( next == NULL ) { - _Heap_Protection_delay_block_free( heap, block ); - do_free = false; - } else if ( next == HEAP_PROTECTION_OBOLUS ) { - _Heap_Protection_check_free_block( heap, block ); - } else { - _Heap_Protection_block_error( heap, block ); + /* + * Sometimes after a free the allocated area is still in use. An example + * is the task stack of a thread that deletes itself. The thread dispatch + * disable level is a way to detect this use case. + */ + if ( _Thread_Dispatch_is_enabled() ) { + if ( next == NULL ) { + _Heap_Protection_delay_block_free( heap, block ); + do_free = false; + } else if ( next == HEAP_PROTECTION_OBOLUS ) { + _Heap_Protection_check_free_block( heap, block ); + } else { + _Heap_Protection_block_error( heap, block ); + } + } else if ( next == NULL ) { + /* + * This is a hack to prevent heavy workspace fragmentation which would + * lead to test suite failures. + */ + _Heap_Protection_free_all_delayed_blocks( heap ); } return do_free;