source: rtems/cpukit/score/inline/rtems/score/heap.inl @ 484a769

4.104.114.95
Last change on this file since 484a769 was 484a769, checked in by Ralf Corsepius <ralf.corsepius@…>, on 09/04/08 at 17:46:39

Convert to "bool".

  • Property mode set to 100644
File size: 9.4 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-2006.
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 _RTEMS_SCORE_HEAP_H
20# error "Never use <rtems/score/heap.inl> directly; include <rtems/score/heap.h> instead."
21#endif
22
23#ifndef _RTEMS_SCORE_HEAP_INL
24#define _RTEMS_SCORE_HEAP_INL
25
26/**
27 *  @addtogroup ScoreHeap
28 *  @{
29 */
30
31#include <rtems/score/address.h>
32
33/**
34 *  This function returns the head of the specified heap.
35 *
36 *  @param[in] the_heap points to the heap being operated upon
37 *
38 *  @return This method returns a pointer to the dummy head of the free
39 *          block list.
40 */
41RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Head (
42  Heap_Control *the_heap
43)
44{
45  return &the_heap->free_list;
46}
47
48/**
49 *  This function returns the tail of the specified heap.
50 *
51 *  @param[in] the_heap points to the heap being operated upon
52 *
53 *  @return This method returns a pointer to the dummy tail of the heap
54 *          free list.
55 */
56RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Tail (
57  Heap_Control *the_heap
58)
59{
60  return &the_heap->free_list;
61}
62
63/**
64 *  Return the first free block of the specified heap.
65 *
66 *  @param[in] the_heap points to the heap being operated upon
67 *
68 *  @return This method returns a pointer to the first free block.
69 */
70RTEMS_INLINE_ROUTINE Heap_Block *_Heap_First (
71  Heap_Control *the_heap
72)
73{
74  return _Heap_Head(the_heap)->next;
75}
76
77/**
78 *  Return the last free block of the specified heap.
79 *
80 *  @param[in] the_heap points to the heap being operated upon
81 *
82 *  @return This method returns a pointer to the last block on the free list.
83 */
84RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Last (
85  Heap_Control *the_heap
86)
87{
88  return _Heap_Tail(the_heap)->prev;
89}
90
91/**
92 *  This function removes 'the_block' from doubly-linked list.
93 *
94 *  @param[in] the_block is the block to remove from the heap used block
95 *             list.
96 */
97RTEMS_INLINE_ROUTINE void _Heap_Block_remove (
98  Heap_Block *the_block
99)
100{
101  Heap_Block *block = the_block;
102
103  Heap_Block *next = block->next;
104  Heap_Block *prev = block->prev;
105  prev->next = next;
106  next->prev = prev;
107}
108
109/**
110 *  This function replaces @a old_block by @a new_block in doubly-linked list.
111 *  When a block is allocated, the memory is allocated from the low memory
112 *  address range of the block.  This means that the upper address range of
113 *  the memory block must be added to the free block list in place of the
114 *  lower address portion being allocated.  This method is also used as part
115 *  of resizing a block.
116 *
117 *  @param[in] old_block is the block which is currently on the list.
118 *  @param[in] new_block is the new block which will replace it on the list.
119 */
120
121RTEMS_INLINE_ROUTINE void _Heap_Block_replace (
122  Heap_Block *old_block,
123  Heap_Block *new_block
124)
125{
126  Heap_Block *block = old_block;
127  Heap_Block *next = block->next;
128  Heap_Block *prev = block->prev;
129
130  block = new_block;
131  block->next = next;
132  block->prev = prev;
133  next->prev = prev->next = block;
134}
135
136/**
137 *  This function inserts @a the_block after @a prev_block
138 *  in the doubly-linked free block list.
139 *
140 *  @param[in] prev_block is the previous block in the free list.
141 *  @param[in] the_block is the block being freed.
142 */
143RTEMS_INLINE_ROUTINE void _Heap_Block_insert_after (
144  Heap_Block *prev_block,
145  Heap_Block *the_block
146)
147{
148  Heap_Block *prev = prev_block;
149  Heap_Block *block = the_block;
150
151  Heap_Block *next = prev->next;
152  block->next  = next;
153  block->prev  = prev;
154  next->prev = prev->next = block;
155}
156
157/**
158 *  Return TRUE if @a value is a multiple of @a alignment,  FALSE otherwise
159 *
160 *  @param[in] value is the address to verify alignment of.
161 *  @param[in] alignment is the alignment factor to verify.
162 *
163 *  @return This method returns TRUE if the address is aligned and false
164 *          otherwise.
165 */
166RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned (
167  uint32_t  value,
168  uint32_t  alignment
169)
170{
171  return (value % alignment) == 0;
172}
173
174/**
175 *  Align @a *value up to the nearest multiple of @a alignment.
176 *
177 *  @param[in] value is a pointer to be aligned.
178 *  @param[in] alignment is the alignment value.
179 *
180 *  @return Upon return, @a value will contain the aligned result.
181 */
182RTEMS_INLINE_ROUTINE void _Heap_Align_up (
183  uint32_t *value,
184  uint32_t  alignment
185)
186{
187  uint32_t v = *value;
188  uint32_t a = alignment;
189  uint32_t r = v % a;
190  *value = r ? v - r + a : v;
191}
192
193/**
194 *  Align @a *value down to the nearest multiple of @a alignment.
195 *
196 *  @param[in] value is a pointer to be aligned.
197 *  @param[in] alignment is the alignment value.
198 *
199 *  @return Upon return, @a value will contain the aligned result.
200 */
201RTEMS_INLINE_ROUTINE void _Heap_Align_down (
202  uint32_t *value,
203  uint32_t  alignment
204)
205{
206  uint32_t v = *value;
207  *value = v - (v % alignment);
208}
209
210/**
211 *  Return TRUE if @a ptr is aligned at @a alignment boundary,
212 *  FALSE otherwise.
213 *
214 *  @param[in] ptr is the pointer to verify alignment of.
215 *  @param[in] alignment is the alignment factor.
216 *
217 *  @return This method returns TRUE if @a ptr is aligned at @a alignment
218 *          boundary, and FALSE otherwise.
219 */
220RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned_ptr (
221  void      *ptr,
222  uint32_t  alignment
223)
224{
225  return (_H_p2u(ptr) % alignment) == 0;
226}
227
228/**
229 *  Align @a *value up to the nearest multiple of @a alignment.
230 *
231 *  @param[in] value is a pointer to be aligned.
232 *  @param[in] alignment is the alignment value.
233 *
234 *  @return Upon return, @a value will contain the aligned result.
235 */
236RTEMS_INLINE_ROUTINE void _Heap_Align_up_uptr (
237  _H_uptr_t *value,
238  uint32_t  alignment
239)
240{
241  _H_uptr_t v = *value;
242  uint32_t a = alignment;
243  _H_uptr_t r = v % a;
244  *value = r ? v - r + a : v;
245}
246
247/**
248 *  Align @a *value down to the nearest multiple of @a alignment.
249 *
250 *  @param[in] value is a pointer to be aligned.
251 *  @param[in] alignment is the alignment value.
252 *
253 *  @return Upon return, @a value will contain the aligned result.
254 */
255RTEMS_INLINE_ROUTINE void _Heap_Align_down_uptr (
256  _H_uptr_t *value,
257  uint32_t  alignment
258)
259{
260  _H_uptr_t v = *value;
261  *value = v - (v % alignment);
262}
263
264/**
265 *  This function calculates and returns a block's location (address)
266 *  in the heap based upon a base address @a base and an @a offset.
267 *
268 *  @param[in] base is the base address of the memory area.
269 *  @param[in] offset is the byte offset into @a base.
270 *
271 *  @return This method returns a pointer to the block's address.
272 */
273RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at(
274  void     *base,
275  uint32_t  offset
276)
277{
278  return (Heap_Block *) _Addresses_Add_offset( base, offset );
279}
280
281/**
282 *  This function returns the starting address of the portion of @a the_block
283 *  which the user may access.
284 *
285 *  @param[in] the_block is the heap block to find the user area of.
286 *
287 *  @return This method returns a pointer to the start of the user area in
288 *          the block.
289 */
290RTEMS_INLINE_ROUTINE void *_Heap_User_area (
291  Heap_Block *the_block
292)
293{
294  return (void *) _Addresses_Add_offset ( the_block, HEAP_BLOCK_USER_OFFSET );
295}
296
297/**
298 *  Fill @a *the_block with the address of the beginning of the block given
299 *  pointer to the user accessible area @a base.
300 *
301 *  @param[in] the_heap points to the heap being operated upon
302 *  @param[in] base points to the user area in the block.
303 *  @param[in] the_block will be the address of the heap block.
304 *
305 *  @return This method returns a pointer to the heap block based upon the
306 *               given heap and user pointer.
307 */
308RTEMS_INLINE_ROUTINE void _Heap_Start_of_block (
309  Heap_Control  *the_heap,
310  void          *base,
311  Heap_Block   **the_block
312)
313{
314  _H_uptr_t addr = _H_p2u(base);
315  /* The address passed could be greater than the block address plus
316   * HEAP_BLOCK_USER_OFFSET as _Heap_Allocate_aligned() may produce such user
317   * pointers. To get rid of this offset we need to align the address down
318   * to the nearest 'page_size' boundary. */
319  _Heap_Align_down_uptr ( &addr, the_heap->page_size );
320  *the_block = (Heap_Block *)(addr - HEAP_BLOCK_USER_OFFSET);
321}
322
323/**
324 *  This function returns TRUE if the previous block of @a the_block
325 *  is in use, and FALSE otherwise.
326 *
327 *  @param[in] the_block is the block to operate upon.
328 *
329 *  @return This method returns TRUE if the previous block is used and FALSE
330 *          if the previous block is free.
331 */
332RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used (
333  Heap_Block *the_block
334)
335{
336  return (the_block->size & HEAP_PREV_USED);
337}
338
339/**
340 *  This function returns the size of @a the_block in bytes.
341 *
342 *  @param[in] the_block is the block to operate upon.
343 *
344 *  @return This method returns the size of the specified heap block in bytes.
345 */
346RTEMS_INLINE_ROUTINE uint32_t _Heap_Block_size (
347  Heap_Block *the_block
348)
349{
350  return (the_block->size & ~HEAP_PREV_USED);
351}
352
353/**
354 *  This function returns TRUE if @a the_block is within the memory area
355 *  managed by @a the_heap, and FALSE otherwise.
356 *
357 *  @param[in] the_heap points to the heap being operated upon
358 *  @param[in] the_block is the block address to check.
359 *
360 *  @return This method returns TRUE if @a the_block appears to have been
361 *          allocated from @a the_heap, and FALSE otherwise.
362 */
363RTEMS_INLINE_ROUTINE bool _Heap_Is_block_in (
364  Heap_Control *the_heap,
365  Heap_Block   *the_block
366)
367{
368  return _Addresses_Is_in_range( the_block, the_heap->start, the_heap->final );
369}
370
371/**@}*/
372
373#endif
374/* end of include file */
Note: See TracBrowser for help on using the repository browser.