• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3  * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without modification,
6  * are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice, this list of
9  *    conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12  *    of conditions and the following disclaimer in the documentation and/or other materials
13  *    provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16  *    to endorse or promote products derived from this software without specific prior written
17  *    permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /**
33  * @defgroup los_memory  Dynamic memory
34  * @ingroup kernel
35  */
36 
37 #ifndef _LOS_MEMORY_H
38 #define _LOS_MEMORY_H
39 
40 #include "los_config.h"
41 #include "los_list.h"
42 #include "los_debug.h"
43 
44 #ifdef __cplusplus
45 #if __cplusplus
46 extern "C" {
47 #endif /* __cplusplus */
48 #endif /* __cplusplus */
49 
50 #if (LOSCFG_PLATFORM_EXC == 1)
51 UINT32 OsMemExcInfoGet(UINT32 memNumMax, MemInfoCB *memExcInfo);
52 #endif
53 
54 /**
55  * @ingroup los_memory
56  * Starting address of the memory.
57  */
58 #define OS_SYS_MEM_ADDR     LOSCFG_SYS_HEAP_ADDR
59 
60 #if (LOSCFG_MEM_LEAKCHECK == 1)
61 /**
62  * @ingroup los_memory
63  * @brief Print function call stack information of all used nodes.
64  *
65  * @par Description:
66  * <ul>
67  * <li>This API is used to print function call stack information of all used nodes.</li>
68  * </ul>
69  *
70  * @param pool          [IN] Starting address of memory.
71  *
72  * @retval none.
73  * @par Dependency:
74  * <ul>
75  * <li>los_memory.h: the header file that contains the API declaration.</li>
76  * </ul>
77  * @see None.
78  */
79 extern VOID LOS_MemUsedNodeShow(VOID *pool);
80 #endif
81 
82 #if (LOSCFG_MEM_MUL_POOL == 1)
83 /**
84  * @ingroup los_memory
85  * @brief Deinitialize dynamic memory.
86  *
87  * @par Description:
88  * <ul>
89  * <li>This API is used to deinitialize the dynamic memory of a doubly linked list.</li>
90  * </ul>
91  *
92  * @param pool          [IN] Starting address of memory.
93  *
94  * @retval #OS_ERROR   The dynamic memory fails to be deinitialized.
95  * @retval #LOS_OK     The dynamic memory is successfully deinitialized.
96  * @par Dependency:
97  * <ul>
98  * <li>los_memory.h: the header file that contains the API declaration.</li>
99  * </ul>
100  * @see None.
101  */
102 extern UINT32 LOS_MemDeInit(VOID *pool);
103 
104 /**
105  * @ingroup los_memory
106  * @brief Print information about all pools.
107  *
108  * @par Description:
109  * <ul>
110  * <li>This API is used to print information about all pools.</li>
111  * </ul>
112  *
113  * @retval #UINT32   The pool number.
114  * @par Dependency:
115  * <ul>
116  * <li>los_memory.h: the header file that contains the API declaration.</li>
117  * </ul>
118  * @see None.
119  */
120 extern UINT32 LOS_MemPoolList(VOID);
121 #endif
122 
123 #if (LOSCFG_MEM_FREE_BY_TASKID == 1)
124 /**
125  * @ingroup los_memory
126  * @brief Free memory nodes allocated by the specified task.
127  *
128  * @par Description:
129  * <ul>
130  * <li>This API is used to free all memory nodes allocated by the specified task.</li>
131  * </ul>
132  *
133  * @param pool           [IN] The memory pool address.
134  * @param taskID         [IN] The task ID and all memory nodes allocated by this task will be freed.
135  *
136  * @retval #OS_ERROR     The memory pool is NULL or the task ID is invalid.
137  * @retval #LOS_OK       All memory nodes allocated by this task are freed successfully.
138  * @par Dependency:
139  * <ul>
140  * <li>los_memory.h: the header file that contains the API declaration.</li>
141  * </ul>
142  * @see None.
143  */
144 extern UINT32 LOS_MemFreeByTaskID(VOID *pool, UINT32 taskID);
145 #endif
146 
147 #if (LOSCFG_MEM_MUL_REGIONS == 1)
148 typedef struct {
149     VOID *startAddress;
150     UINT32 length;
151 } LosMemRegion;
152 
153 /**
154  * @ingroup los_memory
155  * @brief Initialize multiple non-continuous memory regions.
156  *
157  * @par Description:
158  * <ul>
159  * <li>This API is used to initialize multiple non-continuous memory regions. If the starting address of a pool is
160  *  specified, the memory regions will be linked to the pool as free nodes. Otherwise, the first memory region will
161  *  be initialized as a *  new pool, and the rest regions will be linked as free nodes to the new pool.</li>
162  * </ul>
163  *
164  * @attention
165  * <ul>
166  * <li>If the starting address of a memory pool is specified, the start address of the non-continuous memory regions should be
167  *  greater than the end address of the memory pool.</li>
168  * <li>The multiple non-continuous memory regions shouldn't conflict with each other.</li>
169  * </ul>
170  *
171  * @param pool           [IN] The memory pool address. If NULL is specified, the start address of first memory region will be
172  *                            initialized as the memory pool address. If not NULL, it should be a valid address of a memory pool.
173  * @param memRegions     [IN] The LosMemRegion array that contains multiple non-continuous memory regions. The start address
174  *                           of the memory regions are placed in ascending order.
175  * @param memRegionCount [IN] The count of non-continuous memory regions, and it should be the length of the LosMemRegion array.
176  *
177  * @retval #LOS_NOK    The multiple non-continuous memory regions fails to be initialized.
178  * @retval #LOS_OK     The multiple non-continuous memory regions is initialized successfully.
179  * @par Dependency:
180  * <ul>
181  * <li>los_memory.h: the header file that contains the API declaration.</li>
182  * </ul>
183  * @see None.
184  */
185 extern UINT32 LOS_MemRegionsAdd(VOID *pool, const LosMemRegion * const memRegions, UINT32 memRegionCount);
186 #endif
187 
188 /**
189  * @ingroup los_memory
190  * Memory pool extern information structure
191  */
192 typedef struct {
193     UINT32 totalUsedSize;
194     UINT32 totalFreeSize;
195     UINT32 maxFreeNodeSize;
196     UINT32 usedNodeNum;
197     UINT32 freeNodeNum;
198 #if (LOSCFG_MEM_WATERLINE == 1)
199     UINT32 usageWaterLine;
200 #endif
201 } LOS_MEM_POOL_STATUS;
202 
203 /**
204  * @ingroup los_memory
205  * @brief Initialize dynamic memory.
206  *
207  * @par Description:
208  * <ul>
209  * <li>This API is used to initialize the dynamic memory of a doubly linked list.</li>
210  * </ul>
211  * @attention
212  * <ul>
213  * <li>The size parameter value should match the following two conditions :
214  * 1) Be less than or equal to the Memory pool size;
215  * 2) Be greater than the size of OS_MEM_MIN_POOL_SIZE.</li>
216  * <li>Call this API when dynamic memory needs to be initialized during the startup of Huawei LiteOS.</li>
217  * <li>The parameter input must be four byte-aligned.</li>
218  * <li>The init area [pool, pool + size] should not conflict with other pools.</li>
219  * </ul>
220  *
221  * @param pool         [IN] Starting address of memory.
222  * @param size         [IN] Memory size.
223  *
224  * @retval #OS_ERROR   The dynamic memory fails to be initialized.
225  * @retval #LOS_OK     The dynamic memory is successfully initialized.
226  * @par Dependency:
227  * <ul>
228  * <li>los_memory.h: the header file that contains the API declaration.</li>
229  * </ul>
230  * @see None.
231  */
232 extern UINT32 LOS_MemInit(VOID *pool, UINT32 size);
233 
234 /**
235  * @ingroup los_memory
236  * @brief Allocate dynamic memory.
237  *
238  * @par Description:
239  * <ul>
240  * <li>This API is used to allocate a memory block of which the size is specified.</li>
241  * </ul>
242  * @attention
243  * <ul>
244  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
245  * <li>The size of the input parameter size can not be greater than the memory pool size that specified at the second
246  * input parameter of LOS_MemInit.</li>
247  * <li>The size of the input parameter size must be four byte-aligned.</li>
248  * </ul>
249  *
250  * @param  pool    [IN] Pointer to the memory pool that contains the memory block to be allocated.
251  * @param  size    [IN] Size of the memory block to be allocated (unit: byte).
252  *
253  * @retval #NULL          The memory fails to be allocated.
254  * @retval #VOID*         The memory is successfully allocated with the starting address of the allocated memory block
255  *                        returned.
256  * @par Dependency:
257  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
258  * @see LOS_MemRealloc | LOS_MemAllocAlign | LOS_MemFree
259  */
260 extern VOID *LOS_MemAlloc(VOID *pool, UINT32 size);
261 
262 /**
263  * @ingroup los_memory
264  * @brief Free dynamic memory.
265  *
266  * @par Description:
267  * <li>This API is used to free specified dynamic memory that has been allocated.</li>
268  * @attention
269  * <ul>
270  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
271  * <li>The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign or LOS_MemRealloc.</li>
272  * </ul>
273  *
274  * @param  pool  [IN] Pointer to the memory pool that contains the dynamic memory block to be freed.
275  * @param  ptr   [IN] Starting address of the memory block to be freed.
276  *
277  * @retval #LOS_NOK          The memory block fails to be freed because the starting address of the memory block is
278  *                           invalid, or the memory overwriting occurs.
279  * @retval #LOS_OK           The memory block is successfully freed.
280  * @par Dependency:
281  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
282  * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemAllocAlign
283  */
284 extern UINT32 LOS_MemFree(VOID *pool, VOID *ptr);
285 
286 /**
287  * @ingroup los_memory
288  * @brief Re-allocate a memory block.
289  *
290  * @par Description:
291  * <ul>
292  * <li>This API is used to allocate a new memory block of which the size is specified by size if the original memory
293  * block size is insufficient. The new memory block will copy the data in the original memory block of which the
294  * address is specified by ptr. The size of the new memory block determines the maximum size of data to be copied.
295  * After the new memory block is created, the original one is freed.</li>
296  * </ul>
297  * @attention
298  * <ul>
299  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
300  * <li>The input ptr parameter must be allocated by LOS_MemAlloc or LOS_MemAllocAlign.</li>
301  * <li>The size of the input parameter size can not be greater than the memory pool size that specified at the second
302  * input parameter of LOS_MemInit.</li>
303  * <li>The size of the input parameter size must be aligned as follows: 1) if the ptr is allocated by LOS_MemAlloc,
304  * it must be four byte-aligned; 2) if the ptr is allocated by LOS_MemAllocAlign, it must be aligned with the size of
305  * the input parameter boundary of LOS_MemAllocAlign.</li>
306  * </ul>
307  *
308  * @param  pool     [IN] Pointer to the memory pool that contains the original and new memory blocks.
309  * @param  ptr      [IN] Address of the original memory block.
310  * @param  size     [IN] Size of the new memory block.
311  *
312  * @retval #NULL    The memory fails to be re-allocated.
313  * @retval #VOID*   The memory is successfully re-allocated with the starting address of the new memory block returned.
314  * @par Dependency:
315  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
316  * @see LOS_MemAlloc | LOS_MemAllocAlign | LOS_MemFree
317  */
318 extern VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size);
319 
320 /**
321  * @ingroup los_memory
322  * @brief Allocate aligned memory.
323  *
324  * @par Description:
325  * <ul>
326  * <li>This API is used to allocate memory blocks of specified size and of which the starting addresses are aligned on
327  * a specified boundary.</li>
328  * </ul>
329  * @attention
330  * <ul>
331  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
332  * <li>The size of the input parameter size can not be greater than the memory pool size that specified at the second
333  * input parameter of LOS_MemInit.</li>
334  * <li>The alignment parameter value must be a power of 2 with the minimum value being 4.</li>
335  * </ul>
336  *
337  * @param  pool      [IN] Pointer to the memory pool that contains the memory blocks to be allocated.
338  * @param  size      [IN] Size of the memory to be allocated.
339  * @param  boundary  [IN] Boundary on which the memory is aligned.
340  *
341  * @retval #NULL    The memory fails to be allocated.
342  * @retval #VOID*   The memory is successfully allocated with the starting address of the allocated memory returned.
343  * @par Dependency:
344  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
345  * @see LOS_MemAlloc | LOS_MemRealloc | LOS_MemFree
346  */
347 extern VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary);
348 
349 /**
350  * @ingroup los_memory
351  * @brief Get the size of memory pool's size.
352  *
353  * @par Description:
354  * <ul>
355  * <li>This API is used to get the size of memory pool' total size.</li>
356  * </ul>
357  * @attention
358  * <ul>
359  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
360  * </ul>
361  *
362  * @param  pool           [IN] A pointer pointed to the memory pool.
363  *
364  * @retval #LOS_NOK        The incoming parameter pool is NULL.
365  * @retval #UINT32         The size of the memory pool.
366  * @par Dependency:
367  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
368  * @see None.
369  */
370 extern UINT32 LOS_MemPoolSizeGet(const VOID *pool);
371 
372 /**
373  * @ingroup los_memory
374  * @brief Get the size of memory totally used.
375  *
376  * @par Description:
377  * <ul>
378  * <li>This API is used to get the size of memory totally used in memory pool.</li>
379  * </ul>
380  * @attention
381  * <ul>
382  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
383  * </ul>
384  *
385  * @param  pool           [IN] A pointer pointed to the memory pool.
386  *
387  * @retval #LOS_NOK        The incoming parameter pool is NULL.
388  * @retval #UINT32         The size of the memory pool used.
389  * @par Dependency:
390  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
391  * @see None.
392  */
393 extern UINT32 LOS_MemTotalUsedGet(VOID *pool);
394 
395 /**
396  * @ingroup los_memory
397  * @brief Get the information of memory pool.
398  *
399  * @par Description:
400  * <ul>
401  * <li>This API is used to get the information of memory pool.</li>
402  * </ul>
403  * @attention
404  * <ul>
405  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
406  * </ul>
407  *
408  * @param  pool                 [IN] A pointer pointed to the memory pool.
409  * @param  poolStatus           [IN] A pointer for storage the pool status
410  *
411  * @retval #LOS_NOK           The incoming parameter pool is NULL or invalid.
412  * @retval #LOS_OK            Success to get memory information.
413  * @par Dependency:
414  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
415  * @see None.
416  */
417 extern UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *poolStatus);
418 
419 /**
420  * @ingroup los_memory
421  * @brief Get the number of free node in every size.
422  *
423  * @par Description:
424  * <ul>
425  * <li>This API is used to get the number of free node in every size.</li>
426  * </ul>
427  * @attention
428  * <ul>
429  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
430  * </ul>
431  *
432  * @param  pool               [IN] A pointer pointed to the memory pool.
433  *
434  * @retval #LOS_NOK           The incoming parameter pool is NULL.
435  * @retval #UINT32            The address of the last used node that casts to UINT32.
436  * @par Dependency:
437  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
438  * @see None.
439  */
440 extern UINT32 LOS_MemFreeNodeShow(VOID *pool);
441 
442 /**
443  * @ingroup los_memory
444  * @brief Check the memory pool integrity.
445  *
446  * @par Description:
447  * <ul>
448  * <li>This API is used to check the memory pool integrity.</li>
449  * </ul>
450  * @attention
451  * <ul>
452  * <li>The input pool parameter must be initialized via func LOS_MemInit.</li>
453  * <li>LOS_MemIntegrityCheck will be called by malloc function when the macro of LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK
454  * is defined in LiteOS.</li>
455  * <li>LOS_MemIntegrityCheck function can be called by user anytime.</li>
456  * </ul>
457  *
458  * @param  pool              [IN] A pointer pointed to the memory pool.
459  *
460  * @retval #LOS_NOK           The memory pool (pool) is impaired.
461  * @retval #LOS_OK            The memory pool (pool) is integrated.
462  * @par Dependency:
463  * <ul><li>los_memory.h: the header file that contains the API declaration.</li></ul>
464  * @see None.
465  */
466 extern UINT32 LOS_MemIntegrityCheck(const VOID *pool);
467 
468 /**
469  * @ingroup los_memory
470  * @brief Enable memory pool to support no internal lock during using interfaces.
471  *
472  * @par Description:
473  * <ul>
474  * <li>This API is used to enable memory pool to support no internal lock during using interfaces,</li>
475  * <li>such as LOS_MemAlloc/LOS_MemAllocAlign/LOS_MemRealloc/LOS_MemFree and so on.
476  * </ul>
477  * @attention
478  * <ul>
479  * <li>The memory pool does not support multi-threaded concurrent application scenarios.
480  * <li>If you want to use this function, you need to call this interface before the memory
481  * pool is used, it cannot be called during the trial period.</li>
482  * </ul>
483  *
484  * @param pool         [IN] Starting address of memory.
485  *
486  * @retval node.
487  * @par Dependency:
488  * <ul>
489  * <li>los_memory.h: the header file that contains the API declaration.</li>
490  * </ul>
491  * @see None.
492  */
493 
494 /* Supposing a Second Level Index: SLI = 3. */
495 #define OS_MEM_SLI                      3
496 /* Giving 1 free list for each small bucket: 4, 8, 12, up to 124. */
497 #define OS_MEM_SMALL_BUCKET_COUNT       31
498 #define OS_MEM_SMALL_BUCKET_MAX_SIZE    128
499 /* Giving 2^OS_MEM_SLI free lists for each large bucket. */
500 #define OS_MEM_LARGE_BUCKET_COUNT       24
501 /* OS_MEM_SMALL_BUCKET_MAX_SIZE to the power of 2 is 7. */
502 #define OS_MEM_LARGE_START_BUCKET       7
503 
504 /* The count of free list. */
505 #define OS_MEM_FREE_LIST_COUNT  (OS_MEM_SMALL_BUCKET_COUNT + (OS_MEM_LARGE_BUCKET_COUNT << OS_MEM_SLI))
506 /* The bitmap is used to indicate whether the free list is empty, 1: not empty, 0: empty. */
507 #define OS_MEM_BITMAP_WORDS     ((OS_MEM_FREE_LIST_COUNT >> 5) + 1)
508 
509 struct OsMemNodeHead {
510 #if (LOSCFG_BASE_MEM_NODE_INTEGRITY_CHECK == 1)
511     UINT32 magic;
512 #endif
513 #if (LOSCFG_MEM_LEAKCHECK == 1)
514     UINTPTR linkReg[LOSCFG_MEM_RECORD_LR_CNT];
515 #endif
516     union {
517         struct OsMemNodeHead *prev; /* The prev is used for current node points to the previous node */
518         struct OsMemNodeHead *next; /* The next is used for sentinel node points to the expand node */
519     } ptr;
520 #if (LOSCFG_TASK_MEM_USED == 1)
521     UINT32 taskID;
522     UINT32 sizeAndFlag;
523 #elif (LOSCFG_MEM_FREE_BY_TASKID == 1)
524     UINT32 taskID : 6;
525     UINT32 sizeAndFlag : 26;
526 #else
527     UINT32 sizeAndFlag;
528 #endif
529 };
530 
531 struct OsMemFreeNodeHead {
532     struct OsMemNodeHead header;
533     struct OsMemFreeNodeHead *prev;
534     struct OsMemFreeNodeHead *next;
535 };
536 
537 struct OsMemPoolInfo {
538     VOID *pool;
539     UINT32 totalSize;
540     UINT32 attr;
541 #if (LOSCFG_MEM_WATERLINE == 1)
542     UINT32 waterLine;   /* Maximum usage size in a memory pool */
543     UINT32 curUsedSize; /* Current usage size in a memory pool */
544 #endif
545 #if (LOSCFG_MEM_MUL_REGIONS == 1)
546     UINT32 totalGapSize;
547 #endif
548 };
549 
550 struct OsMemPoolHead {
551     struct OsMemPoolInfo info;
552     UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS];
553     struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT];
554 #if (LOSCFG_MEM_MUL_POOL == 1)
555     VOID *nextPool;
556 #endif
557 };
558 
559 extern VOID LOS_MemUnlockEnable(VOID *pool);
560 
561 extern UINT32 OsMemSystemInit(VOID);
562 extern VOID OsTaskMemUsed(VOID *pool, UINT32 *tskMemInfoBuf, UINT32 tskMemInfoCnt);
563 
564 #ifdef __cplusplus
565 #if __cplusplus
566 }
567 #endif /* __cplusplus */
568 #endif /* __cplusplus */
569 
570 #endif /* _LOS_MEMORY_H */
571