source: rtems/cpukit/score/src/heapfree.c @ 371cea31

4.104.115
Last change on this file since 371cea31 was 371cea31, checked in by Joel Sherrill <joel.sherrill@…>, on 08/26/09 at 12:00:24

2009-08-24 Sebastian Huber <Sebastian.Huber@…>

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