source: rtems/cpukit/score/inline/rtems/score/heap.inl @ 962e894f

4.104.114.84.95
Last change on this file since 962e894f was 962e894f, checked in by Joel Sherrill <joel.sherrill@…>, on 01/20/05 at 18:22:29

2005-01-20 Sergei Organov <osv@…>

PR 536/rtems
Heap manager re-implementation to consume less memory and still satisfy
alignment requirements.


  • score/src/heap.c, score/src/heapallocate.c, score/src/heapextend.c, score/src/heapfree.c, score/src/heapgetinfo.c, score/src/heapgetfreeinfo.c, core/src/heapsizeofuserarea.c, score/src/heapwalk.c, core/macros/rtems/score/heap.inl, score/inline/rtems/score/heap.inl, score/include/rtems/score/heap.h: Reimplemented.
  • score/src/heapallocatealigned.c: new file
  • score/Makefile.am: HEAP_C_FILES: add score/src/heapallocatealigned.c
  • Property mode set to 100644
File size: 5.8 KB
Line 
1/**
2 *  @file  rtems/score/heap.inl
3 *
4 *  This file contains the static inline implementation of the inlined
5 *  routines from the heap handler.
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2004.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 *
16 *  $Id$
17 */
18
19#ifndef __HEAP_inl
20#define __HEAP_inl
21
22/**
23 *  @addtogroup ScoreHeap
24 *  @{
25 */
26
27#include <rtems/score/address.h>
28
29/**
30 *  This function returns the head of the specified heap.
31 */
32
33RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Head (
34  Heap_Control *the_heap
35)
36{
37  return &the_heap->free_list;
38}
39
40/**
41 *  This function returns the tail of the specified heap.
42 */
43
44RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Tail (
45  Heap_Control *the_heap
46)
47{
48  return &the_heap->free_list;
49}
50
51/**
52 *  Return the first free block of the specified heap.
53 */
54
55RTEMS_INLINE_ROUTINE Heap_Block *_Heap_First (
56  Heap_Control *the_heap
57)
58{
59  return _Heap_Head(the_heap)->next;
60}
61
62/*PAGE
63 *
64 *  _Heap_Last
65 *
66 *  DESCRIPTION:
67 *
68 *  Return the last free block of the specified heap.
69 */
70
71RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Last (
72  Heap_Control *the_heap
73)
74{
75  return _Heap_Tail(the_heap)->prev;
76}
77
78/*PAGE
79 *
80 *  _Heap_Block_remove
81 *
82 *  DESCRIPTION:
83 *
84 *  This function removes 'the_block' from doubly-linked list.
85 */
86
87RTEMS_INLINE_ROUTINE void _Heap_Block_remove (
88  Heap_Block *the_block
89)
90{
91  Heap_Block *block = the_block;
92
93  Heap_Block *next = block->next;
94  Heap_Block *prev = block->prev;
95  prev->next = next;
96  next->prev = prev;
97}
98
99/**
100 *  This function replaces @a old_block by @a new_block in doubly-linked list.
101 */
102
103RTEMS_INLINE_ROUTINE void _Heap_Block_replace (
104  Heap_Block *old_block,
105  Heap_Block *new_block
106)
107{
108  Heap_Block *block = old_block;
109  Heap_Block *next = block->next;
110  Heap_Block *prev = block->prev;
111
112  block = new_block;
113  block->next = next;
114  block->prev = prev;
115  next->prev = prev->next = block;
116}
117
118/**
119 *  This function inserts @a the_block after @a prev_block
120 *  in doubly-linked list.
121 */
122RTEMS_INLINE_ROUTINE void _Heap_Block_insert_after (
123  Heap_Block *prev_block,
124  Heap_Block *the_block
125)
126{
127  Heap_Block *prev = prev_block;
128  Heap_Block *block = the_block;
129
130  Heap_Block *next = prev->next;
131  block->next  = next;
132  block->prev  = prev;
133  next->prev = prev->next = block;
134}
135
136/**
137 *  Return TRUE if @a value is a multiple of @a alignment,  FALSE otherwise
138 */
139
140RTEMS_INLINE_ROUTINE boolean _Heap_Is_aligned (
141  uint32_t  value,
142  uint32_t  alignment
143)
144{
145  return (value % alignment) == 0;
146}
147
148/**
149 *  Align @a *value up to the nearest multiple of @a alignment.
150 */
151
152RTEMS_INLINE_ROUTINE void _Heap_Align_up (
153  uint32_t *value,
154  uint32_t  alignment
155)
156{
157  uint32_t v = *value;
158  uint32_t a = alignment;
159  uint32_t r = v % a;
160  *value = r ? v - r + a : v;
161}
162
163/**
164 *  Align @a *value down to the nearest multiple of @a alignment.
165 */
166
167RTEMS_INLINE_ROUTINE void _Heap_Align_down (
168  uint32_t *value,
169  uint32_t  alignment
170)
171{
172  uint32_t v = *value;
173  *value = v - (v % alignment);
174}
175
176/**
177 *  Return TRUE if @a ptr is aligned at @a alignment boundary,
178 *  FALSE otherwise
179 */
180
181RTEMS_INLINE_ROUTINE boolean _Heap_Is_aligned_ptr (
182  void *ptr,
183  uint32_t  alignment
184)
185{
186  return (_H_p2u(ptr) % alignment) == 0;
187}
188
189/**
190 *  Align @a *value up to the nearest multiple of @a alignment.
191 */
192
193RTEMS_INLINE_ROUTINE void _Heap_Align_up_uptr (
194  _H_uptr_t *value,
195  uint32_t  alignment
196)
197{
198  _H_uptr_t v = *value;
199  uint32_t a = alignment;
200  _H_uptr_t r = v % a;
201  *value = r ? v - r + a : v;
202}
203
204/**
205 *  Align @a *value down to the nearest multiple of @a alignment.
206 */
207
208RTEMS_INLINE_ROUTINE void _Heap_Align_down_uptr (
209  _H_uptr_t *value,
210  uint32_t  alignment
211)
212{
213  _H_uptr_t v = *value;
214  *value = v - (v % alignment);
215}
216
217/**
218 *  This function calculates and returns a block's location (address)
219 *  in the heap based upon a base address @a base and an @a offset.
220 */
221
222RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at(
223  void       *base,
224  uint32_t  offset
225)
226{
227  return (Heap_Block *) _Addresses_Add_offset( base, offset );
228}
229
230/**
231 *  This function returns the starting address of the portion of @a the_block
232 *  which the user may access.
233 */
234
235RTEMS_INLINE_ROUTINE void *_Heap_User_area (
236  Heap_Block *the_block
237)
238{
239  return (void *) _Addresses_Add_offset ( the_block, HEAP_BLOCK_USER_OFFSET );
240}
241
242/**
243 *  Fill @a *the_block with the address of the beginning of the block given
244 *  pointer to the user accessible area @a base.
245 */
246
247RTEMS_INLINE_ROUTINE void _Heap_Start_of_block (
248  Heap_Control  *the_heap,
249  void          *base,
250  Heap_Block   **the_block
251)
252{
253  _H_uptr_t addr = _H_p2u(base);
254  /* The address passed could be greater than the block address plus
255   * HEAP_BLOCK_USER_OFFSET as _Heap_Allocate_aligned() may produce such user
256   * pointers. To get rid of this offset we need to align the address down
257   * to the nearest 'page_size' boundary. */
258  _Heap_Align_down_uptr ( &addr, the_heap->page_size );
259  *the_block = (Heap_Block *)(addr - HEAP_BLOCK_USER_OFFSET);
260}
261
262/**
263 *  This function returns TRUE if the previous block of @a the_block
264 *  is in use, and FALSE otherwise.
265 */
266
267RTEMS_INLINE_ROUTINE boolean _Heap_Is_prev_used (
268  Heap_Block *the_block
269)
270{
271  return (the_block->size & HEAP_PREV_USED);
272}
273
274/**
275 *  This function returns the size of @a the_block in bytes.
276 */
277
278RTEMS_INLINE_ROUTINE uint32_t _Heap_Block_size (
279  Heap_Block *the_block
280)
281{
282  return (the_block->size & ~HEAP_PREV_USED);
283}
284
285/**
286 *  This function returns TRUE if @a the_block is within the memory area
287 *  managed by @a the_heap, and FALSE otherwise.
288 */
289
290RTEMS_INLINE_ROUTINE boolean _Heap_Is_block_in (
291  Heap_Control *the_heap,
292  Heap_Block   *the_block
293)
294{
295  return _Addresses_Is_in_range( the_block, the_heap->start, the_heap->final );
296}
297
298/**@}*/
299
300#endif
301/* end of include file */
Note: See TracBrowser for help on using the repository browser.