RTEMS: cpukit/include/rtems/score/heapimpl.h Source File

| RTEMS 5.4-rc2

Loading...
Searching...
No Matches
heapimpl.h
Go to the documentation of this file.
1
9/*
10 * COPYRIGHT (c) 1989-2008.
11 * On-Line Applications Research Corporation (OAR).
12 *
13 * The license and distribution terms for this file may be
14 * found in the file LICENSE in this distribution or at
15 * http://www.rtems.org/license/LICENSE.
16 */
17
18#ifndef _RTEMS_SCORE_HEAPIMPL_H
19#define _RTEMS_SCORE_HEAPIMPL_H
20
21#include <rtems/score/heap.h>
22
23#ifdef __cplusplus
24extern "C" {
25#endif
26
36#define HEAP_PREV_BLOCK_USED ((uintptr_t) 1)
37
42#define HEAP_ALLOC_BONUS sizeof(uintptr_t)
43
47 typedef enum {
48 HEAP_RESIZE_SUCCESSFUL,
49 HEAP_RESIZE_UNSATISFIED,
50 HEAP_RESIZE_FATAL_ERROR
51} Heap_Resize_status;
52
68bool _Heap_Get_first_and_last_block(
69 uintptr_t heap_area_begin,
70 uintptr_t heap_area_size,
71 uintptr_t page_size,
72 uintptr_t min_block_size,
73 Heap_Block **first_block_ptr,
74 Heap_Block **last_block_ptr
75);
76
94uintptr_t _Heap_Initialize(
95 Heap_Control *heap,
96 void *area_begin,
97 uintptr_t area_size,
98 uintptr_t page_size
99);
100
119void *_Heap_Allocate_aligned_with_boundary(
120 Heap_Control *heap,
121 uintptr_t size,
122 uintptr_t alignment,
123 uintptr_t boundary
124);
125
139 RTEMS_INLINE_ROUTINE void *_Heap_Allocate_aligned(
140 Heap_Control *heap,
141 uintptr_t size,
142 uintptr_t alignment
143)
144{
145 return _Heap_Allocate_aligned_with_boundary( heap, size, alignment, 0 );
146}
147
160 RTEMS_INLINE_ROUTINE void *_Heap_Allocate( Heap_Control *heap, uintptr_t size )
161{
162 return _Heap_Allocate_aligned_with_boundary( heap, size, 0, 0 );
163}
164
176bool _Heap_Free( Heap_Control *heap, void *addr );
177
190bool _Heap_Walk(
191 Heap_Control *heap,
192 int source,
193 bool dump
194);
195
204 typedef bool (*Heap_Block_visitor)(
205 const Heap_Block *block,
206 uintptr_t block_size,
207 bool block_is_used,
208 void *visitor_arg
209);
210
219void _Heap_Iterate(
220 Heap_Control *heap,
221 Heap_Block_visitor visitor,
222 void *visitor_arg
223);
224
241 Heap_Block *_Heap_Greedy_allocate(
242 Heap_Control *heap,
243 const uintptr_t *block_sizes,
244 size_t block_count
245);
246
261 Heap_Block *_Heap_Greedy_allocate_all_except_largest(
262 Heap_Control *heap,
263 uintptr_t *allocatable_size
264);
265
272void _Heap_Greedy_free(
273 Heap_Control *heap,
274 Heap_Block *blocks
275);
276
283void _Heap_Get_information(
284 Heap_Control *heap,
285 Heap_Information_block *info
286);
287
295void _Heap_Get_free_information(
296 Heap_Control *heap,
297 Heap_Information *info
298);
299
316bool _Heap_Size_of_alloc_area(
317 Heap_Control *heap,
318 void *addr,
319 uintptr_t *size
320);
321
343 Heap_Resize_status _Heap_Resize_block(
344 Heap_Control *heap,
345 void *addr,
346 uintptr_t size,
347 uintptr_t *old_size,
348 uintptr_t *new_size
349);
350
372 Heap_Block *_Heap_Block_allocate(
373 Heap_Control *heap,
374 Heap_Block *block,
375 uintptr_t alloc_begin,
376 uintptr_t alloc_size
377);
378
379#ifndef HEAP_PROTECTION
380 #define _Heap_Protection_block_initialize( heap, block ) ((void) 0)
381 #define _Heap_Protection_block_check( heap, block ) ((void) 0)
382 #define _Heap_Protection_block_error( heap, block, reason ) ((void) 0)
383 #define _Heap_Protection_free_all_delayed_blocks( heap ) ((void) 0)
384#else
385 static inline void _Heap_Protection_block_initialize(
386 Heap_Control *heap,
387 Heap_Block *block
388 )
389 {
390 (*heap->Protection.block_initialize)( heap, block );
391 }
392
393 static inline void _Heap_Protection_block_check(
394 Heap_Control *heap,
395 Heap_Block *block
396 )
397 {
398 (*heap->Protection.block_check)( heap, block );
399 }
400
401 static inline void _Heap_Protection_block_error(
402 Heap_Control *heap,
403 Heap_Block *block,
404 Heap_Error_reason reason
405 )
406 {
407 (*heap->Protection.block_error)( heap, block, reason );
408 }
409
410 void _Heap_Protection_free_all_delayed_blocks( Heap_Control *heap );
411#endif
412
423 RTEMS_INLINE_ROUTINE void _Heap_Protection_set_delayed_free_fraction(
424 Heap_Control *heap,
425 uintptr_t fraction
426)
427{
428#ifdef HEAP_PROTECTION
429 heap->Protection.delayed_free_fraction = fraction;
430#else
431 (void) heap;
432 (void) fraction;
433#endif
434}
435
443 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_head( Heap_Control *heap )
444{
445 return &heap->free_list;
446}
447
455 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_tail( Heap_Control *heap )
456{
457 return &heap->free_list;
458}
459
467 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_first( Heap_Control *heap )
468{
469 return _Heap_Free_list_head(heap)->next;
470}
471
479 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Free_list_last( Heap_Control *heap )
480{
481 return _Heap_Free_list_tail(heap)->prev;
482}
483
489 RTEMS_INLINE_ROUTINE void _Heap_Free_list_remove( Heap_Block *block )
490{
491 Heap_Block *next = block->next;
492 Heap_Block *prev = block->prev;
493
494 prev->next = next;
495 next->prev = prev;
496}
497
504 RTEMS_INLINE_ROUTINE void _Heap_Free_list_replace(
505 Heap_Block *old_block,
506 Heap_Block *new_block
507)
508{
509 Heap_Block *next = old_block->next;
510 Heap_Block *prev = old_block->prev;
511
512 new_block->next = next;
513 new_block->prev = prev;
514
515 next->prev = new_block;
516 prev->next = new_block;
517}
518
525 RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_after(
526 Heap_Block *block_before,
527 Heap_Block *new_block
528)
529{
530 Heap_Block *next = block_before->next;
531
532 new_block->next = next;
533 new_block->prev = block_before;
534 block_before->next = new_block;
535 next->prev = new_block;
536}
537
544 RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_before(
545 Heap_Block *block_next,
546 Heap_Block *new_block
547)
548{
549 Heap_Block *prev = block_next->prev;
550
551 new_block->next = block_next;
552 new_block->prev = prev;
553 prev->next = new_block;
554 block_next->prev = new_block;
555}
556
566 RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned(
567 uintptr_t value,
568 uintptr_t alignment
569)
570{
571 return (value % alignment) == 0;
572}
573
582 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down(
583 uintptr_t value,
584 uintptr_t alignment
585)
586{
587 return value - (value % alignment);
588}
589
598 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_at(
599 const Heap_Block *block,
600 uintptr_t offset
601)
602{
603 return (Heap_Block *) ((uintptr_t) block + offset);
604}
605
613 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Prev_block(
614 const Heap_Block *block
615)
616{
617 return (Heap_Block *) ((uintptr_t) block - block->prev_size);
618}
619
627 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Alloc_area_of_block(
628 const Heap_Block *block
629)
630{
631 return (uintptr_t) block + HEAP_BLOCK_HEADER_SIZE;
632}
633
642 RTEMS_INLINE_ROUTINE Heap_Block *_Heap_Block_of_alloc_area(
643 uintptr_t alloc_begin,
644 uintptr_t page_size
645)
646{
647 return (Heap_Block *) (_Heap_Align_down( alloc_begin, page_size )
648 - HEAP_BLOCK_HEADER_SIZE);
649}
650
658 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Block_size( const Heap_Block *block )
659{
660 return block->size_and_flag & ~HEAP_PREV_BLOCK_USED;
661}
662
669 RTEMS_INLINE_ROUTINE void _Heap_Block_set_size(
670 Heap_Block *block,
671 uintptr_t size
672)
673{
674 uintptr_t flag = block->size_and_flag & HEAP_PREV_BLOCK_USED;
675
676 block->size_and_flag = size | flag;
677}
678
688 RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used( const Heap_Block *block )
689{
690 return block->size_and_flag & HEAP_PREV_BLOCK_USED;
691}
692
701 RTEMS_INLINE_ROUTINE bool _Heap_Is_used(
702 const Heap_Block *block
703)
704{
705 const Heap_Block *const next_block =
706 _Heap_Block_at( block, _Heap_Block_size( block ) );
707
708 return _Heap_Is_prev_used( next_block );
709}
710
719 RTEMS_INLINE_ROUTINE bool _Heap_Is_free(
720 const Heap_Block *block
721)
722{
723 return !_Heap_Is_used( block );
724}
725
735 RTEMS_INLINE_ROUTINE bool _Heap_Is_block_in_heap(
736 const Heap_Control *heap,
737 const Heap_Block *block
738)
739{
740 return (uintptr_t) block >= (uintptr_t) heap->first_block
741 && (uintptr_t) block <= (uintptr_t) heap->last_block;
742}
743
757 RTEMS_INLINE_ROUTINE void _Heap_Set_last_block_size( Heap_Control *heap )
758{
759 _Heap_Block_set_size(
760 heap->last_block,
761 (uintptr_t) heap->first_block - (uintptr_t) heap->last_block
762 );
763}
764
774 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Get_size( const Heap_Control *heap )
775{
776 return heap->stats.size;
777}
778
788 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Max( uintptr_t a, uintptr_t b )
789{
790 return a > b ? a : b;
791}
792
802 RTEMS_INLINE_ROUTINE uintptr_t _Heap_Min( uintptr_t a, uintptr_t b )
803{
804 return a < b ? a : b;
805}
806
807#ifdef RTEMS_DEBUG
808 #define RTEMS_HEAP_DEBUG
809#endif
810
811#ifdef RTEMS_HEAP_DEBUG
812 #include <assert.h>
813 #define _HAssert( cond ) \
814 do { \
815 if ( !(cond) ) { \
816 __assert( __FILE__, __LINE__, #cond ); \
817 } \
818 } while (0)
819#else
820 #define _HAssert( cond ) ((void) 0)
821#endif
822
825#ifdef __cplusplus
826}
827#endif
828
829#endif
830/* end of include file */
assert.h
Information for the Assert Handler.
RTEMS_INLINE_ROUTINE
#define RTEMS_INLINE_ROUTINE
Definition: basedefs.h:66
_Heap_Greedy_free
void _Heap_Greedy_free(Heap_Control *heap, Heap_Block *blocks)
Frees blocks of a greedy allocation.
Definition: heapgreedy.c:96
_Heap_Min
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Min(uintptr_t a, uintptr_t b)
Returns the smaller one of the two arguments.
Definition: heapimpl.h:802
_Heap_Block_size
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Block_size(const Heap_Block *block)
Returns the block size.
Definition: heapimpl.h:658
_Heap_Alloc_area_of_block
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Alloc_area_of_block(const Heap_Block *block)
Returns the first address in the block without the heap header.
Definition: heapimpl.h:627
_Heap_Align_down
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down(uintptr_t value, uintptr_t alignment)
Returns the aligned value, truncating.
Definition: heapimpl.h:582
_Heap_Greedy_allocate_all_except_largest
Heap_Block * _Heap_Greedy_allocate_all_except_largest(Heap_Control *heap, uintptr_t *allocatable_size)
Greedily allocates all blocks except the largest free block.
Definition: heapgreedy.c:78
_Heap_Block_allocate
Heap_Block * _Heap_Block_allocate(Heap_Control *heap, Heap_Block *block, uintptr_t alloc_begin, uintptr_t alloc_size)
Allocates the memory area. starting at alloc_begin of size alloc_size bytes in the block block.
Definition: heap.c:431
_Heap_Free_list_head
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_head(Heap_Control *heap)
Returns the head of the free list of the heap.
Definition: heapimpl.h:443
_Heap_Get_first_and_last_block
bool _Heap_Get_first_and_last_block(uintptr_t heap_area_begin, uintptr_t heap_area_size, uintptr_t page_size, uintptr_t min_block_size, Heap_Block **first_block_ptr, Heap_Block **last_block_ptr)
Gets the first and last block for the heap area.
Definition: heap.c:170
_Heap_Max
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Max(uintptr_t a, uintptr_t b)
Returns the bigger one of the two arguments.
Definition: heapimpl.h:788
HEAP_BLOCK_HEADER_SIZE
#define HEAP_BLOCK_HEADER_SIZE
The block header consists of the two size fields (Heap_Block::prev_size and Heap_Block::size_and_flag...
Definition: heap.h:250
_Heap_Allocate_aligned_with_boundary
void * _Heap_Allocate_aligned_with_boundary(Heap_Control *heap, uintptr_t size, uintptr_t alignment, uintptr_t boundary)
Allocates an aligned memory area with boundary constraint.
Definition: heapallocate.c:201
_Heap_Get_size
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Get_size(const Heap_Control *heap)
Returns the size of the allocatable area in bytes.
Definition: heapimpl.h:774
_Heap_Iterate
void _Heap_Iterate(Heap_Control *heap, Heap_Block_visitor visitor, void *visitor_arg)
Iterates over all blocks of the heap.
Definition: heapiterate.c:29
_Heap_Free_list_insert_before
RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_before(Heap_Block *block_next, Heap_Block *new_block)
Inserts a block before an existing block in the free list.
Definition: heapimpl.h:544
_Heap_Get_information
void _Heap_Get_information(Heap_Control *heap, Heap_Information_block *info)
Returns information about used and free blocks for the heap.
Definition: heapgetinfo.c:45
_Heap_Free_list_tail
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_tail(Heap_Control *heap)
Returns the tail of the free list of the heap.
Definition: heapimpl.h:455
_Heap_Is_aligned
RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned(uintptr_t value, uintptr_t alignment)
Checks if the value is aligned to the given alignment.
Definition: heapimpl.h:566
_Heap_Prev_block
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Prev_block(const Heap_Block *block)
Returns the address of the previous block.
Definition: heapimpl.h:613
_Heap_Is_used
RTEMS_INLINE_ROUTINE bool _Heap_Is_used(const Heap_Block *block)
Returns if the heap block is used.
Definition: heapimpl.h:701
_Heap_Free_list_remove
RTEMS_INLINE_ROUTINE void _Heap_Free_list_remove(Heap_Block *block)
Removes the block from the free list.
Definition: heapimpl.h:489
_Heap_Free_list_insert_after
RTEMS_INLINE_ROUTINE void _Heap_Free_list_insert_after(Heap_Block *block_before, Heap_Block *new_block)
Inserts a block after an existing block in the free list.
Definition: heapimpl.h:525
_Heap_Block_at
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Block_at(const Heap_Block *block, uintptr_t offset)
Returns the block which is offset away from block.
Definition: heapimpl.h:598
_Heap_Resize_block
Heap_Resize_status _Heap_Resize_block(Heap_Control *heap, void *addr, uintptr_t size, uintptr_t *old_size, uintptr_t *new_size)
Resizes the block of the allocated memory area.
Definition: heapresizeblock.c:86
_Heap_Size_of_alloc_area
bool _Heap_Size_of_alloc_area(Heap_Control *heap, void *addr, uintptr_t *size)
Returns the size of the allocatable memory area.
Definition: heapsizeofuserarea.c:24
_Heap_Walk
bool _Heap_Walk(Heap_Control *heap, int source, bool dump)
Verifies the integrity of the heap.
Definition: heapwalk.c:312
_Heap_Greedy_allocate
Heap_Block * _Heap_Greedy_allocate(Heap_Control *heap, const uintptr_t *block_sizes, size_t block_count)
Greedily allocates and empties the heap.
Definition: heapgreedy.c:29
Heap_Error_reason
Heap_Error_reason
The heap error reason.
Definition: heap.h:142
_Heap_Free_list_last
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_last(Heap_Control *heap)
Returns the last block of the free list of the heap.
Definition: heapimpl.h:479
_Heap_Allocate
RTEMS_INLINE_ROUTINE void * _Heap_Allocate(Heap_Control *heap, uintptr_t size)
Allocates a memory area.
Definition: heapimpl.h:160
Heap_Block_visitor
bool(* Heap_Block_visitor)(const Heap_Block *block, uintptr_t block_size, bool block_is_used, void *visitor_arg)
Heap block visitor.
Definition: heapimpl.h:204
_Heap_Free
bool _Heap_Free(Heap_Control *heap, void *addr)
Frees the allocated memory area.
Definition: heapfree.c:99
_Heap_Is_block_in_heap
RTEMS_INLINE_ROUTINE bool _Heap_Is_block_in_heap(const Heap_Control *heap, const Heap_Block *block)
Returns if the block is part of the heap.
Definition: heapimpl.h:735
_Heap_Free_list_first
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_first(Heap_Control *heap)
Returns the first block of the free list of the heap.
Definition: heapimpl.h:467
Heap_Resize_status
Heap_Resize_status
See _Heap_Resize_block().
Definition: heapimpl.h:47
_Heap_Initialize
uintptr_t _Heap_Initialize(Heap_Control *heap, void *area_begin, uintptr_t area_size, uintptr_t page_size)
Initializes the heap control block.
Definition: heap.c:207
_Heap_Allocate_aligned
RTEMS_INLINE_ROUTINE void * _Heap_Allocate_aligned(Heap_Control *heap, uintptr_t size, uintptr_t alignment)
Allocates an aligned memory area.
Definition: heapimpl.h:139
_Heap_Block_of_alloc_area
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Block_of_alloc_area(uintptr_t alloc_begin, uintptr_t page_size)
Returns the starting address of the block corresponding to the allocatable area.
Definition: heapimpl.h:642
_Heap_Protection_set_delayed_free_fraction
RTEMS_INLINE_ROUTINE void _Heap_Protection_set_delayed_free_fraction(Heap_Control *heap, uintptr_t fraction)
Sets the fraction of delayed free blocks that is actually freed during memory shortage.
Definition: heapimpl.h:423
HEAP_PREV_BLOCK_USED
#define HEAP_PREV_BLOCK_USED
See also Heap_Block::size_and_flag.
Definition: heapimpl.h:36
_Heap_Is_prev_used
RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used(const Heap_Block *block)
Returns if the previous heap block is used.
Definition: heapimpl.h:688
_Heap_Free_list_replace
RTEMS_INLINE_ROUTINE void _Heap_Free_list_replace(Heap_Block *old_block, Heap_Block *new_block)
Replaces one block in the free list by another.
Definition: heapimpl.h:504
_Heap_Is_free
RTEMS_INLINE_ROUTINE bool _Heap_Is_free(const Heap_Block *block)
Returns if the heap block is free.
Definition: heapimpl.h:719
_Heap_Block_set_size
RTEMS_INLINE_ROUTINE void _Heap_Block_set_size(Heap_Block *block, uintptr_t size)
Sets the block size.
Definition: heapimpl.h:669
_Heap_Get_free_information
void _Heap_Get_free_information(Heap_Control *heap, Heap_Information *info)
Returns information about free blocks for the heap.
Definition: heapgetfreeinfo.c:24
_Heap_Set_last_block_size
RTEMS_INLINE_ROUTINE void _Heap_Set_last_block_size(Heap_Control *heap)
Sets the size of the last block for the heap.
Definition: heapimpl.h:757
heap.h
Heap Handler API.
Heap_Block
Description for free or used blocks.
Definition: heap.h:256
Heap_Block::prev
Heap_Block * prev
Pointer to the previous free block or part of the allocated area.
Definition: heap.h:312
Heap_Block::next
Heap_Block * next
Pointer to the next free block or part of the allocated area.
Definition: heap.h:304
Heap_Control
Control block used to manage a heap.
Definition: heap.h:318
Heap_Information_block
Information block returned by _Heap_Get_information().
Definition: heapinfo.h:145
Heap_Information
Information about blocks.
Definition: heapinfo.h:125
Heap_Statistics::size
uintptr_t size
Size of the allocatable area in bytes.
Definition: heapinfo.h:60