summaryrefslogblamecommitdiffstats
path: root/cpukit/score/include/rtems/score/heap.h
blob: c68bfd0fd168770a062fc9cd2a09d6fc9ae449bc (plain) (tree)
1
2
3
4
5
6
7
8
9
10
    
                             







                                                                         



                            
                                                    
  

                                                           
                                         






                      







                                                                   



                  
   

                                





                             
   

                                          




                                            
 
   
















                                                           

                                                       
                



                                                                  

                         


                                                                      
   
                            
 




                                                                      
 
   

                                                                 





                                                               
                                                                 





                                                                  

                                                
 













                                                                     





                                                                   
                                                                 




                                                                   
                          







                                      

  
   

                                                                     
                                                                        






                                                                      
                













                                          
                       

                 


                                                                         
                                                                







                                                                          
   
                            

                                 

                         

  


                                                                         
  






                                                                       
   


                                 

                               

  
   
                                                                 
                                                                           
                                                          



                                                                         
   

                         
                    

  
   
                                                                      
                                                                           
              






                                                                            
   


                                        
                           

  
   
                                                         
                                                                   
                                                           




                                                                           
   




                             
   
                                                        



                                                                  
   





                         
   


                                                                         



                                                             
   




                                                  













                                                               
 
                             
                               
      




                  

       

                         
/** 
 *  @file  rtems/score/heap.h
 *
 *  This include file contains the information pertaining to the Heap
 *  Handler.  A heap is a doubly linked list of variable size
 *  blocks which are allocated using the first fit method.  Garbage
 *  collection is performed each time a block is returned to the heap by
 *  coalescing neighbor blocks.  Control information for both allocated
 *  and unallocated blocks is contained in the heap space.  A heap header
 *  contains control information for the heap.
 */

/*
 *  COPYRIGHT (c) 1989-2004.
 *  On-Line Applications Research Corporation (OAR).
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 *
 *  $Id$
 */

#ifndef __RTEMS_HEAP_h
#define __RTEMS_HEAP_h

/**
 *  @defgroup ScoreHeap Heap Handler
 *
 *  This group contains functionality which provides the foundation
 *  Heap services used in all of the APIs supported by RTEMS.
 */
/**@{*/

#ifdef __cplusplus
extern "C" {
#endif

/**
 *  Status codes for heap_extend
 */
typedef enum {
  HEAP_EXTEND_SUCCESSFUL,
  HEAP_EXTEND_ERROR,
  HEAP_EXTEND_NOT_IMPLEMENTED
}  Heap_Extend_status;

/**
 *  Status codes for _Heap_Get_information
 */
typedef enum {
    HEAP_GET_INFORMATION_SUCCESSFUL = 0,
    HEAP_GET_INFORMATION_SYSTEM_STATE_ERROR,
    HEAP_GET_INFORMATION_BLOCK_ERROR
}  Heap_Get_information_status;

/**
 *  Information block returned by the Heap routines used to
 *  obtain statistics.  This information is returned about
 *  either free or used blocks.
 */

typedef struct {
  /** Number of blocks of this type. */
  uint32_t number;
  /** Largest blocks of this type. */
  uint32_t largest;
  /** Total size of the blocks of this type. */
  uint32_t total;

} Heap_Information;


/**
 *  Information block returned by _Heap_Get_information
 */
typedef struct {
  /** This field is information on the used blocks in the heap. */
  Heap_Information Free;
  /** This field is information on the used blocks in the heap. */
  Heap_Information Used;
} Heap_Information_block;

/**
 *  This constant is used in the size/used field of each heap block to
 *  indicate when a block is in use.
 */
#define HEAP_BLOCK_USED    1

/**
 *  This constant is used in the size/used field of each heap block to
 *  indicate when a block is free.
 */
#define HEAP_BLOCK_FREE    0

/**
 *  The size/used field value for the dummy front and back flags.
 */
#define HEAP_DUMMY_FLAG    (0 + HEAP_BLOCK_USED)

/*
 *  The following constants reflect various requirements of the
 *  heap data structures which impact the management of a heap.
 *
 *  NOTE:  Because free block overhead is greater than used block
 *         overhead AND a portion of the allocated space is from
 *         the extra free block overhead, the absolute lower bound
 *         of the minimum fragment size is equal to the size of
 *         the free block overhead.
 */

/** size dummy first and last blocks */
#define HEAP_OVERHEAD (sizeof( uint32_t   ) * 2)

/** number of bytes of overhead in used block */
#define HEAP_BLOCK_USED_OVERHEAD (sizeof( void * ) * 2)

/** Minimum number of bytes the user may specify for the heap size */
#define HEAP_MINIMUM_SIZE (HEAP_OVERHEAD + sizeof (Heap_Block))

/**
 *  Forward reference
 *
 *  @ref Heap_Block
 */
typedef struct Heap_Block_struct Heap_Block;

/**
 *  The following defines the data structure used to manage
 *  individual blocks in a heap.   When the block is allocated, the
 *  next and previous fields are not used by the Heap Handler
 *  and thus the address returned for the block starts at
 *  the address of the next field.
 *
 *  @note  The next and previous pointers are only valid when the
 *         block is free.  Caution must be exercised to insure that
 *         allocated blocks are large enough to contain them and
 *         that they are not accidentally overwritten when the
 *         block is actually allocated.
 */
struct Heap_Block_struct {
  /** size and status of prev block */
  uint32_t    back_flag;
  /** size and status of block */
  uint32_t    front_flag;
  /** pointer to next block */
  Heap_Block *next;
  /** pointer to previous block */
  Heap_Block *previous;
};

/**
 *  The following defines the control block used to manage each heap.
 *
 *  @note This structure is layed out such that it can be used a a dummy
 *  first and last block on the free block chain.  The extra padding
 *  insures the dummy last block is the correct size.
 *
 *  The first Heap_Block starts at first while the second starts at
 *  final.  This is effectively the same trick as is used in the Chain
 *  Handler.
 */
typedef struct {
  /** first valid block address in heap */
  Heap_Block *start;
  /** last valid block address in heap */
  Heap_Block *final;

  /** pointer to first block in heap */
  Heap_Block *first;
  /** always NULL pointer */
  Heap_Block *permanent_null;
  /** pointer to last block in heap */
  Heap_Block *last;
  /** allocation unit */
  uint32_t    page_size;
  /** reserved field */
  uint32_t    reserved;
}   Heap_Control;

/**
 *  This routine initializes @a the_heap record to manage the
 *  contiguous heap of @a size bytes which starts at @a starting_address.
 *  Blocks of memory are allocated from the heap in multiples of
 *  @a page_size byte units.
 *
 *  @param the_heap (in) is the heap to operate upon
 *  @param starting_address (in) is the starting address of the memory for
 *         the heap
 *  @param size (in) is the size in bytes of the memory area for the heap
 *  @param page_size (in) is the size in bytes of the allocation unit
 *  @return XXX
 */
uint32_t   _Heap_Initialize(
  Heap_Control *the_heap,
  void         *starting_address,
  uint32_t      size,
  uint32_t      page_size
);

/**
 *  This routine grows @a the_heap memory area using the size bytes which
 *  begin at @a starting_address.
 *
 *  @param the_heap (in) is the heap to operate upon
 *  @param starting_address (in) is the starting address of the memory
 *         to add to the heap
 *  @param size (in) is the size in bytes of the memory area to add
 *  @param amount_extended (in) points to a user area to return the 
 *  @return a status indicating success or the reason for failure
 *  @return *size filled in with the amount of memory added to the heap
 */
Heap_Extend_status _Heap_Extend(
  Heap_Control *the_heap,
  void         *starting_address,
  uint32_t      size,
  uint32_t     *amount_extended
);

/**
 *  This function attempts to allocate a block of size bytes from
 *  @a the_heap.  If insufficient memory is free in @a the_heap to allocate
 *  a  block of the requested size, then NULL is returned.
 *
 *  @param the_heap (in) is the heap to operate upon
 *  @param size (in) is the amount of memory to allocate in bytes
 *  @return NULL if unsuccessful and a pointer to the block if successful
 */
void *_Heap_Allocate(
  Heap_Control *the_heap,
  uint32_t      size
);

/**
 *  This kernel routine sets size to the size of the given heap block.
 *  It returns TRUE if the @a starting_address is in @a the_heap, and FALSE
 *  otherwise.
 *
 *  @param the_heap (in) is the heap to operate upon
 *  @param starting_address (in) is the starting address of the user block 
 *         to obtain the size of
 *  @param size (in) points to a user area to return the size in
 *  @return TRUE if successfully able to determine the size, FALSE otherwise
 *  @return *size filled in with the size of the user area for this block
 */
boolean _Heap_Size_of_user_area(
  Heap_Control        *the_heap,
  void                *starting_address,
  uint32_t            *size
);

/**
 *  This routine returns the block of memory which begins
 *  at @a starting_address to @a the_heap.  Any coalescing which is
 *  possible with the freeing of this routine is performed.
 *
 *  @param the_heap (in) is the heap to operate upon
 *  @param starting_address (in) is the starting address of the user block 
 *         to free
 *  @return TRUE if successfully freed, FALSE otherwise
 */
boolean _Heap_Free(
  Heap_Control *the_heap,
  void         *start_address
);

/**
 *  This routine walks the heap to verify its integrity.
 *  
 *  @param the_heap (in) is the heap to operate upon
 *  @param source (in) XXX
 *  @param do_dump (in) is set to TRUE if errors should be printed
 */
void _Heap_Walk(
  Heap_Control *the_heap,
  int           source,
  boolean       do_dump
);

/**
 *  This kernel routine walks the heap and tots up the free and allocated
 *  sizes.  Derived from _Heap_Walk.
 *
 *  @param the_heap (in) pointer to heap header
 *  @param the_info (in) pointer to a status information area
 *  @return *the_info is filled with status information
 *  @return 0=success, otherwise heap is corrupt.
 */
Heap_Get_information_status _Heap_Get_information(
  Heap_Control            *the_heap,
  Heap_Information_block  *the_info
);

/**
 *  This heap routine returns information about the free blocks
 *  in the specified heap.
 *  
 *  @param the_heap (in) pointer to heap header.
 *  @param info (in) pointer to the free block information.
 *  
 *  @return free block information filled in.
 */ 
    
void _Heap_Get_free_information(
  Heap_Control        *the_heap,
  Heap_Information    *info
);

#ifndef __RTEMS_APPLICATION__
#include <rtems/score/heap.inl>
#endif

#ifdef __cplusplus
}
#endif

/**@}*/

#endif
/* end of include file */