[rtems commit] score: _Heap_Protection_set_delayed_free_fraction

Sebastian Huber sebh at rtems.org
Mon Mar 24 14:53:27 UTC 2014


Module:    rtems
Branch:    master
Commit:    2a713e3b944625c45154f0ea7f5703e918de758b
Changeset: http://git.rtems.org/rtems/commit/?id=2a713e3b944625c45154f0ea7f5703e918de758b

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Mar 24 15:57:29 2014 +0100

score: _Heap_Protection_set_delayed_free_fraction

Add and use _Heap_Protection_set_delayed_free_fraction().  This makes it
possible to avoid a dependency on _Thread_Dispatch_is_enabled().

---

 cpukit/score/include/rtems/score/heap.h     |    1 +
 cpukit/score/include/rtems/score/heapimpl.h |   23 ++++++++++++++++++++++
 cpukit/score/src/heap.c                     |    2 +
 cpukit/score/src/heapallocate.c             |    4 ++-
 cpukit/score/src/heapfree.c                 |   28 ++++++--------------------
 cpukit/score/src/wkspace.c                  |    2 +
 6 files changed, 38 insertions(+), 22 deletions(-)

diff --git a/cpukit/score/include/rtems/score/heap.h b/cpukit/score/include/rtems/score/heap.h
index 62a64e5..1ca840d 100644
--- a/cpukit/score/include/rtems/score/heap.h
+++ b/cpukit/score/include/rtems/score/heap.h
@@ -161,6 +161,7 @@ typedef struct Heap_Block Heap_Block;
     Heap_Block *first_delayed_free_block;
     Heap_Block *last_delayed_free_block;
     uintptr_t delayed_free_block_count;
+    uintptr_t delayed_free_fraction;
   } Heap_Protection;
 
   typedef struct {
diff --git a/cpukit/score/include/rtems/score/heapimpl.h b/cpukit/score/include/rtems/score/heapimpl.h
index abc573d..a8948ed 100644
--- a/cpukit/score/include/rtems/score/heapimpl.h
+++ b/cpukit/score/include/rtems/score/heapimpl.h
@@ -347,6 +347,29 @@ Heap_Block *_Heap_Block_allocate(
   }
 #endif
 
+/**
+ * @brief Sets the fraction of delayed free blocks that is actually freed
+ * during memory shortage.
+ *
+ * The default is to free half the delayed free blocks.  This is equal to a
+ * fraction value of two.
+ *
+ * @param[in] heap The heap control.
+ * @param[in] fraction The fraction is one divided by this fraction value.
+ */
+RTEMS_INLINE_ROUTINE void _Heap_Protection_set_delayed_free_fraction(
+  Heap_Control *heap,
+  uintptr_t fraction
+)
+{
+#ifdef HEAP_PROTECTION
+  heap->Protection.delayed_free_fraction = fraction;
+#else
+  (void) heap;
+  (void) fraction;
+#endif
+}
+
 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_head( Heap_Control *heap )
 {
   return &heap->free_list;
diff --git a/cpukit/score/src/heap.c b/cpukit/score/src/heap.c
index fa2430a..949e963 100644
--- a/cpukit/score/src/heap.c
+++ b/cpukit/score/src/heap.c
@@ -285,6 +285,8 @@ uintptr_t _Heap_Initialize(
   stats->max_free_blocks = 1;
   stats->instance = instance++;
 
+  _Heap_Protection_set_delayed_free_fraction( heap, 2 );
+
   _HAssert( _Heap_Is_aligned( heap->page_size, CPU_ALIGNMENT ) );
   _HAssert( _Heap_Is_aligned( heap->min_block_size, page_size ) );
   _HAssert(
diff --git a/cpukit/score/src/heapallocate.c b/cpukit/score/src/heapallocate.c
index f8a4820..597077e 100644
--- a/cpukit/score/src/heapallocate.c
+++ b/cpukit/score/src/heapallocate.c
@@ -34,7 +34,9 @@
   {
     bool search_again = false;
     uintptr_t const blocks_to_free_count =
-      (heap->Protection.delayed_free_block_count + 1) / 2;
+      (heap->Protection.delayed_free_block_count
+         + heap->Protection.delayed_free_fraction - 1)
+      / heap->Protection.delayed_free_fraction;
 
     if ( alloc_begin == 0 && blocks_to_free_count > 0 ) {
       Heap_Block *block_to_free = heap->Protection.first_delayed_free_block;
diff --git a/cpukit/score/src/heapfree.c b/cpukit/score/src/heapfree.c
index df51438..e577e13 100644
--- a/cpukit/score/src/heapfree.c
+++ b/cpukit/score/src/heapfree.c
@@ -20,7 +20,6 @@
 #endif
 
 #include <rtems/score/heapimpl.h>
-#include <rtems/score/threadimpl.h>
 
 #ifndef HEAP_PROTECTION
   #define _Heap_Protection_determine_block_free( heap, block ) true
@@ -83,26 +82,13 @@
     bool do_free = true;
     Heap_Block *const next = block->Protection_begin.next_delayed_free_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 );
+    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 );
     }
 
     return do_free;
diff --git a/cpukit/score/src/wkspace.c b/cpukit/score/src/wkspace.c
index a1460ff..071c178 100644
--- a/cpukit/score/src/wkspace.c
+++ b/cpukit/score/src/wkspace.c
@@ -123,6 +123,8 @@ void _Workspace_Handler_initialization(
       INTERNAL_ERROR_TOO_LITTLE_WORKSPACE
     );
   }
+
+  _Heap_Protection_set_delayed_free_fraction( &_Workspace_Area, 1 );
 }
 
 void *_Workspace_Allocate(




More information about the vc mailing list