os_mempool.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. /*
  2. * SPDX-FileCopyrightText: 2015-2022 The Apache Software Foundation (ASF)
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * SPDX-FileContributor: 2019-2022 Espressif Systems (Shanghai) CO LTD
  7. */
  8. /*
  9. * Licensed to the Apache Software Foundation (ASF) under one
  10. * or more contributor license agreements. See the NOTICE file
  11. * distributed with this work for additional information
  12. * regarding copyright ownership. The ASF licenses this file
  13. * to you under the Apache License, Version 2.0 (the
  14. * "License"); you may not use this file except in compliance
  15. * with the License. You may obtain a copy of the License at
  16. *
  17. * http://www.apache.org/licenses/LICENSE-2.0
  18. *
  19. * Unless required by applicable law or agreed to in writing,
  20. * software distributed under the License is distributed on an
  21. * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  22. * KIND, either express or implied. See the License for the
  23. * specific language governing permissions and limitations
  24. * under the License.
  25. */
  26. /**
  27. * @addtogroup OSKernel
  28. * @{
  29. * @defgroup OSMempool Memory Pools
  30. * @{
  31. */
  32. #ifndef _OS_MEMPOOL_H_
  33. #define _OS_MEMPOOL_H_
  34. #include <stdbool.h>
  35. #include "os/os.h"
  36. #ifdef __cplusplus
  37. extern "C" {
  38. #endif
  39. /**
  40. * A memory block structure. This simply contains a pointer to the free list
  41. * chain and is only used when the block is on the free list. When the block
  42. * has been removed from the free list the entire memory block is usable by the
  43. * caller.
  44. */
  45. struct os_memblock {
  46. SLIST_ENTRY(os_memblock) mb_next;
  47. };
  48. /* XXX: Change this structure so that we keep the first address in the pool? */
  49. /* XXX: add memory debug structure and associated code */
  50. /* XXX: Change how I coded the SLIST_HEAD here. It should be named:
  51. SLIST_HEAD(,os_memblock) mp_head; */
  52. /**
  53. * Memory pool
  54. */
  55. struct os_mempool {
  56. /** Size of the memory blocks, in bytes. */
  57. uint32_t mp_block_size;
  58. /** The number of memory blocks. */
  59. uint16_t mp_num_blocks;
  60. /** The number of free blocks left */
  61. uint16_t mp_num_free;
  62. /** The lowest number of free blocks seen */
  63. uint16_t mp_min_free;
  64. /** Bitmap of OS_MEMPOOL_F_[...] values. */
  65. uint8_t mp_flags;
  66. /** Address of memory buffer used by pool */
  67. uint32_t mp_membuf_addr;
  68. STAILQ_ENTRY(os_mempool) mp_list;
  69. SLIST_HEAD(,os_memblock);
  70. /** Name for memory block */
  71. const char *name;
  72. };
  73. /**
  74. * Indicates an extended mempool. Address can be safely cast to
  75. * (struct os_mempool_ext *).
  76. */
  77. #define OS_MEMPOOL_F_EXT 0x01
  78. struct os_mempool_ext;
  79. /**
  80. * Block put callback function. If configured, this callback gets executed
  81. * whenever a block is freed to the corresponding extended mempool. Note: The
  82. * os_memblock_put() function calls this callback instead of freeing the block
  83. * itself. Therefore, it is the callback's responsibility to free the block
  84. * via a call to os_memblock_put_from_cb().
  85. *
  86. * @param ome The extended mempool that a block is being
  87. * freed back to.
  88. * @param data The block being freed.
  89. * @param arg Optional argument configured along with the
  90. * callback.
  91. *
  92. * @return Indicates whether the block was successfully
  93. * freed. A non-zero value should only be
  94. * returned if the block was not successfully
  95. * released back to its pool.
  96. */
  97. typedef os_error_t os_mempool_put_fn(struct os_mempool_ext *ome, void *data,
  98. void *arg);
  99. struct os_mempool_ext {
  100. struct os_mempool mpe_mp;
  101. /* Callback that is executed immediately when a block is freed. */
  102. os_mempool_put_fn *mpe_put_cb;
  103. void *mpe_put_arg;
  104. };
  105. #define OS_MEMPOOL_INFO_NAME_LEN (32)
  106. /**
  107. * Information describing a memory pool, used to return OS information
  108. * to the management layer.
  109. */
  110. struct os_mempool_info {
  111. /** Size of the memory blocks in the pool */
  112. int omi_block_size;
  113. /** Number of memory blocks in the pool */
  114. int omi_num_blocks;
  115. /** Number of free memory blocks */
  116. int omi_num_free;
  117. /** Minimum number of free memory blocks ever */
  118. int omi_min_free;
  119. /** Name of the memory pool */
  120. char omi_name[OS_MEMPOOL_INFO_NAME_LEN];
  121. };
  122. /**
  123. * Get information about the next system memory pool.
  124. *
  125. * @param mempool The current memory pool, or NULL if starting iteration.
  126. * @param info A pointer to the structure to return memory pool information
  127. * into.
  128. *
  129. * @return The next memory pool in the list to get information about, or NULL
  130. * when at the last memory pool.
  131. */
  132. struct os_mempool *os_mempool_info_get_next(struct os_mempool *,
  133. struct os_mempool_info *);
  134. #if (OS_ALIGNMENT == 4)
  135. typedef uint32_t os_membuf_t;
  136. #elif (OS_ALIGNMENT == 8)
  137. typedef uint64_t os_membuf_t;
  138. #elif (OS_ALIGNMENT == 16)
  139. typedef __uint128_t os_membuf_t;
  140. #else
  141. #error "Unhandled `OS_ALIGNMENT` for `os_membuf_t`"
  142. #endif /* OS_ALIGNMENT == * */
  143. #define OS_MEMPOOL_SIZE(n,blksize) ((((blksize) + ((OS_ALIGNMENT)-1)) / (OS_ALIGNMENT)) * (n))
  144. /** Calculates the number of bytes required to initialize a memory pool. */
  145. #define OS_MEMPOOL_BYTES(n,blksize) \
  146. (sizeof (os_membuf_t) * OS_MEMPOOL_SIZE((n), (blksize)))
  147. #if SOC_ESP_NIMBLE_CONTROLLER
  148. /**
  149. * Initialize a memory pool.
  150. *
  151. * @param mp Pointer to a pointer to a mempool
  152. * @param blocks The number of blocks in the pool
  153. * @param blocks_size The size of the block, in bytes.
  154. * @param membuf Pointer to memory to contain blocks.
  155. * @param name Name of the pool.
  156. *
  157. * @return os_error_t
  158. */
  159. os_error_t r_os_mempool_init(struct os_mempool *mp, uint16_t blocks,
  160. uint32_t block_size, void *membuf, const char *name);
  161. #define os_mempool_init r_os_mempool_init
  162. /**
  163. * Initializes an extended memory pool. Extended attributes (e.g., callbacks)
  164. * are not specified when this function is called; they are assigned manually
  165. * after initialization.
  166. *
  167. * @param mpe The extended memory pool to initialize.
  168. * @param blocks The number of blocks in the pool.
  169. * @param block_size The size of each block, in bytes.
  170. * @param membuf Pointer to memory to contain blocks.
  171. * @param name Name of the pool.
  172. *
  173. * @return os_error_t
  174. */
  175. os_error_t r_os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
  176. uint32_t block_size, void *membuf, const char *name);
  177. #define os_mempool_ext_init r_os_mempool_ext_init
  178. /**
  179. * Removes the specified mempool from the list of initialized mempools.
  180. *
  181. * @param mp The mempool to unregister.
  182. *
  183. * @return 0 on success;
  184. * OS_INVALID_PARM if the mempool is not
  185. * registered.
  186. */
  187. os_error_t r_os_mempool_unregister(struct os_mempool *mp);
  188. #define os_mempool_unregister r_os_mempool_unregister
  189. /**
  190. * Clears a memory pool.
  191. *
  192. * @param mp The mempool to clear.
  193. *
  194. * @return os_error_t
  195. */
  196. os_error_t r_os_mempool_clear(struct os_mempool *mp);
  197. #define os_mempool_clear r_os_mempool_clear
  198. /**
  199. * Performs an integrity check of the specified mempool. This function
  200. * attempts to detect memory corruption in the specified memory pool.
  201. *
  202. * @param mp The mempool to check.
  203. *
  204. * @return true if the memory pool passes the integrity
  205. * check;
  206. * false if the memory pool is corrupt.
  207. */
  208. bool r_os_mempool_is_sane(const struct os_mempool *mp);
  209. #define os_mempool_is_sane r_os_mempool_is_sane
  210. /**
  211. * Checks if a memory block was allocated from the specified mempool.
  212. *
  213. * @param mp The mempool to check as parent.
  214. * @param block_addr The memory block to check as child.
  215. *
  216. * @return 0 if the block does not belong to the mempool;
  217. * 1 if the block does belong to the mempool.
  218. */
  219. int r_os_memblock_from(const struct os_mempool *mp, const void *block_addr);
  220. #define os_memblock_from r_os_memblock_from
  221. /**
  222. * Get a memory block from a memory pool
  223. *
  224. * @param mp Pointer to the memory pool
  225. *
  226. * @return void* Pointer to block if available; NULL otherwise
  227. */
  228. void *r_os_memblock_get(struct os_mempool *mp);
  229. #define os_memblock_get r_os_memblock_get
  230. /**
  231. * Puts the memory block back into the pool, ignoring the put callback, if any.
  232. * This function should only be called from a put callback to free a block
  233. * without causing infinite recursion.
  234. *
  235. * @param mp Pointer to memory pool
  236. * @param block_addr Pointer to memory block
  237. *
  238. * @return os_error_t
  239. */
  240. os_error_t r_os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr);
  241. #define os_memblock_put_from_cb r_os_memblock_put_from_cb
  242. /**
  243. * Puts the memory block back into the pool
  244. *
  245. * @param mp Pointer to memory pool
  246. * @param block_addr Pointer to memory block
  247. *
  248. * @return os_error_t
  249. */
  250. os_error_t r_os_memblock_put(struct os_mempool *mp, void *block_addr);
  251. #define os_memblock_put r_os_memblock_put
  252. #else
  253. /**
  254. * Initialize a memory pool.
  255. *
  256. * @param mp Pointer to a pointer to a mempool
  257. * @param blocks The number of blocks in the pool
  258. * @param blocks_size The size of the block, in bytes.
  259. * @param membuf Pointer to memory to contain blocks.
  260. * @param name Name of the pool.
  261. *
  262. * @return os_error_t
  263. */
  264. os_error_t os_mempool_init(struct os_mempool *mp, uint16_t blocks,
  265. uint32_t block_size, void *membuf, const char *name);
  266. /**
  267. * Initializes an extended memory pool. Extended attributes (e.g., callbacks)
  268. * are not specified when this function is called; they are assigned manually
  269. * after initialization.
  270. *
  271. * @param mpe The extended memory pool to initialize.
  272. * @param blocks The number of blocks in the pool.
  273. * @param block_size The size of each block, in bytes.
  274. * @param membuf Pointer to memory to contain blocks.
  275. * @param name Name of the pool.
  276. *
  277. * @return os_error_t
  278. */
  279. os_error_t os_mempool_ext_init(struct os_mempool_ext *mpe, uint16_t blocks,
  280. uint32_t block_size, void *membuf, const char *name);
  281. /**
  282. * Removes the specified mempool from the list of initialized mempools.
  283. *
  284. * @param mp The mempool to unregister.
  285. *
  286. * @return 0 on success;
  287. * OS_INVALID_PARM if the mempool is not
  288. * registered.
  289. */
  290. os_error_t os_mempool_unregister(struct os_mempool *mp);
  291. /**
  292. * Clears a memory pool.
  293. *
  294. * @param mp The mempool to clear.
  295. *
  296. * @return os_error_t
  297. */
  298. os_error_t os_mempool_clear(struct os_mempool *mp);
  299. /**
  300. * Clears an extended memory pool.
  301. *
  302. * @param mpe The extended memory pool to clear.
  303. *
  304. * @return os_error_t
  305. */
  306. os_error_t os_mempool_ext_clear(struct os_mempool_ext *mpe);
  307. /**
  308. * Performs an integrity check of the specified mempool. This function
  309. * attempts to detect memory corruption in the specified memory pool.
  310. *
  311. * @param mp The mempool to check.
  312. *
  313. * @return true if the memory pool passes the integrity
  314. * check;
  315. * false if the memory pool is corrupt.
  316. */
  317. bool os_mempool_is_sane(const struct os_mempool *mp);
  318. /**
  319. * Checks if a memory block was allocated from the specified mempool.
  320. *
  321. * @param mp The mempool to check as parent.
  322. * @param block_addr The memory block to check as child.
  323. *
  324. * @return 0 if the block does not belong to the mempool;
  325. * 1 if the block does belong to the mempool.
  326. */
  327. int os_memblock_from(const struct os_mempool *mp, const void *block_addr);
  328. /**
  329. * Get a memory block from a memory pool
  330. *
  331. * @param mp Pointer to the memory pool
  332. *
  333. * @return void* Pointer to block if available; NULL otherwise
  334. */
  335. void *os_memblock_get(struct os_mempool *mp);
  336. /**
  337. * Puts the memory block back into the pool, ignoring the put callback, if any.
  338. * This function should only be called from a put callback to free a block
  339. * without causing infinite recursion.
  340. *
  341. * @param mp Pointer to memory pool
  342. * @param block_addr Pointer to memory block
  343. *
  344. * @return os_error_t
  345. */
  346. os_error_t os_memblock_put_from_cb(struct os_mempool *mp, void *block_addr);
  347. /**
  348. * Puts the memory block back into the pool
  349. *
  350. * @param mp Pointer to memory pool
  351. * @param block_addr Pointer to memory block
  352. *
  353. * @return os_error_t
  354. */
  355. os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr);
  356. #endif
  357. #ifdef __cplusplus
  358. }
  359. #endif
  360. #endif /* _OS_MEMPOOL_H_ */
  361. /**
  362. * @} OSMempool
  363. * @} OSKernel
  364. */