| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef ZEPHYR_INCLUDE_SYS_MEMPOOL_H_ |
| #define ZEPHYR_INCLUDE_SYS_MEMPOOL_H_ |
| |
| #include <kernel.h> |
| #include <sys/mempool_base.h> |
| #include <sys/mutex.h> |
| |
| struct sys_mem_pool { |
| struct sys_mem_pool_base base; |
| struct sys_mutex mutex; |
| }; |
| |
| struct sys_mem_pool_block { |
| struct sys_mem_pool *pool; |
| u32_t level : 4; |
| u32_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 <name>; @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 |