source: rtems/cpukit/score/src/heapextend.c @ a8eed23

4.104.114.84.9
Last change on this file since a8eed23 was a8eed23, checked in by Ralf Corsepius <ralf.corsepius@…>, on Jan 27, 2005 at 5:57:05 AM

Include config.h.

  • Property mode set to 100644
File size: 2.8 KB
Line 
1/*
2 *  Heap Handler
3 *
4 *  COPYRIGHT (c) 1989-1999.
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
22/*PAGE
23 *
24 *  _Heap_Extend
25 *
26 *  This routine grows the_heap memory area using the size bytes which
27 *  begin at starting_address.
28 *
29 *  Input parameters:
30 *    the_heap          - pointer to heap header.
31 *    starting_address  - pointer to the memory area.
32 *    size              - size in bytes of the memory block to allocate.
33 *
34 *  Output parameters:
35 *    *amount_extended  - amount of memory added to the_heap
36 */
37
38Heap_Extend_status _Heap_Extend(
39  Heap_Control        *the_heap,
40  void                *starting_address,
41  uint32_t             size,
42  uint32_t            *amount_extended
43)
44{
45  uint32_t         the_size;
46  Heap_Statistics *const stats = &the_heap->stats;
47
48  /*
49   *  The overhead was taken from the original heap memory.
50   */
51
52  Heap_Block  *old_final;
53  Heap_Block  *new_final;
54
55  /*
56   *  There are five possibilities for the location of starting
57   *  address:
58   *
59   *    1. non-contiguous lower address     (NOT SUPPORTED)
60   *    2. contiguous lower address         (NOT SUPPORTED)
61   *    3. in the heap                      (ERROR)
62   *    4. contiguous higher address        (SUPPORTED)
63   *    5. non-contiguous higher address    (NOT SUPPORTED)
64   *
65   *  As noted, this code only supports (4).
66   */
67
68  if ( starting_address >= the_heap->begin &&        /* case 3 */
69       starting_address < the_heap->end
70     )
71    return HEAP_EXTEND_ERROR;
72
73  if ( starting_address != the_heap->end )
74    return HEAP_EXTEND_NOT_IMPLEMENTED;         /* cases 1, 2, and 5 */
75
76  /*
77   *  Currently only case 4 should make it to this point.
78   *  The basic trick is to make the extend area look like a used
79   *  block and free it.
80   */
81
82  old_final = the_heap->final;
83  the_heap->end = _Addresses_Add_offset( the_heap->end, size );
84  the_size = _Addresses_Subtract( the_heap->end, old_final ) - HEAP_OVERHEAD;
85  _Heap_Align_down( &the_size, the_heap->page_size );
86
87  *amount_extended = size;
88
89  if( the_size < the_heap->min_block_size )
90    return HEAP_EXTEND_SUCCESSFUL;
91
92  old_final->size = the_size | (old_final->size & HEAP_PREV_USED);
93  new_final = _Heap_Block_at( old_final, the_size );
94  new_final->size = HEAP_PREV_USED;
95  the_heap->final = new_final;
96
97  stats->size += size;
98  stats->used_blocks += 1;
99  stats->frees -= 1;    /* Don't count subsequent call as actual free() */
100
101  _Heap_Free( the_heap, _Heap_User_area( old_final ) );
102
103  return HEAP_EXTEND_SUCCESSFUL;
104}
Note: See TracBrowser for help on using the repository browser.