RTEMS 6.1-rc1
heapimpl.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
12/*
13 * COPYRIGHT (c) 1989-2008.
14 * On-Line Applications Research Corporation (OAR).
15 *
16 * Redistribution and use in source and binary forms, with or without
17 * modification, are permitted provided that the following conditions
18 * are met:
19 * 1. Redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer.
21 * 2. Redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
26 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
29 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35 * POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#ifndef _RTEMS_SCORE_HEAPIMPL_H
39#define _RTEMS_SCORE_HEAPIMPL_H
40
41#include <rtems/score/heap.h>
42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
56#define HEAP_PREV_BLOCK_USED ((uintptr_t) 1)
57
62#define HEAP_ALLOC_BONUS sizeof(uintptr_t)
63
67typedef enum {
68 HEAP_RESIZE_SUCCESSFUL,
69 HEAP_RESIZE_UNSATISFIED,
70 HEAP_RESIZE_FATAL_ERROR
72
89 uintptr_t heap_area_begin,
90 uintptr_t heap_area_size,
91 uintptr_t page_size,
92 uintptr_t min_block_size,
93 Heap_Block **first_block_ptr,
94 Heap_Block **last_block_ptr
95);
96
114uintptr_t _Heap_Initialize(
115 Heap_Control *heap,
116 void *area_begin,
117 uintptr_t area_size,
118 uintptr_t page_size
119);
120
140 Heap_Control *heap,
141 uintptr_t size,
142 uintptr_t alignment,
143 uintptr_t boundary
144);
145
159static inline void *_Heap_Allocate_aligned(
160 Heap_Control *heap,
161 uintptr_t size,
162 uintptr_t alignment
163)
164{
165 return _Heap_Allocate_aligned_with_boundary( heap, size, alignment, 0 );
166}
167
180static inline void *_Heap_Allocate( Heap_Control *heap, uintptr_t size )
181{
182 return _Heap_Allocate_aligned_with_boundary( heap, size, 0, 0 );
183}
184
196bool _Heap_Free( Heap_Control *heap, void *addr );
197
210bool _Heap_Walk(
211 Heap_Control *heap,
212 int source,
213 bool dump
214);
215
224typedef bool (*Heap_Block_visitor)(
225 const Heap_Block *block,
226 uintptr_t block_size,
227 bool block_is_used,
228 void *visitor_arg
229);
230
239void _Heap_Iterate(
240 Heap_Control *heap,
241 Heap_Block_visitor visitor,
242 void *visitor_arg
243);
244
262 Heap_Control *heap,
263 const uintptr_t *block_sizes,
264 size_t block_count
265);
266
282 Heap_Control *heap,
283 uintptr_t *allocatable_size
284);
285
293 Heap_Control *heap,
294 Heap_Block *blocks
295);
296
304 Heap_Control *heap,
306);
307
316 Heap_Control *heap,
317 Heap_Information *info
318);
319
337 Heap_Control *heap,
338 void *addr,
339 uintptr_t *size
340);
341
364 Heap_Control *heap,
365 void *addr,
366 uintptr_t size,
367 uintptr_t *old_size,
368 uintptr_t *new_size
369);
370
393 Heap_Control *heap,
394 Heap_Block *block,
395 uintptr_t alloc_begin,
396 uintptr_t alloc_size
397);
398
399#ifndef HEAP_PROTECTION
400 #define _Heap_Protection_block_initialize( heap, block ) ((void) 0)
401 #define _Heap_Protection_block_check( heap, block ) ((void) 0)
402 #define _Heap_Protection_block_error( heap, block, reason ) ((void) 0)
403 #define _Heap_Protection_free_all_delayed_blocks( heap ) ((void) 0)
404#else
405 static inline void _Heap_Protection_block_initialize(
406 Heap_Control *heap,
407 Heap_Block *block
408 )
409 {
410 (*heap->Protection.block_initialize)( heap, block );
411 }
412
413 static inline void _Heap_Protection_block_check(
414 Heap_Control *heap,
415 Heap_Block *block
416 )
417 {
418 (*heap->Protection.block_check)( heap, block );
419 }
420
421 static inline void _Heap_Protection_block_error(
422 Heap_Control *heap,
423 Heap_Block *block,
424 Heap_Error_reason reason
425 )
426 {
427 (*heap->Protection.block_error)( heap, block, reason );
428 }
429
430 void _Heap_Protection_free_all_delayed_blocks( Heap_Control *heap );
431#endif
432
443static inline void _Heap_Protection_set_delayed_free_fraction(
444 Heap_Control *heap,
445 uintptr_t fraction
446)
447{
448#ifdef HEAP_PROTECTION
449 heap->Protection.delayed_free_fraction = fraction;
450#else
451 (void) heap;
452 (void) fraction;
453#endif
454}
455
463static inline Heap_Block *_Heap_Free_list_head( Heap_Control *heap )
464{
465 return &heap->free_list;
466}
467
475static inline Heap_Block *_Heap_Free_list_tail( Heap_Control *heap )
476{
477 return &heap->free_list;
478}
479
487static inline Heap_Block *_Heap_Free_list_first( Heap_Control *heap )
488{
489 return _Heap_Free_list_head(heap)->next;
490}
491
499static inline Heap_Block *_Heap_Free_list_last( Heap_Control *heap )
500{
501 return _Heap_Free_list_tail(heap)->prev;
502}
503
509static inline void _Heap_Free_list_remove( Heap_Block *block )
510{
511 Heap_Block *next = block->next;
512 Heap_Block *prev = block->prev;
513
514 prev->next = next;
515 next->prev = prev;
516}
517
524static inline void _Heap_Free_list_replace(
525 Heap_Block *old_block,
526 Heap_Block *new_block
527)
528{
529 Heap_Block *next = old_block->next;
530 Heap_Block *prev = old_block->prev;
531
532 new_block->next = next;
533 new_block->prev = prev;
534
535 next->prev = new_block;
536 prev->next = new_block;
537}
538
545static inline void _Heap_Free_list_insert_after(
546 Heap_Block *block_before,
547 Heap_Block *new_block
548)
549{
550 Heap_Block *next = block_before->next;
551
552 new_block->next = next;
553 new_block->prev = block_before;
554 block_before->next = new_block;
555 next->prev = new_block;
556}
557
564static inline void _Heap_Free_list_insert_before(
565 Heap_Block *block_next,
566 Heap_Block *new_block
567)
568{
569 Heap_Block *prev = block_next->prev;
570
571 new_block->next = block_next;
572 new_block->prev = prev;
573 prev->next = new_block;
574 block_next->prev = new_block;
575}
576
586static inline bool _Heap_Is_aligned(
587 uintptr_t value,
588 uintptr_t alignment
589)
590{
591 return (value % alignment) == 0;
592}
593
602static inline uintptr_t _Heap_Align_down(
603 uintptr_t value,
604 uintptr_t alignment
605)
606{
607 return value - (value % alignment);
608}
609
618static inline Heap_Block *_Heap_Block_at(
619 const Heap_Block *block,
620 uintptr_t offset
621)
622{
623 return (Heap_Block *) ((uintptr_t) block + offset);
624}
625
633static inline Heap_Block *_Heap_Prev_block(
634 const Heap_Block *block
635)
636{
637 return (Heap_Block *) ((uintptr_t) block - block->prev_size);
638}
639
647static inline uintptr_t _Heap_Alloc_area_of_block(
648 const Heap_Block *block
649)
650{
651 return (uintptr_t) block + HEAP_BLOCK_HEADER_SIZE;
652}
653
662static inline Heap_Block *_Heap_Block_of_alloc_area(
663 uintptr_t alloc_begin,
664 uintptr_t page_size
665)
666{
667 return (Heap_Block *) (_Heap_Align_down( alloc_begin, page_size )
669}
670
678static inline uintptr_t _Heap_Block_size( const Heap_Block *block )
679{
680 return block->size_and_flag & ~HEAP_PREV_BLOCK_USED;
681}
682
689static inline void _Heap_Block_set_size(
690 Heap_Block *block,
691 uintptr_t size
692)
693{
694 uintptr_t flag = block->size_and_flag & HEAP_PREV_BLOCK_USED;
695
696 block->size_and_flag = size | flag;
697}
698
708static inline bool _Heap_Is_prev_used( const Heap_Block *block )
709{
710 return block->size_and_flag & HEAP_PREV_BLOCK_USED;
711}
712
721static inline bool _Heap_Is_used(
722 const Heap_Block *block
723)
724{
725 const Heap_Block *const next_block =
726 _Heap_Block_at( block, _Heap_Block_size( block ) );
727
728 return _Heap_Is_prev_used( next_block );
729}
730
739static inline bool _Heap_Is_free(
740 const Heap_Block *block
741)
742{
743 return !_Heap_Is_used( block );
744}
745
755static inline bool _Heap_Is_block_in_heap(
756 const Heap_Control *heap,
757 const Heap_Block *block
758)
759{
760 return (uintptr_t) block >= (uintptr_t) heap->first_block
761 && (uintptr_t) block <= (uintptr_t) heap->last_block;
762}
763
777static inline void _Heap_Set_last_block_size( Heap_Control *heap )
778{
779 _Heap_Block_set_size(
780 heap->last_block,
781 (uintptr_t) heap->first_block - (uintptr_t) heap->last_block
782 );
783}
784
794static inline uintptr_t _Heap_Get_size( const Heap_Control *heap )
795{
796 return heap->stats.size;
797}
798
808static inline uintptr_t _Heap_Max( uintptr_t a, uintptr_t b )
809{
810 return a > b ? a : b;
811}
812
822static inline uintptr_t _Heap_Min( uintptr_t a, uintptr_t b )
823{
824 return a < b ? a : b;
825}
826
827#ifdef RTEMS_DEBUG
828 #define RTEMS_HEAP_DEBUG
829#endif
830
831#ifdef RTEMS_HEAP_DEBUG
832 #include <assert.h>
833 #define _HAssert( cond ) \
834 do { \
835 if ( !(cond) ) { \
836 __assert( __FILE__, __LINE__, #cond ); \
837 } \
838 } while (0)
839#else
840 #define _HAssert( cond ) ((void) 0)
841#endif
842
845#ifdef __cplusplus
846}
847#endif
848
849#endif
850/* end of include file */
This header file provides the interfaces of the Assert Handler.
void _Heap_Greedy_free(Heap_Control *heap, Heap_Block *blocks)
Frees blocks of a greedy allocation.
Definition: heapgreedy.c:111
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:93
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:449
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:188
#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:271
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:221
void _Heap_Iterate(Heap_Control *heap, Heap_Block_visitor visitor, void *visitor_arg)
Iterates over all blocks of the heap.
Definition: heapiterate.c:43
void _Heap_Get_information(Heap_Control *heap, Heap_Information_block *info)
Returns information about used and free blocks for the heap.
Definition: heapgetinfo.c:65
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:106
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:44
bool _Heap_Walk(Heap_Control *heap, int source, bool dump)
Verifies the integrity of the heap.
Definition: heapwalk.c:332
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:44
Heap_Error_reason
The heap error reason.
Definition: heap.h:163
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:224
bool _Heap_Free(Heap_Control *heap, void *addr)
Frees the allocated memory area.
Definition: heapfree.c:119
Heap_Resize_status
See _Heap_Resize_block().
Definition: heapimpl.h:67
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:225
#define HEAP_PREV_BLOCK_USED
See also Heap_Block::size_and_flag.
Definition: heapimpl.h:56
void _Heap_Get_free_information(Heap_Control *heap, Heap_Information *info)
Returns information about free blocks for the heap.
Definition: heapgetfreeinfo.c:44
This header file provides interfaces of the Heap Handler which are used by the implementation and the...
Description for free or used blocks.
Definition: heap.h:277
Heap_Block * prev
Pointer to the previous free block or part of the allocated area.
Definition: heap.h:333
Heap_Block * next
Pointer to the next free block or part of the allocated area.
Definition: heap.h:325
Control block used to manage a heap.
Definition: heap.h:339
Information block returned by _Heap_Get_information().
Definition: heapinfo.h:165
Information about blocks.
Definition: heapinfo.h:145
uintptr_t size
Size of the allocatable area in bytes.
Definition: heapinfo.h:80
unsigned size
Definition: tte.h:1