123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
- * All rights reserved.
- *
- * This software is supplied "AS IS" without any warranties.
- * RDA assumes no responsibility or liability for the use of the software,
- * conveys no license or title under any patent, copyright, or mask work
- * right to the product. RDA reserves the right to make changes in the
- * software without notification. RDA also make no representation or
- * warranty that such application will be suitable for the specified use
- * without further testing or modification.
- */
- #ifndef __OSI_MEM_H__
- #define __OSI_MEM_H__
- #include "kernel_config.h"
- #include <stdint.h>
- #include <stdbool.h>
- #include <stdlib.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- /**
- * opaque data structure for memory pool
- */
- typedef struct osiMemPool osiMemPool_t;
- /**
- * memory pool information
- */
- typedef struct
- {
- void *start; ///< memory pool start pointer
- uint32_t size; ///< memory pool total size
- uint32_t index; ///< memory pool internal index
- uint32_t avail_size; ///< available size. The actual allocatable size may be less than this
- uint32_t max_block_size; ///< maximum allocatable block size
- } osiMemPoolStat_t;
- /**
- * memory allocate/free record
- */
- typedef struct
- {
- uintptr_t caller; ///< [31] 1: allocate, 0: free, [30:0] caller address[31:1]
- uintptr_t ptr; ///< address
- } osiMemRecord_t;
- /**
- * memory block information for error scan
- */
- typedef struct
- {
- uintptr_t address; ///< usable address
- uintptr_t caller; ///< caller address
- unsigned flags; ///< error flags
- } osiMemErrorBlock_t;
- typedef struct
- {
- uint32_t num_allocs; ///< allocs number
- uint32_t num_frees; ///< frees number
- } osiMemStatistics_t;
- /**
- * initialize a fixed pool
- *
- * Initialize and register a fixed size block pool. The pool management data
- * structure will be located inside the provided memory, Due to alignment
- * it may exist an offset.
- *
- * @note Due to there are management overhead, the available block count is
- * not `pool_size/block_size`.
- *
- * @param ptr starting pointer of the memory
- * @param size memory total size
- * @param block_size block size
- * @return
- * - the pool pointer on success
- * - NULL on failure
- */
- osiMemPool_t *osiFixedPoolInit(void *ptr, size_t size, size_t block_size);
- /**
- * initialize a block pool
- *
- * Initialize and register a block pool pool. The variadic parameters should
- * be ended with a zero. Each pair of (size_t count, size_t size) indicates
- * to create a fixed pool child for the block pool. When allocating from
- * the block pool, fixed pool children will be checked automatically. It
- * may be helpful to reduce memory fragmentation.
- *
- * The management data structure of block pool and all children will be
- * located inside the provided memory.
- *
- * @note The feature of fixed block pool inside is experimental.
- *
- * @param ptr starting pointer of the memory pool.
- * @param size memory pool size
- * @return
- * - the pool pointer on success
- * - NULL on failure
- */
- osiMemPool_t *osiBlockPoolInit(void *ptr, size_t size, ...);
- /**
- * set the default pool
- *
- * Default pool will be used by malloc/calloc, and it must be block pool.
- * The first created block pool will be set to default automatically.
- * And this API will change default pool.
- *
- * When \p pool is NULL or invalid, it will return silently.
- *
- * @param pool pool to be set as default.
- */
- void osiPoolSetDefault(osiMemPool_t *pool);
- /**
- * allocate from specified pool
- *
- * When \p pool is NULL or invalid, or \p size is zero, NULL will be
- * returned.
- *
- * Refer to malloc(3).
- *
- * @param pool the pool
- * @param size size to be allocated
- * @return
- * - allocated memory pointer on success
- * - NULL at failure
- */
- void *osiPoolMalloc(osiMemPool_t *pool, size_t size);
- /**
- * allocate from specified pool, which is unlikely to be freed
- *
- * Comparing to \p osiPoolMalloc, allocator will try to allocate
- * from location with less fragmentation impact.
- *
- * Usually, it only be called at system initialization. It is a replacement
- * of global variable (either DATA or BSS).
- *
- * @param pool the pool
- * @param size size to be allocated
- * @return
- * - allocated memory pointer on success
- * - NULL at failure
- */
- void *osiPoolMallocUnlikelyFree(osiMemPool_t *pool, size_t size);
- /**
- * allocate from specified pool, and clear to zero
- *
- * It is the exact same as `osiPoolMalloc(pool, nmemb*size)` and clear
- * memory to zero.
- *
- * Refer to calloc(3).
- *
- * @param pool the pool.
- * @param nmemb member count to be allocated.
- * @param size size of each member.
- * @return
- * - allocated memory pointer on success
- * - NULL at failure
- */
- void *osiPoolCalloc(osiMemPool_t *pool, size_t nmemb, size_t size);
- /**
- * change size of memory block
- *
- * Refer to realloc(3).
- *
- * @param pool the pool.
- * @param ptr pointer to be changed.
- * @param size changed size.
- * @return
- * - allocated memory pointer on success
- * - NULL at failure
- */
- void *osiPoolRealloc(osiMemPool_t *pool, void *ptr, size_t size);
- /**
- * allocate from specified pool with specified alignment
- *
- * The pool must be block pool.
- *
- * \p alignment should be power of 2. When \p alignment is less than
- * default alignment, it will behavior the same as `osiPoolMalloc`.
- *
- * Refer to memalign(3).
- *
- * @param[in] pool The pool
- * @param[in] alignment Requested alignment
- * @param[in] size Size to be allocated
- * @return
- * - allocated memory pointer on success
- * - NULL at failure
- */
- void *osiPoolMemalign(osiMemPool_t *pool, size_t alignment, size_t size);
- /**
- * set memory block caller address
- *
- * Caller address is for debug only. And won't affect behavior. All APIs
- * in this module will set caller automatically. Only for memory management
- * wrappers, and it is wanted to set caller to the caller of wrapper,
- * this function may be called.
- *
- * @param ptr pointer of memory block.
- * @param caller caller address
- */
- void osiMemSetCaller(void *ptr, void *caller);
- /**
- * get the allocated size for the pointer
- *
- * The size is allocated by memory management. The size may be larger than
- * the size requested, due to tail padding.
- *
- * @param ptr pointer of memory block
- * @return
- * - allocated memory block size
- * - 0 if \p ptr is NULL
- * - -1 if \p ptr is invalid
- */
- int osiMemAllocSize(void *ptr);
- /**
- * increase reference count of the pointer
- *
- * When the reference count reach the maximum allowed reference count,
- * system will panic.
- *
- * When \p ptr is NULL, nothing will be done.
- *
- * @param ptr pointer of memory block
- */
- void osiMemRef(void *ptr);
- /**
- * get reference count of the pointer
- *
- * When \p ptr is NULL, 0 will be returned.
- *
- * @param ptr pointer of memory block
- * @return reference count of the pointer
- */
- size_t osiMemRefCount(void *ptr);
- /**
- * decrease reference if the reference count is not 1
- *
- * At object oriented design with refrence count, it is not enough to
- * consider memory reference count only. Rather, it is needed to
- * consider the object reference count. So, the *delete* function of
- * object should be:
- *
- * \code{.cpp}
- * void objectDelete(void *object)
- * {
- * if (osiMemUnrefNotLast(object))
- * return;
- *
- * objectCleanup(object);
- * free(object);
- * }
- * \endcode
- *
- * When the reference count of the object, which is stored inside memory
- * management, is not 1, only decrease the reference count. Only when
- * it is the last reference, the cleanup shall be called.
- *
- * When \p ptr is NULL, it will return true, and do nothing. Conceptually,
- * NULL pointer can be regarded as reference count of 0. So, it is not
- * the last reference.
- *
- * When reference count of \p ptr is greater than 1, the reference count
- * will be decreased by 1, and it is the same as \p free.
- *
- * @param ptr pointer of memory block
- * @return
- * - true if it is not the last reference, or \p ptr is NULL
- * - false if it is the last reference
- */
- bool osiMemUnrefNotLast(void *ptr);
- /**
- * refer to malloc(3).
- */
- void *osiMalloc(size_t size);
- /**
- * refer to calloc(3).
- */
- void *osiCalloc(size_t nmemb, size_t size);
- /**
- * refer to realloc(3).
- */
- void *osiRealloc(void *ptr, size_t size);
- /**
- * refer to memalign(3).
- */
- void *osiMemalign(size_t alignment, size_t size);
- /**
- * refer to free(3).
- */
- void osiFree(void *ptr);
- /**
- * get memory pool information
- *
- * \p max_block_size is the maximum allocatable size. \p realloc and
- * \p memalign will use more extra spaces, they may fail with that size.
- *
- * \code{.cpp}
- * malloc(stat->max_block_size); // will success
- * realloc(ptr, stat->max_block_size); // may fail
- * memalign(32, stat->max_block_size); // may fail
- * \endcode
- *
- * @param pool the memory pool. \p NULL for default memory pool
- * @param stat output memory pool information
- * @return
- * - true on success
- * - false if there are no memory pool, or \p stat is NULL
- */
- bool osiMemPoolStat(osiMemPool_t *pool, osiMemPoolStat_t *stat);
- /**
- * scan all heaps for memory block error
- *
- * This should only be called after system enter blue screen.
- *
- * \param blocks output memory block error information
- * \param count maximum error block count
- * \return
- * - memory block error count
- */
- int osiMemScanError(osiMemErrorBlock_t *blocks, unsigned count);
- /**
- * get last memory allocate/free records
- *
- * \param records output memory allocate/free record
- * \param count maximum record count
- * \return
- * - memory allocate/free record count
- */
- int osiMemRecordGetLast(osiMemRecord_t *records, unsigned count);
- #ifdef CONFIG_KERNEL_MEM_STATISTICS_SUPPORT
- /**
- * get the count of alloc and free.
- *
- * \param Statistics output memory allocate/free count
- * \return
- */
- void osiMemStatistic(osiMemStatistics_t *statistics);
- #endif
- #ifdef __cplusplus
- }
- #endif
- #endif
|