source: rtems/cpukit/score/src/heapfree.c @ e3f6d35

4.10
Last change on this file since e3f6d35 was dea3eccb, checked in by Joel Sherrill <joel.sherrill@…>, on 09/06/09 at 15:24:08

2009-09-06 Sebastian Huber <Sebastian.Huber@…>

  • libcsupport/src/free.c, libmisc/stackchk/check.c, rtems/include/rtems/rtems/region.h, rtems/src/regioncreate.c, rtems/src/regionextend.c, rtems/src/regiongetinfo.c, rtems/src/regiongetsegment.c, rtems/src/regiongetsegmentsize.c, rtems/src/regionresizesegment.c, score/src/pheapallocate.c, score/src/pheapallocatealigned.c, score/src/pheapextend.c, score/src/pheapfree.c, score/src/pheapgetblocksize.c, score/src/pheapgetfreeinfo.c, score/src/pheapgetinfo.c, score/src/pheapgetsize.c, score/src/pheapinit.c, score/src/pheapresizeblock.c, score/src/pheapwalk.c: Update for heap API changes.
  • score/include/rtems/score/apimutex.h, score/include/rtems/score/object.h: Documentation.
  • score/include/rtems/score/heap.h, score/include/rtems/score/protectedheap.h, score/inline/rtems/score/heap.inl, score/src/heap.c, score/src/heapallocate.c, score/src/heapallocatealigned.c, score/src/heapextend.c, score/src/heapfree.c, score/src/heapgetfreeinfo.c, score/src/heapgetinfo.c, score/src/heapresizeblock.c, score/src/heapsizeofuserarea.c, score/src/heapwalk.c: Overall cleanup. Added boundary constraint to allocation function. More changes follow.
  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup ScoreHeap
5 *
6 * @brief Heap Handler implementation.
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2007.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.com/license/LICENSE.
16 *
17 *  $Id$
18 */
19
20#if HAVE_CONFIG_H
21#include "config.h"
22#endif
23
24#include <rtems/system.h>
25#include <rtems/score/sysstate.h>
26#include <rtems/score/heap.h>
27
28bool _Heap_Free( Heap_Control *heap, void *alloc_begin_ptr )
29{
30  Heap_Statistics *const stats = &heap->stats;
31  uintptr_t alloc_begin = (uintptr_t) alloc_begin_ptr;
32  Heap_Block *block =
33    _Heap_Block_of_alloc_area( alloc_begin, heap->page_size );
34  Heap_Block *next_block = NULL;
35  uintptr_t block_size = 0;
36  uintptr_t next_block_size = 0;
37  bool next_is_free = false;
38
39  if ( !_Heap_Is_block_in_heap( heap, block ) ) {
40    return false;
41  }
42
43  block_size = _Heap_Block_size( block );
44  next_block = _Heap_Block_at( block, block_size );
45
46  if ( !_Heap_Is_block_in_heap( heap, next_block ) ) {
47    _HAssert( false );
48    return false;
49  }
50
51  if ( !_Heap_Is_prev_used( next_block ) ) {
52    _HAssert( false );
53    return false;
54  }
55
56  next_block_size = _Heap_Block_size( next_block );
57  next_is_free = next_block != heap->last_block
58    && !_Heap_Is_prev_used( _Heap_Block_at( next_block, next_block_size ));
59
60  if ( !_Heap_Is_prev_used( block ) ) {
61    uintptr_t const prev_size = block->prev_size;
62    Heap_Block * const prev_block = _Heap_Block_at( block, -prev_size );
63
64    if ( !_Heap_Is_block_in_heap( heap, prev_block ) ) {
65      _HAssert( false );
66      return( false );
67    }
68
69    /* As we always coalesce free blocks, the block that preceedes prev_block
70       must have been used. */
71    if ( !_Heap_Is_prev_used ( prev_block) ) {
72      _HAssert( false );
73      return( false );
74    }
75
76    if ( next_is_free ) {       /* coalesce both */
77      uintptr_t const size = block_size + prev_size + next_block_size;
78      _Heap_Free_list_remove( next_block );
79      stats->free_blocks -= 1;
80      prev_block->size_and_flag = size | HEAP_PREV_BLOCK_USED;
81      next_block = _Heap_Block_at( prev_block, size );
82      _HAssert(!_Heap_Is_prev_used( next_block));
83      next_block->prev_size = size;
84    } else {                      /* coalesce prev */
85      uintptr_t const size = block_size + prev_size;
86      prev_block->size_and_flag = size | HEAP_PREV_BLOCK_USED;
87      next_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
88      next_block->prev_size = size;
89    }
90  } else if ( next_is_free ) {    /* coalesce next */
91    uintptr_t const size = block_size + next_block_size;
92    _Heap_Free_list_replace( next_block, block );
93    block->size_and_flag = size | HEAP_PREV_BLOCK_USED;
94    next_block  = _Heap_Block_at( block, size );
95    next_block->prev_size = size;
96  } else {                        /* no coalesce */
97    /* Add 'block' to the head of the free blocks list as it tends to
98       produce less fragmentation than adding to the tail. */
99    _Heap_Free_list_insert_after( _Heap_Free_list_head( heap), block );
100    block->size_and_flag = block_size | HEAP_PREV_BLOCK_USED;
101    next_block->size_and_flag &= ~HEAP_PREV_BLOCK_USED;
102    next_block->prev_size = block_size;
103
104    /* Statistics */
105    ++stats->free_blocks;
106    if ( stats->max_free_blocks < stats->free_blocks ) {
107      stats->max_free_blocks = stats->free_blocks;
108    }
109  }
110
111  /* Statistics */
112  --stats->used_blocks;
113  ++stats->frees;
114  stats->free_size += block_size;
115
116  return( true );
117}
Note: See TracBrowser for help on using the repository browser.