/* * Copyright (c) 2018 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #ifndef ZEPHYR_INCLUDE_SYS_MEMPOOL_H_ #define ZEPHYR_INCLUDE_SYS_MEMPOOL_H_ #include #include #include struct sys_mem_pool { struct sys_mem_pool_base base; struct sys_mutex mutex; }; struct sys_mem_pool_block { struct sys_mem_pool *pool; uint32_t level : 4; uint32_t block : 28; }; /** * @brief Statically define system memory pool * * The memory pool's buffer contains @a n_max blocks that are @a max_size bytes * long. The memory pool allows blocks to be repeatedly partitioned into * quarters, down to blocks of @a min_size bytes long. The buffer is aligned * to a @a align -byte boundary. * * If the pool is to be accessed outside the module where it is defined, it * can be declared via * * @code extern struct sys_mem_pool ; @endcode * * This pool will not be in an initialized state. You will still need to * run sys_mem_pool_init() on it before using any other APIs. * * @param name Name of the memory pool. * @param ignored ignored, any value * @param minsz Size of the smallest blocks in the pool (in bytes). * @param maxsz Size of the largest blocks in the pool (in bytes). * @param nmax Number of maximum sized blocks in the pool. * @param align Alignment of the pool's buffer (power of 2). * @param section Destination binary section for pool data */ #define SYS_MEM_POOL_DEFINE(name, ignored, minsz, maxsz, nmax, align, section) \ char __aligned(WB_UP(align)) Z_GENERIC_SECTION(section) \ _mpool_buf_##name[WB_UP(maxsz) * nmax \ + _MPOOL_BITS_SIZE(maxsz, minsz, nmax)]; \ struct sys_mem_pool_lvl Z_GENERIC_SECTION(section) \ _mpool_lvls_##name[Z_MPOOL_LVLS(maxsz, minsz)]; \ Z_GENERIC_SECTION(section) struct sys_mem_pool name = { \ .base = { \ .buf = _mpool_buf_##name, \ .max_sz = WB_UP(maxsz), \ .n_max = nmax, \ .n_levels = Z_MPOOL_LVLS(maxsz, minsz), \ .levels = _mpool_lvls_##name, \ .flags = SYS_MEM_POOL_USER \ } \ }; \ BUILD_ASSERT(WB_UP(maxsz) >= _MPOOL_MINBLK) /** * @brief Initialize a memory pool * * This is intended to complete initialization of memory pools that have been * declared with SYS_MEM_POOL_DEFINE(). * * @param p Memory pool to initialize */ static inline void sys_mem_pool_init(struct sys_mem_pool *p) { z_sys_mem_pool_base_init(&p->base); } /** * @brief Allocate a block of memory * * Allocate a chunk of memory from a memory pool. This cannot be called from * interrupt context. * * @param p Address of the memory pool * @param size Requested size of the memory block * @return A pointer to the requested memory, or NULL if none is available */ void *sys_mem_pool_alloc(struct sys_mem_pool *p, size_t size); /** * @brief Free memory allocated from a memory pool * * Free memory previously allocated by sys_mem_pool_alloc(). * It is safe to pass NULL to this function, in which case it is a no-op. * * @param ptr Pointer to previously allocated memory */ void sys_mem_pool_free(void *ptr); /** * @brief Try to perform in-place expansion of memory allocated from a pool * * Return 0 if memory previously allocated by sys_mem_pool_alloc() * can accommodate a new size, otherwise return the size of data that * needs to be copied over to new memory. * * @param ptr Pointer to previously allocated memory * @param new_size New size requested for the memory block * @return A 0 if OK, or size of data to copy elsewhere */ size_t sys_mem_pool_try_expand_inplace(void *ptr, size_t new_size); #endif