26 #ifndef HEAP_PROTECTION 27 #define _Heap_Protection_free_delayed_blocks( heap, alloc_begin ) false 29 static bool _Heap_Protection_free_delayed_blocks(
34 bool search_again =
false;
35 uintptr_t
const blocks_to_free_count =
36 (heap->Protection.delayed_free_block_count
37 + heap->Protection.delayed_free_fraction - 1)
38 / heap->Protection.delayed_free_fraction;
40 if ( alloc_begin == 0 && blocks_to_free_count > 0 ) {
41 Heap_Block *block_to_free = heap->Protection.first_delayed_free_block;
44 for ( count = 0; count < blocks_to_free_count; ++count ) {
48 _Heap_Protection_block_error(
56 block_to_free->Protection_begin.next_delayed_free_block;
57 block_to_free->Protection_begin.next_delayed_free_block =
58 HEAP_PROTECTION_OBOLUS;
65 block_to_free = next_block_to_free;
68 heap->Protection.delayed_free_block_count -= blocks_to_free_count;
69 heap->Protection.first_delayed_free_block = block_to_free;
78 #ifdef RTEMS_HEAP_DEBUG 79 static void _Heap_Check_allocation(
82 uintptr_t alloc_begin,
88 uintptr_t
const min_block_size = heap->min_block_size;
89 uintptr_t
const page_size = heap->page_size;
91 uintptr_t
const block_begin = (uintptr_t) block;
93 uintptr_t
const block_end = block_begin + block_size;
95 uintptr_t
const alloc_end = alloc_begin + alloc_size;
98 uintptr_t
const alloc_area_offset = alloc_begin - alloc_area_begin;
100 _HAssert( block_size >= min_block_size );
101 _HAssert( block_begin < block_end );
111 _HAssert( alloc_area_offset < page_size );
114 if ( alignment == 0 ) {
115 _HAssert( alloc_begin == alloc_area_begin );
120 if ( boundary != 0 ) {
123 _HAssert( alloc_size <= boundary );
124 _HAssert( boundary_line <= alloc_begin || alloc_end <= boundary_line );
128 #define _Heap_Check_allocation( h, b, ab, as, ag, bd ) ((void) 0) 131 static uintptr_t _Heap_Check_block(
134 uintptr_t alloc_size,
139 uintptr_t
const page_size = heap->page_size;
140 uintptr_t
const min_block_size = heap->min_block_size;
142 uintptr_t
const block_begin = (uintptr_t) block;
144 uintptr_t
const block_end = block_begin + block_size;
147 uintptr_t
const alloc_begin_ceiling = block_end - min_block_size
151 uintptr_t alloc_begin = alloc_end - alloc_size;
156 if ( alloc_begin > alloc_begin_ceiling ) {
160 alloc_end = alloc_begin + alloc_size;
163 if ( boundary != 0 ) {
164 uintptr_t
const boundary_floor = alloc_begin_floor + alloc_size;
167 while ( alloc_begin < boundary_line && boundary_line < alloc_end ) {
168 if ( boundary_line < boundary_floor ) {
171 alloc_begin = boundary_line - alloc_size;
173 alloc_end = alloc_begin + alloc_size;
179 if ( alloc_begin >= alloc_begin_floor ) {
180 uintptr_t
const alloc_block_begin =
182 uintptr_t
const free_size = alloc_block_begin - block_begin;
184 if ( free_size >= min_block_size || free_size == 0 ) {
194 uintptr_t alloc_size,
202 uintptr_t
const page_size = heap->page_size;
204 uintptr_t alloc_begin = 0;
205 uint32_t search_count = 0;
206 bool search_again =
false;
208 if ( block_size_floor < alloc_size ) {
213 if ( boundary != 0 ) {
214 if ( boundary < alloc_size ) {
218 if ( alignment == 0 ) {
219 alignment = page_size;
227 while ( block != free_list_tail ) {
230 _Heap_Protection_block_check( heap, block );
238 if ( alignment == 0 ) {
241 alloc_begin = _Heap_Check_block(
254 if ( alloc_begin != 0 ) {
261 search_again = _Heap_Protection_free_delayed_blocks( heap, alloc_begin );
262 }
while ( search_again );
264 if ( alloc_begin != 0 ) {
267 _Heap_Check_allocation(
290 return (
void *) alloc_begin;
Run-time heap statistics.
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.
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_first(Heap_Control *heap)
Returns the first block of the free list of the heap.
uintptr_t size_and_flag
Contains the size of the current block and a flag which indicates if the previous block is free or us...
bool _Heap_Free(Heap_Control *heap, void *addr)
Frees the allocated memory 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.
Heap Handler Implementation.
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.
RTEMS_INLINE_ROUTINE Heap_Block * _Heap_Free_list_tail(Heap_Control *heap)
Returns the tail of the free list of the heap.
uint32_t allocs
Total number of successful allocations.
uint64_t lifetime_allocated
Lifetime number of bytes allocated from this heap.
Description for free or used blocks.
RTEMS_INLINE_ROUTINE bool _Heap_Is_prev_used(const Heap_Block *block)
Returns if the previous heap block is used.
uint32_t failed_allocs
Total number of failed allocations.
A supposed to be free block is not inside the heap memory area.
RTEMS_INLINE_ROUTINE bool _Heap_Is_aligned(uintptr_t value, uintptr_t alignment)
Checks if the value is aligned to the given alignment.
Control block used to manage a heap.
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Align_down(uintptr_t value, uintptr_t alignment)
Returns the aligned value, truncating.
Heap_Block * next
Pointer to the next free block or part of the allocated area.
uint32_t max_search
Maximum number of blocks searched ever.
#define HEAP_ALLOC_BONUS
Size of the part at the block begin which may be used for allocation in charge of the previous block...
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...
uint32_t searches
Total number of searches.
#define HEAP_BLOCK_HEADER_SIZE
The block header consists of the two size fields (Heap_Block::prev_size and Heap_Block::size_and_flag...
void * _Heap_Allocate_aligned_with_boundary(Heap_Control *heap, uintptr_t alloc_size, uintptr_t alignment, uintptr_t boundary)
Allocates an aligned memory area with boundary constraint.
RTEMS_INLINE_ROUTINE uintptr_t _Heap_Block_size(const Heap_Block *block)
Returns the block size.