#ifndef _apl_memory_mempoolapi_h_ #define _apl_memory_mempoolapi_h_ /*---------------------------------------------------------------------------- ** SUMMARY: Memory Pool Interface (MEMPOOL) ** ** DESCRIPTION: ** This file provides an interface for creating and using memory pools. ** Each memory pool contains a collection of N same sized blocks of ** memory, i.e. each memory pool is heap that can only allocate fixed size ** blocks. The application can create many memory pools and each memory ** pool has its own block size. This interface can be used in 'parallel' ** (i.e. co-exist) with other Memory interfaces. ** ** OUT-OF-MEMORY ** ------------- ** The application can at compile time, determine the behavior for ** the out-of-memory condition. By default, Apl_memPoolAllocate() returns ** a NULL pointer when the heap has been exhausted. However, by using the ** the compile switch, USE_APL_MEMPOOL_FATAL_ERROR_WHEN_OUTOFMEMORY, ** Apl_memPoolAllocate() will generate a fatal error when it is unable to ** satifiy the application request for memory. ** ** MEMORY ALIGNMENT ** ---------------- ** By default all blocks allocated from all memory pools are aligned on ** even address boundaries. If the application/platform requires different ** alignment then it needs to set 'OPTION_APL_MEMPOOL_ALIGNMENT_SIZE' to the ** size, in bytes, of the alignment. For example, for alignment on 4 byte ** boundaries, set OPTION_APL_MEMPOOL_ALIGNMENT_SIZE equal to 4. Boundaries ** of 1, 2, and 4 are supported. ** NOTE: When creating a memory pool, the application is RESPONSIBLE for ** providing the raw memory and that raw memory MUST be properly ** aligned to a 'OPTION_APL_MEMPOOL_ALIGNMENT_SIZE' boundary. ** ** ** CONFIGURATION ** ------------- ** COMPILE: USE_APL_MEMPOOL_FATAL_ERROR_WHEN_OUTOFMEMORY ** ** APPLICATION: OPTION_APL_MEMPOOL_ALIGNMENT_SIZE ** ** PLATFORM: none. ** ** ** NOTES: ** 1. Unless explicitly stated, NONE of the following methods may be called ** from interrtup service routines. ** 2. For efficency/optimization some methods are 'inlined'. The inlining ** is done by using the preprocessor/macros. The application should ** treat all methods as function calls and not rely on the fact they may ** be currently defined as macros. ----------------------------------------------------------------------------*/ #include "aplcfg.h" /* For: Application configuration */ #include "apl/types/types.h" /* For: basic types */ #ifdef __cplusplus extern "C" { #endif /*-------------- ERRORS ----------------------------------------------------*/ /** The handle of the 'offending' memory pool is reported with the error */ #define APL_ERRSTR_MEMPOOL_OUT_OF_MEMORY "MEMPOOL: No available free blocks. Memory Pool Handle=" /***/ #define APL_ERR_MEMPOOL_OUT_OF_MEMORY _APL_ERR_MEMPOOL_OUT_OF_MEMORY /*-------------- TYPES -----------------------------------------------------*/ /** Memory Pool Handle. */ #define AplMemPoolHdl _AplMemPoolHdl /*-------------- MACROS/CONSTANTS ------------------------------------------*/ /** Aligment boundary (default value) */ #ifndef OPTION_APL_MEMPOOL_ALIGNMENT_SIZE #define OPTION_APL_MEMPOOL_ALIGNMENT_SIZE 2 #endif /** Helper macro for calculating the raw memory size for 'numBlocks' blocks of size 'blockSize' (also accounts for alignment bytes when needed). */ #define APL_MEMPOOL_RAWSIZE(numBlocks,blockSize) _APL_MEMPOOL_RAWSIZE(numBlocks,blockSize) /*-------------- INLINE IMPLEMENTATION -------------------------------------*/ #include "apl/memory/mempool.h" /* For: inline implementation */ /*-------------- PUBLIC/PUBLISHED API --------------------------------------*/ /** This method creates a Memory Pool. The handle of the newly created memory pool is always returned. The application must supply the raw memory to be used for the pool. The memory pool will create N blocks of size 'userBlockSize'. If the method is able to create at least one block, then a handle to the created memory pool is returned. If there is insufficient memory for even one block, then 0 is returned. The actual number of blocks created is determine by the following formula: (rawMemorySize - 'pool_overhead') numBlocks = -------------------------------------------- (userBlockSize + 'block_overhead') where pool_overhead and block_overhead represent the internal data structure overhead and alignment bytes for the pool and each block. Always use the the macro APL_MEMPOOL_RAWSIZE() to calculate the raw size of the memory required for a memory pool since it properly accounts for the internal organization and neccesary alignment byte(s). NOTES: o The compile option, USE_APL_MEMPOOL_FATAL_ERROR_WHEN_OUTOFMEMORY, applies to this method when used. o This method is thread-safe since it is re-entrant (i.e. all data is local). o It is the RESPONSIBILITY of the application to ensure that memory pointed to by 'rawMemory' is properly aligned to an alignment boundary specifieid by OPTION_APL_MEMPOOL_ALIGNMENT_SIZE. Prototype: AplMemPoolHdl Apl_memPoolCreate( void* rawMemory, AplSize_t rawMemorySize, AplSize_t userBlockSize ); */ #define Apl_memPoolCreate _Apl_memPoolCreate /*-------------- PUBLIC/PUBLISHED API --------------------------------------*/ /** This method attempts to allocate a block of memory from the specified memory pool. The size of the block is determined by the memory pool. The method returns a pointer to an available block of memory if successful, else 0 is returned if no blocks are currently available. NOTES: o There is compile option to generate a fatal error when the out-of-memory condition occurs (see inteface description above for more details). Prototype: void* Apl_memPoolAllocate( AplMemPoolHdl poolToAllocateFrom ); */ #define Apl_memPoolAllocate _Apl_memPoolAllocate /** This method returns the block of memory specified to the specified memory pool. o This method is NOT thread-safe. o If 'blockToFree' equals 0, then no operation is performed o You must free the same pointer that was originally allocated from Apl_memPoolAllocateXXX() AND freed to the SAME memory pool that was use. Freeing 'different' pointers or freeing to different memory pools will crash the system! Prototype: void Apl_memPoolFree( AplMemPoolHdl poolMemoryWasAllocatedFrom, void* blockToFree ); */ #define Apl_memPoolFree _Apl_memPoolFree #ifdef __cplusplus } #endif /*--------------------------------------------------------------------------*/ #endif /* end _apl_memory_mempoolapi_h_ */