Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSScoreHeap
0007  *
0008  * @brief This header file provides interfaces of the
0009  *   @ref RTEMSScoreBarrier which are only used by the implementation.
0010  */
0011 
0012 /*
0013  *  COPYRIGHT (c) 1989-2008.
0014  *  On-Line Applications Research Corporation (OAR).
0015  *
0016  * Redistribution and use in source and binary forms, with or without
0017  * modification, are permitted provided that the following conditions
0018  * are met:
0019  * 1. Redistributions of source code must retain the above copyright
0020  *    notice, this list of conditions and the following disclaimer.
0021  * 2. Redistributions in binary form must reproduce the above copyright
0022  *    notice, this list of conditions and the following disclaimer in the
0023  *    documentation and/or other materials provided with the distribution.
0024  *
0025  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0026  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0027  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0028  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0029  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0030  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0031  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0032  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0033  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0034  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0035  * POSSIBILITY OF SUCH DAMAGE.
0036  */
0037 
0038 #ifndef _RTEMS_SCORE_HEAPIMPL_H
0039 #define _RTEMS_SCORE_HEAPIMPL_H
0040 
0041 #include <rtems/score/heap.h>
0042 
0043 #ifdef __cplusplus
0044 extern "C" {
0045 #endif
0046 
0047 /**
0048  * @addtogroup RTEMSScoreHeap
0049  *
0050  * @{
0051  */
0052 
0053 /**
0054  * @brief See also @ref Heap_Block.size_and_flag.
0055  */
0056 #define HEAP_PREV_BLOCK_USED ((uintptr_t) 1)
0057 
0058 /**
0059  * @brief Size of the part at the block begin which may be used for allocation
0060  * in charge of the previous block.
0061  */
0062 #define HEAP_ALLOC_BONUS sizeof(uintptr_t)
0063 
0064 /**
0065  * @brief See _Heap_Resize_block().
0066  */
0067 typedef enum {
0068   HEAP_RESIZE_SUCCESSFUL,
0069   HEAP_RESIZE_UNSATISFIED,
0070   HEAP_RESIZE_FATAL_ERROR
0071 } Heap_Resize_status;
0072 
0073 /**
0074  * @brief Gets the first and last block for the heap area.
0075  *
0076  * Nothing will be written to this area.
0077  *
0078  * @param heap_area_begin The starting address of the heap area.
0079  * @param heap_area_size The size of the heap area.
0080  * @param page_size The page size for the calculation.
0081  * @param min_block_size The minimal block size for the calculation.
0082  * @param[out] first_block_ptr The pointer to the first block in the case of success
0083  * @param[out] last_block_ptr The pointer to the last block in the case of success
0084  *
0085  * @retval true The area is big enough.
0086  * @retval false The area is not big enough.
0087  */
0088 bool _Heap_Get_first_and_last_block(
0089   uintptr_t heap_area_begin,
0090   uintptr_t heap_area_size,
0091   uintptr_t page_size,
0092   uintptr_t min_block_size,
0093   Heap_Block **first_block_ptr,
0094   Heap_Block **last_block_ptr
0095 );
0096 
0097 /**
0098  * @brief Initializes the heap control block.
0099  *
0100  * Blocks of memory are allocated from the heap in multiples of @a page_size
0101  * byte units.  If the @a page_size is equal to zero or is not multiple of
0102  * @c CPU_ALIGNMENT, it is aligned up to the nearest @c CPU_ALIGNMENT boundary.
0103  *
0104  * @param[out] heap The heap control block to manage the area.
0105  * @param area_begin The starting address of the area.
0106  * @param area_size The size of the area in bytes.
0107  * @param page_size The page size for the calculation
0108  *
0109  * @retval some_value The maximum memory available.
0110  * @retval 0 The initialization failed.
0111  *
0112  * @see Heap_Initialization_or_extend_handler.
0113  */
0114 uintptr_t _Heap_Initialize(
0115   Heap_Control *heap,
0116   void *area_begin,
0117   uintptr_t area_size,
0118   uintptr_t page_size
0119 );
0120 
0121 /**
0122  * @brief Allocates an aligned memory area with boundary constraint.
0123  *
0124  * A size value of zero will return a unique address which may be freed with
0125  * _Heap_Free().
0126  *
0127  * @param[in, out] heap The heap to allocate a memory are from.
0128  * @param size The size of the desired memory are in bytes.
0129  * @param alignment The allocated memory area will begin at an address aligned by this value.
0130  * @param boundary The allocated memory area will fulfill a boundary constraint,
0131  *      if this value is not equal to zero.  The boundary value specifies
0132  *      the set of addresses which are aligned by the boundary value.  The
0133  *      interior of the allocated memory area will not contain an element of this
0134  *      set.  The begin or end address of the area may be a member of the set.
0135  *
0136  * @retval pointer The starting address of the allocated memory area.
0137  * @retval NULL No memory is available of the parameters are inconsistent.
0138  */
0139 void *_Heap_Allocate_aligned_with_boundary(
0140   Heap_Control *heap,
0141   uintptr_t size,
0142   uintptr_t alignment,
0143   uintptr_t boundary
0144 );
0145 
0146 /**
0147  * @brief Allocates an aligned memory area.
0148  *
0149  * A size value of zero will return a unique address which may be freed with
0150  * _Heap_Free().
0151  *
0152  * @param[in, out] heap The heap to allocate a memory are from.
0153  * @param size The size of the desired memory are in bytes.
0154  * @param alignment The allocated memory area will begin at an address aligned by this value.
0155  *
0156  * @retval pointer The starting address of the allocated memory area.
0157  * @retval NULL No memory is available of the parameters are inconsistent.
0158  */
0159 static inline void *_Heap_Allocate_aligned(
0160   Heap_Control *heap,
0161   uintptr_t size,
0162   uintptr_t alignment
0163 )
0164 {
0165   return _Heap_Allocate_aligned_with_boundary( heap, size, alignment, 0 );
0166 }
0167 
0168 /**
0169  * @brief Allocates a memory area.
0170  *
0171  * A size value of zero will return a unique address which may be freed with
0172  * _Heap_Free().
0173  *
0174  * @param[in, out] heap The heap to allocate a memory are from.
0175  * @param size The size of the desired memory are in bytes.
0176  *
0177  * @retval pointer The starting address of the allocated memory area.
0178  * @retval NULL No memory is available of the parameters are inconsistent.
0179  */
0180 static inline void *_Heap_Allocate( Heap_Control *heap, uintptr_t size )
0181 {
0182   return _Heap_Allocate_aligned_with_boundary( heap, size, 0, 0 );
0183 }
0184 
0185 /**
0186  * @brief Frees the allocated memory area.
0187  *
0188  * Inappropriate values for @a addr may corrupt the heap.
0189  *
0190  * @param[in, out] heap The heap of the allocated memory area.
0191  * @param addr The starting address of the memory area to be freed.
0192  *
0193  * @retval true The allocated memory area was successfully freed.
0194  * @retval false The method failed.
0195  */
0196 bool _Heap_Free( Heap_Control *heap, void *addr );
0197 
0198 /**
0199  * @brief Verifies the integrity of the heap.
0200  *
0201  * Walks the heap to verify its integrity.
0202  *
0203  * @param heap The heap whose integrity is to be verified.
0204  * @param source If @a dump is @c true, this is used to mark the output lines.
0205  * @param dump Indicates whether diagnostic messages will be printed to standard output.
0206  *
0207  * @retval true No errors occurred, the heap“s integrity is not violated.
0208  * @retval false The heap is corrupt.
0209  */
0210 bool _Heap_Walk(
0211   Heap_Control *heap,
0212   int source,
0213   bool dump
0214 );
0215 
0216 /**
0217  * @brief Heap block visitor.
0218  *
0219  * @see _Heap_Iterate().
0220  *
0221  * @retval true Stop the iteration.
0222  * @retval false Continue the iteration.
0223  */
0224 typedef bool (*Heap_Block_visitor)(
0225   const Heap_Block *block,
0226   uintptr_t block_size,
0227   bool block_is_used,
0228   void *visitor_arg
0229 );
0230 
0231 /**
0232  * @brief Iterates over all blocks of the heap.
0233  *
0234  * @param[in, out] heap The heap to iterate over.
0235  * @param visitor This will be called for each heap block with
0236  *      the argument @a visitor_arg.
0237  * @param[in, out] visitor_arg The argument for all calls of @a visitor.
0238  */
0239 void _Heap_Iterate(
0240   Heap_Control *heap,
0241   Heap_Block_visitor visitor,
0242   void *visitor_arg
0243 );
0244 
0245 /**
0246  * @brief Greedily allocates and empties the heap.
0247  *
0248  * Afterwards, the heap has at most @a block_count allocatable blocks of sizes
0249  * specified by @a block_sizes.  All other blocks are used.
0250  *
0251  * @param[in, out] heap The heap to operate upon
0252  * @param block_sizes The sizes of the allocatable blocks.  Must point to an
0253  *      array with @a block_count members.
0254  * @param block_count The maximum number of allocatable blocks of sizes
0255  *      specified by @block_sizes.
0256  *
0257  * @return Pointer to the first allocated block.
0258  *
0259  * @see _Heap_Greedy_free().
0260  */
0261 Heap_Block *_Heap_Greedy_allocate(
0262   Heap_Control *heap,
0263   const uintptr_t *block_sizes,
0264   size_t block_count
0265 );
0266 
0267 /**
0268  * @brief Greedily allocates all blocks except the largest free block.
0269  *
0270  * Afterwards the heap has at most one allocatable block.  This block is the
0271  * largest free block if it exists.  All other blocks are used.
0272  *
0273  * @param[in, out] heap The heap to operate upon.
0274  * @param[out] allocatable_size Stores the size of the largest free block of
0275  *      the heap after the method call.
0276  *
0277  * @return Pointer to the first allocated block.
0278  *
0279  * @see _Heap_Greedy_free().
0280  */
0281 Heap_Block *_Heap_Greedy_allocate_all_except_largest(
0282   Heap_Control *heap,
0283   uintptr_t *allocatable_size
0284 );
0285 
0286 /**
0287  * @brief Frees blocks of a greedy allocation.
0288  *
0289  * @param[in, out] heap The heap to operate upon.
0290  * @param blocks Must be the return value of _Heap_Greedy_allocate().
0291  */
0292 void _Heap_Greedy_free(
0293   Heap_Control *heap,
0294   Heap_Block *blocks
0295 );
0296 
0297 /**
0298  * @brief Returns information about used and free blocks for the heap.
0299  *
0300  * @param heap The heap to get the information from.
0301  * @param[out] info Stores the information of the @a heap after the method call.
0302  */
0303 void _Heap_Get_information(
0304   Heap_Control *heap,
0305   Heap_Information_block *info
0306 );
0307 
0308 /**
0309  * @brief Returns information about free blocks for the heap.
0310  *
0311  * @param heap The heap to get the information from.
0312  * @param[out] info Stores the information about free blocks of @a heap after the
0313  *      method call.
0314  */
0315 void _Heap_Get_free_information(
0316   Heap_Control *heap,
0317   Heap_Information *info
0318 );
0319 
0320 /**
0321  * @brief Returns the size of the allocatable memory area.
0322  *
0323  * The size value may be greater than the initially requested size in
0324  * _Heap_Allocate_aligned_with_boundary().
0325  *
0326  * Inappropriate values for @a addr will not corrupt the heap, but may yield
0327  * invalid size values.
0328  *
0329  * @param heap The heap to operate upon.
0330  * @param addr The starting address of the allocatable memory area.
0331  * @param[out] size Stores the size of the allocatable memory area after the method call.
0332  *
0333  * @retval true The operation was successful.
0334  * @retval false The operation was not successful.
0335  */
0336 bool _Heap_Size_of_alloc_area(
0337   Heap_Control *heap,
0338   void *addr,
0339   uintptr_t *size
0340 );
0341 
0342 /**
0343  * @brief Resizes the block of the allocated memory area.
0344  *
0345  * Inappropriate values for @a addr may corrupt the heap.
0346  *
0347  * @param[in, out] heap The heap to operate upon.
0348  * @param addr The starting address of the allocated memory area to be resized.
0349  * @param size The least possible size for the new memory area.  Resize may be
0350  *      impossible and depends on the current heap usage.
0351  * @param[out] old_size Stores the size available for allocation in the current
0352  *      block before the resize after the method call.
0353  * @param[out] new_size Stores the size available for allocation in the resized
0354  *      block after the method call.  In the case of an unsuccessful resize,
0355  *      zero is returned in this parameter
0356  *
0357  * @retval HEAP_RESIZE_SUCCESSFUL The resize was successful.
0358  * @retval HEAP_RESIZE_UNSATISFIED The least possible size @a size was too big.
0359  *      Resize not possible.
0360  * @retval HEAP_RESIZE_FATAL_ERROR The block starting at @a addr is not part of
0361  *      the heap.
0362  */
0363 Heap_Resize_status _Heap_Resize_block(
0364   Heap_Control *heap,
0365   void *addr,
0366   uintptr_t size,
0367   uintptr_t *old_size,
0368   uintptr_t *new_size
0369 );
0370 
0371 /**
0372  * @brief Allocates the memory area.
0373  * starting at @a alloc_begin of size
0374  * @a alloc_size bytes in the block @a block.
0375  *
0376  * The block may be split up into multiple blocks.  The previous and next block
0377  * may be used or free.  Free block parts which form a vaild new block will be
0378  * inserted into the free list or merged with an adjacent free block.  If the
0379  * block is used, they will be inserted after the free list head.  If the block
0380  * is free, they will be inserted after the previous block in the free list.
0381  *
0382  * Inappropriate values for @a alloc_begin or @a alloc_size may corrupt the
0383  * heap.
0384  *
0385  * @param[in, out] heap The heap to operate upon.
0386  * @param block The block in which the memory area should be allocated
0387  * @param alloc_begin The starting address of the memory area that shall be allocated.
0388  * @param alloc_size The size of the desired allocated area in bytes.
0389  *
0390  * @return The block containing the allocated memory area.
0391  */
0392 Heap_Block *_Heap_Block_allocate(
0393   Heap_Control *heap,
0394   Heap_Block *block,
0395   uintptr_t alloc_begin,
0396   uintptr_t alloc_size
0397 );
0398 
0399 #ifndef HEAP_PROTECTION
0400   #define _Heap_Protection_block_initialize( heap, block ) ((void) 0)
0401   #define _Heap_Protection_block_check( heap, block ) ((void) 0)
0402   #define _Heap_Protection_block_error( heap, block, reason ) ((void) 0)
0403   #define _Heap_Protection_free_all_delayed_blocks( heap ) ((void) 0)
0404 #else
0405   static inline void _Heap_Protection_block_initialize(
0406     Heap_Control *heap,
0407     Heap_Block *block
0408   )
0409   {
0410     (*heap->Protection.block_initialize)( heap, block );
0411   }
0412 
0413   static inline void _Heap_Protection_block_check(
0414     Heap_Control *heap,
0415     Heap_Block *block
0416   )
0417   {
0418     (*heap->Protection.block_check)( heap, block );
0419   }
0420 
0421   static inline void _Heap_Protection_block_error(
0422     Heap_Control *heap,
0423     Heap_Block *block,
0424     Heap_Error_reason reason
0425   )
0426   {
0427     (*heap->Protection.block_error)( heap, block, reason );
0428   }
0429 
0430   void _Heap_Protection_free_all_delayed_blocks( Heap_Control *heap );
0431 #endif
0432 
0433 /**
0434  * @brief Sets the fraction of delayed free blocks that is actually freed
0435  * during memory shortage.
0436  *
0437  * The default is to free half the delayed free blocks.  This is equal to a
0438  * fraction value of two.
0439  *
0440  * @param[in, out] heap The heap control.
0441  * @param fraction The fraction is one divided by this fraction value.
0442  */
0443 static inline void _Heap_Protection_set_delayed_free_fraction(
0444   Heap_Control *heap,
0445   uintptr_t fraction
0446 )
0447 {
0448 #ifdef HEAP_PROTECTION
0449   heap->Protection.delayed_free_fraction = fraction;
0450 #else
0451   (void) heap;
0452   (void) fraction;
0453 #endif
0454 }
0455 
0456 /**
0457  * @brief Returns the head of the free list of the heap.
0458  *
0459  * @param heap The heap to operate upon.
0460  *
0461  * @return The head of the free list.
0462  */
0463 static inline Heap_Block *_Heap_Free_list_head( Heap_Control *heap )
0464 {
0465   return &heap->free_list;
0466 }
0467 
0468 /**
0469  * @brief Returns the tail of the free list of the heap.
0470  *
0471  * @param heap The heap to operate upon.
0472  *
0473  * @return The tail of the free list.
0474  */
0475 static inline Heap_Block *_Heap_Free_list_tail( Heap_Control *heap )
0476 {
0477   return &heap->free_list;
0478 }
0479 
0480 /**
0481  * @brief Returns the first block of the free list of the heap.
0482  *
0483  * @param heap The heap to operate upon.
0484  *
0485  * @return The first block of the free list.
0486  */
0487 static inline Heap_Block *_Heap_Free_list_first( Heap_Control *heap )
0488 {
0489   return _Heap_Free_list_head(heap)->next;
0490 }
0491 
0492 /**
0493  * @brief Returns the last block of the free list of the heap.
0494  *
0495  * @param heap The heap to operate upon.
0496  *
0497  * @return The last block of the free list.
0498  */
0499 static inline Heap_Block *_Heap_Free_list_last( Heap_Control *heap )
0500 {
0501   return _Heap_Free_list_tail(heap)->prev;
0502 }
0503 
0504 /**
0505  * @brief Removes the block from the free list.
0506  *
0507  * @param block The block to be removed.
0508  */
0509 static inline void _Heap_Free_list_remove( Heap_Block *block )
0510 {
0511   Heap_Block *next = block->next;
0512   Heap_Block *prev = block->prev;
0513 
0514   prev->next = next;
0515   next->prev = prev;
0516 }
0517 
0518 /**
0519  * @brief Replaces one block in the free list by another.
0520  *
0521  * @param old_block The block in the free list to replace.
0522  * @param new_block The block that should replace @a old_block.
0523  */
0524 static inline void _Heap_Free_list_replace(
0525   Heap_Block *old_block,
0526   Heap_Block *new_block
0527 )
0528 {
0529   Heap_Block *next = old_block->next;
0530   Heap_Block *prev = old_block->prev;
0531 
0532   new_block->next = next;
0533   new_block->prev = prev;
0534 
0535   next->prev = new_block;
0536   prev->next = new_block;
0537 }
0538 
0539 /**
0540  * @brief Inserts a block after an existing block in the free list.
0541  *
0542  * @param block_before The block that is already in the free list.
0543  * @param new_block The block to be inserted after @a block_before.
0544  */
0545 static inline void _Heap_Free_list_insert_after(
0546   Heap_Block *block_before,
0547   Heap_Block *new_block
0548 )
0549 {
0550   Heap_Block *next = block_before->next;
0551 
0552   new_block->next = next;
0553   new_block->prev = block_before;
0554   block_before->next = new_block;
0555   next->prev = new_block;
0556 }
0557 
0558 /**
0559  * @brief Inserts a block before an existing block in the free list.
0560  *
0561  * @param block_before The block that is already in the free list.
0562  * @param new_block The block to be inserted before @a block_before.
0563  */
0564 static inline void _Heap_Free_list_insert_before(
0565   Heap_Block *block_next,
0566   Heap_Block *new_block
0567 )
0568 {
0569   Heap_Block *prev = block_next->prev;
0570 
0571   new_block->next = block_next;
0572   new_block->prev = prev;
0573   prev->next = new_block;
0574   block_next->prev = new_block;
0575 }
0576 
0577 /**
0578  * @brief Checks if the value is aligned to the given alignment.
0579  *
0580  * @param value The value to check the alignment of.
0581  * @param alignment The alignment for the operation.
0582  *
0583  * @retval true The value is aligned to the given alignment.
0584  * @retval false The value is not aligned to the given alignment.
0585  */
0586 static inline bool _Heap_Is_aligned(
0587   uintptr_t value,
0588   uintptr_t alignment
0589 )
0590 {
0591   return (value % alignment) == 0;
0592 }
0593 
0594 /**
0595  * @brief Returns the aligned value, truncating.
0596  *
0597  * @param value The value to be aligned
0598  * @param alignment The alignment for the operation.
0599  *
0600  * @return The aligned value, truncated.
0601  */
0602 static inline uintptr_t _Heap_Align_down(
0603   uintptr_t value,
0604   uintptr_t alignment
0605 )
0606 {
0607   return value - (value % alignment);
0608 }
0609 
0610 /**
0611  * @brief Returns the block which is @a offset away from @a block.
0612  *
0613  * @param block The block for the relative calculation.
0614  * @param offset The offset for the calculation.
0615  *
0616  * @return The address of the block which is @a offset away from @a block.
0617  */
0618 static inline Heap_Block *_Heap_Block_at(
0619   const Heap_Block *block,
0620   uintptr_t offset
0621 )
0622 {
0623   return (Heap_Block *) ((uintptr_t) block + offset);
0624 }
0625 
0626 /**
0627  * @brief Returns the address of the previous block.
0628  *
0629  * @param block The block of which the address of the previous block is requested.
0630  *
0631  * @return The address of the previous block.
0632  */
0633 static inline Heap_Block *_Heap_Prev_block(
0634   const Heap_Block *block
0635 )
0636 {
0637   return (Heap_Block *) ((uintptr_t) block - block->prev_size);
0638 }
0639 
0640 /**
0641  * @brief Returns the first address in the block without the heap header.
0642  *
0643  * @param block The block for the operation.
0644  *
0645  * @return The first address after the heap header.
0646  */
0647 static inline uintptr_t _Heap_Alloc_area_of_block(
0648   const Heap_Block *block
0649 )
0650 {
0651   return (uintptr_t) block + HEAP_BLOCK_HEADER_SIZE;
0652 }
0653 
0654 /**
0655  * @brief Returns the starting address of the block corresponding to the allocatable area.
0656  *
0657  * @param alloc_begin The starting address of the allocatable area.
0658  * @param page_size The page size for the calculation.
0659  *
0660  * @return The Starting address of the corresponding block of the allocatable area.
0661  */
0662 static inline Heap_Block *_Heap_Block_of_alloc_area(
0663   uintptr_t alloc_begin,
0664   uintptr_t page_size
0665 )
0666 {
0667   return (Heap_Block *) (_Heap_Align_down( alloc_begin, page_size )
0668     - HEAP_BLOCK_HEADER_SIZE);
0669 }
0670 
0671 /**
0672  * @brief Returns the block size.
0673  *
0674  * @param block The block of which the size is requested.
0675  *
0676  * @return The block size.
0677  */
0678 static inline uintptr_t _Heap_Block_size( const Heap_Block *block )
0679 {
0680   return block->size_and_flag & ~HEAP_PREV_BLOCK_USED;
0681 }
0682 
0683 /**
0684  * @brief Sets the block size.
0685  *
0686  * @param[in, out] block The block of which the size shall be set.
0687  * @param size The new size of the block.
0688  */
0689 static inline void _Heap_Block_set_size(
0690   Heap_Block *block,
0691   uintptr_t size
0692 )
0693 {
0694   uintptr_t flag = block->size_and_flag & HEAP_PREV_BLOCK_USED;
0695 
0696   block->size_and_flag = size | flag;
0697 }
0698 
0699 /**
0700  * @brief Returns if the previous heap block is used.
0701  *
0702  * @param block The block of which the information about the previous
0703  *      block is requested.
0704  *
0705  * @retval true The previous block is used.
0706  * @retval false The previous block is not used.
0707  */
0708 static inline bool _Heap_Is_prev_used( const Heap_Block *block )
0709 {
0710   return block->size_and_flag & HEAP_PREV_BLOCK_USED;
0711 }
0712 
0713 /**
0714  * @brief Returns if the heap block is used.
0715  *
0716  * @param block The block of which the information is requested.
0717  *
0718  * @retval true The block is used.
0719  * @retval false The block is not used.
0720  */
0721 static inline bool _Heap_Is_used(
0722   const Heap_Block *block
0723 )
0724 {
0725   const Heap_Block *const next_block =
0726     _Heap_Block_at( block, _Heap_Block_size( block ) );
0727 
0728   return _Heap_Is_prev_used( next_block );
0729 }
0730 
0731 /**
0732  * @brief Returns if the heap block is free.
0733  *
0734  * @param block The block of which the information is requested.
0735  *
0736  * @retval true The block is free.
0737  * @retval false The block is not free.
0738  */
0739 static inline bool _Heap_Is_free(
0740   const Heap_Block *block
0741 )
0742 {
0743   return !_Heap_Is_used( block );
0744 }
0745 
0746 /**
0747  * @brief Returns if the block is part of the heap.
0748  *
0749  * @param heap The heap to test if the @a block is part of it.
0750  * @param block The block of which the information is requested.
0751  *
0752  * @retval true The block is part of the heap.
0753  * @retval false The block is not part of the heap.
0754  */
0755 static inline bool _Heap_Is_block_in_heap(
0756   const Heap_Control *heap,
0757   const Heap_Block *block
0758 )
0759 {
0760   return (uintptr_t) block >= (uintptr_t) heap->first_block
0761     && (uintptr_t) block <= (uintptr_t) heap->last_block;
0762 }
0763 
0764 /**
0765  * @brief Sets the size of the last block for the heap.
0766  *
0767  * The next block of the last block will be the first block.  Since the first
0768  * block indicates that the previous block is used, this ensures that the last
0769  * block appears as used for the _Heap_Is_used() and _Heap_Is_free()
0770  * functions.
0771  *
0772  * This feature will be used to terminate the scattered heap area list.  See
0773  * also _Heap_Extend().
0774  *
0775  * @param[in, out] heap The heap to set the last block size of.
0776  */
0777 static inline void _Heap_Set_last_block_size( Heap_Control *heap )
0778 {
0779   _Heap_Block_set_size(
0780     heap->last_block,
0781     (uintptr_t) heap->first_block - (uintptr_t) heap->last_block
0782   );
0783 }
0784 
0785 /**
0786  * @brief Returns the size of the allocatable area in bytes.
0787  *
0788  * This value is an integral multiple of the page size.
0789  *
0790  * @param heap The heap to get the allocatable area from.
0791  *
0792  * @return The size of the allocatable area in @a heap in bytes.
0793  */
0794 static inline uintptr_t _Heap_Get_size( const Heap_Control *heap )
0795 {
0796   return heap->stats.size;
0797 }
0798 
0799 /**
0800  * @brief Returns the bigger one of the two arguments.
0801  *
0802  * @param a The parameter on the left hand side of the comparison.
0803  * @param b The parameter on the right hand side of the comparison.
0804  *
0805  * @retval a If a > b.
0806  * @retval b If b >= a
0807  */
0808 static inline uintptr_t _Heap_Max( uintptr_t a, uintptr_t b )
0809 {
0810   return a > b ? a : b;
0811 }
0812 
0813 /**
0814  * @brief Returns the smaller one of the two arguments.
0815  *
0816  * @param a The parameter on the left hand side of the comparison.
0817  * @param b The parameter on the right hand side of the comparison.
0818  *
0819  * @retval a If a < b.
0820  * @retval b If b <= a
0821  */
0822 static inline uintptr_t _Heap_Min( uintptr_t a, uintptr_t b )
0823 {
0824   return a < b ? a : b;
0825 }
0826 
0827 #ifdef RTEMS_DEBUG
0828   #define RTEMS_HEAP_DEBUG
0829 #endif
0830 
0831 #ifdef RTEMS_HEAP_DEBUG
0832   #include <assert.h>
0833   #define _HAssert( cond ) \
0834     do { \
0835       if ( !(cond) ) { \
0836         __assert( __FILE__, __LINE__, #cond ); \
0837       } \
0838     } while (0)
0839 #else
0840   #define _HAssert( cond ) ((void) 0)
0841 #endif
0842 
0843 /** @} */
0844 
0845 #ifdef __cplusplus
0846 }
0847 #endif
0848 
0849 #endif
0850 /* end of include file */