[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