| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| /** |
| * @addtogroup OSKernel |
| * @{ |
| * @defgroup OSMempool Memory Pools |
| * @{ |
| */ |
| |
| |
| #ifndef _OS_MEMPOOL_H_ |
| #define _OS_MEMPOOL_H_ |
| |
| #include "os/os.h" |
| #include "os/queue.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /** |
| * A memory block structure. This simply contains a pointer to the free list |
| * chain and is only used when the block is on the free list. When the block |
| * has been removed from the free list the entire memory block is usable by the |
| * caller. |
| */ |
| struct os_memblock { |
| SLIST_ENTRY(os_memblock) mb_next; |
| }; |
| |
| /* XXX: Change this structure so that we keep the first address in the pool? */ |
| /* XXX: add memory debug structure and associated code */ |
| /* XXX: Change how I coded the SLIST_HEAD here. It should be named: |
| SLIST_HEAD(,os_memblock) mp_head; */ |
| |
| /** |
| * Memory pool |
| */ |
| struct os_mempool { |
| /** Size of the memory blocks, in bytes. */ |
| uint32_t mp_block_size; |
| /** The number of memory blocks. */ |
| uint16_t mp_num_blocks; |
| /** The number of free blocks left */ |
| uint16_t mp_num_free; |
| /** The lowest number of free blocks seen */ |
| uint16_t mp_min_free; |
| /** Bitmap of OS_MEMPOOL_F_[...] values. */ |
| uint8_t mp_flags; |
| /** Address of memory buffer used by pool */ |
| uint32_t mp_membuf_addr; |
| STAILQ_ENTRY(os_mempool) mp_list; |
| SLIST_HEAD(,os_memblock); |
| /** Name for memory block */ |
| char *name; |
| }; |
| |
| /** |
| * Indicates an extended mempool. Address can be safely cast to |
| * (struct os_mempool_ext *). |
| */ |
| #define OS_MEMPOOL_F_EXT 0x01 |
| |
| struct os_mempool_ext; |
| |
| /** |
| * Block put callback function. If configured, this callback gets executed |
| * whenever a block is freed to the corresponding extended mempool. Note: The |
| * os_memblock_put() function calls this callback instead of freeing the block |
| * itself. Therefore, it is the callback's responsibility to free the block |
| * via a call to os_memblock_put_from_cb(). |
| * |
| * @param ome The extended mempool that a block is being |
| * freed back to. |
| * @param data The block being freed. |
| * @param arg Optional argument configured along with the |
| * callback. |
| * |
| * @return Indicates whether the block was successfully |
| * freed. A non-zero value should only be |
| * returned if the block was not successfully |
| * released back to its pool. |
| */ |
| typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data, |
| void *arg); |
| |
| struct os_mempool_ext { |
| struct os_mempool mpe_mp; |
| |
| /* Callback that is executed immediately when a block is freed. */ |
| os_mempool_put_fn *mpe_put_cb; |
| void *mpe_put_arg; |
| }; |
| |
| #define OS_MEMPOOL_INFO_NAME_LEN (32) |
| |
| /** |
| * Information describing a memory pool, used to return OS information |
| * to the management layer. |
| */ |
| struct os_mempool_info { |
| /** Size of the memory blocks in the pool */ |
| int omi_block_size; |
| /** Number of memory blocks in the pool */ |
| int omi_num_blocks; |
| /** Number of free memory blocks */ |
| int omi_num_free; |
| /** Minimum number of free memory blocks ever */ |
| int omi_min_free; |
| /** Name of the memory pool */ |
| char omi_name[OS_MEMPOOL_INFO_NAME_LEN]; |
| }; |
| |
| /** |
| * Get information about the next system memory pool. |
| * |
| * @param mempool The current memory pool, or NULL if starting iteration. |
| * @param info A pointer to the structure to return memory pool information |
| * into. |
| * |
| * @return The next memory pool in the list to get information about, or NULL |
| * when at the last memory pool. |
| */ |
| struct os_mempool *os_mempool_info_get_next(struct os_mempool *, |
| struct os_mempool_info *); |
| |
| /* |
| * To calculate size of the memory buffer needed for the pool. NOTE: This size |
| * is NOT in bytes! The size is the number of os_membuf_t elements required for |
| * the memory pool. |
| */ |
| #if MYNEWT_VAL(OS_MEMPOOL_GUARD) |
| /* |
| * Leave extra 4 bytes of guard area at the end. |
| */ |
| #define OS_MEMPOOL_BLOCK_SZ(sz) ((sz) + sizeof(os_membuf_t)) |
| #else |
| #define OS_MEMPOOL_BLOCK_SZ(sz) (sz) |
| #endif |
| #if (OS_CFG_ALIGNMENT == OS_CFG_ALIGN_4) |
| #define OS_MEMPOOL_SIZE(n, blksize) \ |
| (((OS_MEMPOOL_BLOCK_SZ(blksize) + 3) / 4) * (n)) |
| typedef uint32_t os_membuf_t; |
| #else |
| #define OS_MEMPOOL_SIZE(n, blksize) \ |
| (((OS_MEMPOOL_BLOCK_SZ(blksize) + 7) / 8) * (n)) |
| typedef uint64_t os_membuf_t; |
| #endif |
| |
| /** Calculates the number of bytes required to initialize a memory pool. */ |
| #define OS_MEMPOOL_BYTES(n,blksize) \ |
| (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize))) |
| |
| /** |
| * Initialize a memory pool. |
| * |
| * @param mp Pointer to a pointer to a mempool |
| * @param blocks The number of blocks in the pool |
| * @param blocks_size The size of the block, in bytes. |
| * @param membuf Pointer to memory to contain blocks. |
| * @param name Name of the pool. |
| * |
| * @return os_error_t |
| */ |
| os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks, |
| uint32_t block_size, void *membuf, char *name); |
| |
| /** |
| * Initializes an extended memory pool. Extended attributes (e.g., callbacks) |
| * are not specified when this function is called; they are assigned manually |
| * after initialization. |
| * |
| * @param mpe The extended memory pool to initialize. |
| * @param blocks The number of blocks in the pool. |
| * @param block_size The size of each block, in bytes. |
| * @param membuf Pointer to memory to contain blocks. |
| * @param name Name of the pool. |
| * |
| * @return os_error_t |
| */ |
| os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks, |
| uint32_t block_size, void *membuf, char *name); |
| |
| /** |
| * Removes the specified mempool from the list of initialized mempools. |
| * |
| * @param mp The mempool to unregister. |
| * |
| * @return 0 on success; |
| * OS_INVALID_PARM if the mempool is not |
| * registered. |
| */ |
| os_error_t os_mempool_unregister(struct os_mempool *mp); |
| |
| /** |
| * Clears a memory pool. |
| * |
| * @param mp The mempool to clear. |
| * |
| * @return os_error_t |
| */ |
| os_error_t os_mempool_clear(struct os_mempool *mp); |
| |
| /** |
| * Performs an integrity check of the specified mempool. This function |
| * attempts to detect memory corruption in the specified memory pool. |
| * |
| * @param mp The mempool to check. |
| * |
| * @return true if the memory pool passes the integrity |
| * check; |
| * false if the memory pool is corrupt. |
| */ |
| bool os_mempool_is_sane(const struct os_mempool *mp); |
| |
| /** |
| * Checks if a memory block was allocated from the specified mempool. |
| * |
| * @param mp The mempool to check as parent. |
| * @param block_addr The memory block to check as child. |
| * |
| * @return 0 if the block does not belong to the mempool; |
| * 1 if the block does belong to the mempool. |
| */ |
| int os_memblock_from(const struct os_mempool *mp, const void *block_addr); |
| |
| /** |
| * Get a memory block from a memory pool |
| * |
| * @param mp Pointer to the memory pool |
| * |
| * @return void* Pointer to block if available; NULL otherwise |
| */ |
| void *os_memblock_get(struct os_mempool *mp); |
| |
| /** |
| * Puts the memory block back into the pool, ignoring the put callback, if any. |
| * This function should only be called from a put callback to free a block |
| * without causing infinite recursion. |
| * |
| * @param mp Pointer to memory pool |
| * @param block_addr Pointer to memory block |
| * |
| * @return os_error_t |
| */ |
| os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr); |
| |
| /** |
| * Puts the memory block back into the pool |
| * |
| * @param mp Pointer to memory pool |
| * @param block_addr Pointer to memory block |
| * |
| * @return os_error_t |
| */ |
| os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* _OS_MEMPOOL_H_ */ |
| |
| |
| /** |
| * @} OSMempool |
| * @} OSKernel |
| */ |