source: rtems/cpukit/score/src/heapallocate.c @ 20f54e9

4.104.114.84.95
Last change on this file since 20f54e9 was 93b4e6ef, checked in by Joel Sherrill <joel.sherrill@…>, on 11/02/99 at 21:05:17

Split Heap and Time of Day Handlers.

  • Property mode set to 100644
File size: 2.9 KB
Line 
1/*
2 *  Heap Handler
3 *
4 *  COPYRIGHT (c) 1989-1998.
5 *  On-Line Applications Research Corporation (OAR).
6 *  Copyright assigned to U.S. Government, 1994.
7 *
8 *  The license and distribution terms for this file may be
9 *  found in the file LICENSE in this distribution or at
10 *  http://www.OARcorp.com/rtems/license.html.
11 *
12 *  $Id$
13 */
14
15
16#include <rtems/system.h>
17#include <rtems/score/sysstate.h>
18#include <rtems/score/heap.h>
19
20/*PAGE
21 *
22 *  _Heap_Allocate
23 *
24 *  This kernel routine allocates the requested size of memory
25 *  from the specified heap.
26 *
27 *  Input parameters:
28 *    the_heap  - pointer to heap header.
29 *    size      - size in bytes of the memory block to allocate.
30 *
31 *  Output parameters:
32 *    returns - starting address of memory block allocated
33 */
34
35void *_Heap_Allocate(
36  Heap_Control        *the_heap,
37  unsigned32           size
38)
39{
40  unsigned32  excess;
41  unsigned32  the_size;
42  Heap_Block *the_block;
43  Heap_Block *next_block;
44  Heap_Block *temporary_block;
45  void       *ptr;
46  unsigned32  offset;
47 
48  excess   = size % the_heap->page_size;
49  the_size = size + the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD;
50 
51  if ( excess )
52    the_size += the_heap->page_size - excess;
53
54  if ( the_size < sizeof( Heap_Block ) )
55    the_size = sizeof( Heap_Block );
56
57  for ( the_block = the_heap->first;
58        ;
59        the_block = the_block->next ) {
60    if ( the_block == _Heap_Tail( the_heap ) )
61      return( NULL );
62    if ( the_block->front_flag >= the_size )
63      break;
64  }
65
66  if ( (the_block->front_flag - the_size) >
67       (the_heap->page_size + HEAP_BLOCK_USED_OVERHEAD) ) {
68    the_block->front_flag -= the_size;
69    next_block             = _Heap_Next_block( the_block );
70    next_block->back_flag  = the_block->front_flag;
71
72    temporary_block            = _Heap_Block_at( next_block, the_size );
73    temporary_block->back_flag =
74    next_block->front_flag     = _Heap_Build_flag( the_size,
75                                    HEAP_BLOCK_USED );
76    ptr = _Heap_Start_of_user_area( next_block );
77  } else {
78    next_block                = _Heap_Next_block( the_block );
79    next_block->back_flag     = _Heap_Build_flag( the_block->front_flag,
80                                   HEAP_BLOCK_USED );
81    the_block->front_flag     = next_block->back_flag;
82    the_block->next->previous = the_block->previous;
83    the_block->previous->next = the_block->next;
84    ptr = _Heap_Start_of_user_area( the_block );
85  }
86 
87  /*
88   * round ptr up to a multiple of page size
89   * Have to save the bump amount in the buffer so that free can figure it out
90   */
91 
92  offset = the_heap->page_size - (((unsigned32) ptr) & (the_heap->page_size - 1));
93  ptr = _Addresses_Add_offset( ptr, offset );
94  *(((unsigned32 *) ptr) - 1) = offset;
95
96#ifdef RTEMS_DEBUG
97  {
98      unsigned32 ptr_u32;
99      ptr_u32 = (unsigned32) ptr;
100      if (ptr_u32 & (the_heap->page_size - 1))
101          abort();
102  }
103#endif
104
105  return ptr;
106}
107
Note: See TracBrowser for help on using the repository browser.