#ifndef ETHERLIB_MEMORY_POOL_H #define ETHERLIB_MEMORY_POOL_H #include #include #include /** * Record class */ typedef enum { MPRT_FREE = 0, MPRT_ALLOCATED = 1, MPRT_SENTRY = ~0 } MPRecordtype; /** * Record in the allocation registry. */ typedef struct { uint8_t * addrStart; ///< Starting address of allocated memory block. uint32_t size; ///< Size of allocated block. MPRecordtype type; ///< Type of block } MPAllocRecord; /** * Memory pool state structure. */ typedef struct { uint8_t * p; ///< Pointer to contiguous memory block the pool operates on. uint32_t poolSize; ///< Total size of the memory pool. MPAllocRecord * blockRegistry; ///< Array in which block allocations are maintained. uint32_t blockRecCnt; ///< Number of block records (including sentry!) uint32_t freeSpace; ///< Free memory size. } MP; /** * The ways of allocated block shrinking may be carried out. */ typedef enum { MP_SHRINK_BEGIN_FIXED, MP_SHRINK_END_FIXED, // TODO: absolute shrinking } MPShrinkStrategy; /** * Initialize a new memory pool. MP object is allocated at the beginning of the given * area (p). * * Memory structure: * * p -> ------------- * MP object * ------------------ * allocatable area * ------------------ * block registry * p + size -> ------ * * @param p memory block the pool is based on * @param size pool size * @return Pointer to the MP object handling the newly allocated memory pool, or NULL * on failure. */ MP * mp_init(uint8_t * p, uint32_t size); /** * Allocate a memory block chain from memory pool. * @param mp memory pool the allocation is made from * @param size requested memory size * @return beginning of the allocated area or NULL on failure */ uint8_t * mp_alloc(MP * mp, uint32_t size); /** * Release a chain of memory blocks. * @param mp Memory block on which the allocation happened earlier. * @param mpbh Beginning of allocated memory block to free. */ void mp_free(MP * mp, const uint8_t * p); /** * Create report on memory allocations. * @param mp Memory pool */ void mp_report(MP * mp); /** * Get largest contiguous free block size. * @param mp pointer to memory pool * @return largest block size (zero if no more allocatable space is available) */ uint32_t mp_largest_free_block_size(MP *mp); typedef void (MPForeachFn)(MP * mp, const MPAllocRecord * rec, void * userData); /** * Run function on each block. * @param mp pointer to memory pool * @param fn callback function pointer * @param userData data passed to callback function * @param inclFree if true, free blocks are also included into the enumeration */ void mp_foreach_block(MP * mp, MPForeachFn * fn, void * userData, bool inclFree); /** * Get allocation record by starting address. * @param mp pointer to memory pool object * @param startAddr start address of memory block * @return pointer to allocation record if found OR NULL */ MPAllocRecord *mp_get_block_by_start_addr(MP *mp, const uint8_t *startAddr); /** * Shrink block by given size. * @param mp pointer to Memory Pool object * @param beginAddr begin address of block * @param size size decrement * @param strategy shrinking strategy */ bool mp_shrink_block(MP *mp, uint8_t *beginAddr, uint32_t size, MPShrinkStrategy strategy); #endif //ETHERLIB_MEMORY_POOL_H