osi_mem.h 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /* Copyright (C) 2018 RDA Technologies Limited and/or its affiliates("RDA").
  2. * All rights reserved.
  3. *
  4. * This software is supplied "AS IS" without any warranties.
  5. * RDA assumes no responsibility or liability for the use of the software,
  6. * conveys no license or title under any patent, copyright, or mask work
  7. * right to the product. RDA reserves the right to make changes in the
  8. * software without notification. RDA also make no representation or
  9. * warranty that such application will be suitable for the specified use
  10. * without further testing or modification.
  11. */
  12. #ifndef __OSI_MEM_H__
  13. #define __OSI_MEM_H__
  14. #include "kernel_config.h"
  15. #include <stdint.h>
  16. #include <stdbool.h>
  17. #include <stdlib.h>
  18. #ifdef __cplusplus
  19. extern "C" {
  20. #endif
  21. /**
  22. * opaque data structure for memory pool
  23. */
  24. typedef struct osiMemPool osiMemPool_t;
  25. /**
  26. * memory pool information
  27. */
  28. typedef struct
  29. {
  30. void *start; ///< memory pool start pointer
  31. uint32_t size; ///< memory pool total size
  32. uint32_t index; ///< memory pool internal index
  33. uint32_t avail_size; ///< available size. The actual allocatable size may be less than this
  34. uint32_t max_block_size; ///< maximum allocatable block size
  35. } osiMemPoolStat_t;
  36. /**
  37. * memory allocate/free record
  38. */
  39. typedef struct
  40. {
  41. uintptr_t caller; ///< [31] 1: allocate, 0: free, [30:0] caller address[31:1]
  42. uintptr_t ptr; ///< address
  43. } osiMemRecord_t;
  44. /**
  45. * memory block information for error scan
  46. */
  47. typedef struct
  48. {
  49. uintptr_t address; ///< usable address
  50. uintptr_t caller; ///< caller address
  51. unsigned flags; ///< error flags
  52. } osiMemErrorBlock_t;
  53. typedef struct
  54. {
  55. uint32_t num_allocs; ///< allocs number
  56. uint32_t num_frees; ///< frees number
  57. } osiMemStatistics_t;
  58. /**
  59. * initialize a fixed pool
  60. *
  61. * Initialize and register a fixed size block pool. The pool management data
  62. * structure will be located inside the provided memory, Due to alignment
  63. * it may exist an offset.
  64. *
  65. * @note Due to there are management overhead, the available block count is
  66. * not `pool_size/block_size`.
  67. *
  68. * @param ptr starting pointer of the memory
  69. * @param size memory total size
  70. * @param block_size block size
  71. * @return
  72. * - the pool pointer on success
  73. * - NULL on failure
  74. */
  75. osiMemPool_t *osiFixedPoolInit(void *ptr, size_t size, size_t block_size);
  76. /**
  77. * initialize a block pool
  78. *
  79. * Initialize and register a block pool pool. The variadic parameters should
  80. * be ended with a zero. Each pair of (size_t count, size_t size) indicates
  81. * to create a fixed pool child for the block pool. When allocating from
  82. * the block pool, fixed pool children will be checked automatically. It
  83. * may be helpful to reduce memory fragmentation.
  84. *
  85. * The management data structure of block pool and all children will be
  86. * located inside the provided memory.
  87. *
  88. * @note The feature of fixed block pool inside is experimental.
  89. *
  90. * @param ptr starting pointer of the memory pool.
  91. * @param size memory pool size
  92. * @return
  93. * - the pool pointer on success
  94. * - NULL on failure
  95. */
  96. osiMemPool_t *osiBlockPoolInit(void *ptr, size_t size, ...);
  97. /**
  98. * set the default pool
  99. *
  100. * Default pool will be used by malloc/calloc, and it must be block pool.
  101. * The first created block pool will be set to default automatically.
  102. * And this API will change default pool.
  103. *
  104. * When \p pool is NULL or invalid, it will return silently.
  105. *
  106. * @param pool pool to be set as default.
  107. */
  108. void osiPoolSetDefault(osiMemPool_t *pool);
  109. /**
  110. * allocate from specified pool
  111. *
  112. * When \p pool is NULL or invalid, or \p size is zero, NULL will be
  113. * returned.
  114. *
  115. * Refer to malloc(3).
  116. *
  117. * @param pool the pool
  118. * @param size size to be allocated
  119. * @return
  120. * - allocated memory pointer on success
  121. * - NULL at failure
  122. */
  123. void *osiPoolMalloc(osiMemPool_t *pool, size_t size);
  124. /**
  125. * allocate from specified pool, which is unlikely to be freed
  126. *
  127. * Comparing to \p osiPoolMalloc, allocator will try to allocate
  128. * from location with less fragmentation impact.
  129. *
  130. * Usually, it only be called at system initialization. It is a replacement
  131. * of global variable (either DATA or BSS).
  132. *
  133. * @param pool the pool
  134. * @param size size to be allocated
  135. * @return
  136. * - allocated memory pointer on success
  137. * - NULL at failure
  138. */
  139. void *osiPoolMallocUnlikelyFree(osiMemPool_t *pool, size_t size);
  140. /**
  141. * allocate from specified pool, and clear to zero
  142. *
  143. * It is the exact same as `osiPoolMalloc(pool, nmemb*size)` and clear
  144. * memory to zero.
  145. *
  146. * Refer to calloc(3).
  147. *
  148. * @param pool the pool.
  149. * @param nmemb member count to be allocated.
  150. * @param size size of each member.
  151. * @return
  152. * - allocated memory pointer on success
  153. * - NULL at failure
  154. */
  155. void *osiPoolCalloc(osiMemPool_t *pool, size_t nmemb, size_t size);
  156. /**
  157. * change size of memory block
  158. *
  159. * Refer to realloc(3).
  160. *
  161. * @param pool the pool.
  162. * @param ptr pointer to be changed.
  163. * @param size changed size.
  164. * @return
  165. * - allocated memory pointer on success
  166. * - NULL at failure
  167. */
  168. void *osiPoolRealloc(osiMemPool_t *pool, void *ptr, size_t size);
  169. /**
  170. * allocate from specified pool with specified alignment
  171. *
  172. * The pool must be block pool.
  173. *
  174. * \p alignment should be power of 2. When \p alignment is less than
  175. * default alignment, it will behavior the same as `osiPoolMalloc`.
  176. *
  177. * Refer to memalign(3).
  178. *
  179. * @param[in] pool The pool
  180. * @param[in] alignment Requested alignment
  181. * @param[in] size Size to be allocated
  182. * @return
  183. * - allocated memory pointer on success
  184. * - NULL at failure
  185. */
  186. void *osiPoolMemalign(osiMemPool_t *pool, size_t alignment, size_t size);
  187. /**
  188. * set memory block caller address
  189. *
  190. * Caller address is for debug only. And won't affect behavior. All APIs
  191. * in this module will set caller automatically. Only for memory management
  192. * wrappers, and it is wanted to set caller to the caller of wrapper,
  193. * this function may be called.
  194. *
  195. * @param ptr pointer of memory block.
  196. * @param caller caller address
  197. */
  198. void osiMemSetCaller(void *ptr, void *caller);
  199. /**
  200. * get the allocated size for the pointer
  201. *
  202. * The size is allocated by memory management. The size may be larger than
  203. * the size requested, due to tail padding.
  204. *
  205. * @param ptr pointer of memory block
  206. * @return
  207. * - allocated memory block size
  208. * - 0 if \p ptr is NULL
  209. * - -1 if \p ptr is invalid
  210. */
  211. int osiMemAllocSize(void *ptr);
  212. /**
  213. * increase reference count of the pointer
  214. *
  215. * When the reference count reach the maximum allowed reference count,
  216. * system will panic.
  217. *
  218. * When \p ptr is NULL, nothing will be done.
  219. *
  220. * @param ptr pointer of memory block
  221. */
  222. void osiMemRef(void *ptr);
  223. /**
  224. * get reference count of the pointer
  225. *
  226. * When \p ptr is NULL, 0 will be returned.
  227. *
  228. * @param ptr pointer of memory block
  229. * @return reference count of the pointer
  230. */
  231. size_t osiMemRefCount(void *ptr);
  232. /**
  233. * decrease reference if the reference count is not 1
  234. *
  235. * At object oriented design with refrence count, it is not enough to
  236. * consider memory reference count only. Rather, it is needed to
  237. * consider the object reference count. So, the *delete* function of
  238. * object should be:
  239. *
  240. * \code{.cpp}
  241. * void objectDelete(void *object)
  242. * {
  243. * if (osiMemUnrefNotLast(object))
  244. * return;
  245. *
  246. * objectCleanup(object);
  247. * free(object);
  248. * }
  249. * \endcode
  250. *
  251. * When the reference count of the object, which is stored inside memory
  252. * management, is not 1, only decrease the reference count. Only when
  253. * it is the last reference, the cleanup shall be called.
  254. *
  255. * When \p ptr is NULL, it will return true, and do nothing. Conceptually,
  256. * NULL pointer can be regarded as reference count of 0. So, it is not
  257. * the last reference.
  258. *
  259. * When reference count of \p ptr is greater than 1, the reference count
  260. * will be decreased by 1, and it is the same as \p free.
  261. *
  262. * @param ptr pointer of memory block
  263. * @return
  264. * - true if it is not the last reference, or \p ptr is NULL
  265. * - false if it is the last reference
  266. */
  267. bool osiMemUnrefNotLast(void *ptr);
  268. /**
  269. * refer to malloc(3).
  270. */
  271. void *osiMalloc(size_t size);
  272. /**
  273. * refer to calloc(3).
  274. */
  275. void *osiCalloc(size_t nmemb, size_t size);
  276. /**
  277. * refer to realloc(3).
  278. */
  279. void *osiRealloc(void *ptr, size_t size);
  280. /**
  281. * refer to memalign(3).
  282. */
  283. void *osiMemalign(size_t alignment, size_t size);
  284. /**
  285. * refer to free(3).
  286. */
  287. void osiFree(void *ptr);
  288. /**
  289. * get memory pool information
  290. *
  291. * \p max_block_size is the maximum allocatable size. \p realloc and
  292. * \p memalign will use more extra spaces, they may fail with that size.
  293. *
  294. * \code{.cpp}
  295. * malloc(stat->max_block_size); // will success
  296. * realloc(ptr, stat->max_block_size); // may fail
  297. * memalign(32, stat->max_block_size); // may fail
  298. * \endcode
  299. *
  300. * @param pool the memory pool. \p NULL for default memory pool
  301. * @param stat output memory pool information
  302. * @return
  303. * - true on success
  304. * - false if there are no memory pool, or \p stat is NULL
  305. */
  306. bool osiMemPoolStat(osiMemPool_t *pool, osiMemPoolStat_t *stat);
  307. /**
  308. * scan all heaps for memory block error
  309. *
  310. * This should only be called after system enter blue screen.
  311. *
  312. * \param blocks output memory block error information
  313. * \param count maximum error block count
  314. * \return
  315. * - memory block error count
  316. */
  317. int osiMemScanError(osiMemErrorBlock_t *blocks, unsigned count);
  318. /**
  319. * get last memory allocate/free records
  320. *
  321. * \param records output memory allocate/free record
  322. * \param count maximum record count
  323. * \return
  324. * - memory allocate/free record count
  325. */
  326. int osiMemRecordGetLast(osiMemRecord_t *records, unsigned count);
  327. #ifdef CONFIG_KERNEL_MEM_STATISTICS_SUPPORT
  328. /**
  329. * get the count of alloc and free.
  330. *
  331. * \param Statistics output memory allocate/free count
  332. * \return
  333. */
  334. void osiMemStatistic(osiMemStatistics_t *statistics);
  335. #endif
  336. #ifdef __cplusplus
  337. }
  338. #endif
  339. #endif