/* ----------------------------------------------------------------------------
 * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved.
 * Description: LiteOS Mem Module Implementation
 * Author: Huawei LiteOS Team
 * Create: 2013-05-12
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 * 1. Redistributions of source code must retain the above copyright notice, this list of
 * conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific prior written
 * permission.
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * --------------------------------------------------------------------------- */

#include "los_memory_pri.h"
#include "los_memory_internal.h"

#include "securec.h"

#include "los_hwi.h"
#include "los_spinlock.h"
#include "los_trace.h"

#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */

#define POOL_ADDR_ALIGNSIZE 64//是一个宏，表示内存池地址对齐的大小，值为64。

LITE_OS_SEC_BSS  SPIN_LOCK_INIT(g_memSpin);//是一个修饰符，用于指定变量所属的段（section）为.bss.init，该变量在程序运行前会被初始化为0。
//是一个宏，用于初始化自旋锁变量g_memSpin。

UINT8 *m_aucSysMem0 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量，初始值为NULL。
UINT8 *m_aucSysMem1 = (UINT8 *)NULL;//是一个指向UINT8类型的指针变量，初始值为NULL。
__attribute__((section(".data.init"))) UINTPTR g_sys_mem_addr_end;//是一个UINTPTR类型的变量，位于.data.init段，用于记录系统内存地址的末尾位置。


#ifdef LOSCFG_EXC_INTERACTION//表示如果定义了宏LOSCFG_EXC_INTERACTION，则编译以下代码块。
__attribute__((section(".data.init"))) UINTPTR g_excInteractMemSize = 0;//是一个UINTPTR类型的变量，位于.data.init段，用于记录异常交互内存的大小，初始值为0。
#endif


/*这段代码是一个函数LOS_MemInit()的实现，用于初始化内存池。

LITE_OS_SEC_TEXT_INIT 是一个修饰符，用于指定函数所属的段（section）为.text.init，表示该函数在程序运行前会被初始化。

函数参数：

pool 是一个指向内存池的指针，用于存储分配的内存块。
size 是内存池的大小。
函数内部逻辑：

首先，函数会对传入的参数进行检查。如果pool为空指针或size小于等于sizeof(struct LosHeapManager)（一种内部结构的大小），则函数直接返回错误码LOS_NOK。
接下来，函数会检查pool和size是否按照OS_MEM_ALIGN_SIZE（内存对齐大小）进行对齐。如果没有对齐，则打印警告信息，并将size调整为对齐后的大小。
然后，函数会获取并保存当前的中断状态，以防止在初始化过程中发生中断。
接着，函数调用OsMemMulPoolInit()初始化多内存池管理器，如果初始化失败，则跳转到OUT标签处。
如果多内存池管理器初始化成功，函数继续调用OsHeapInit()初始化堆管理器。如果堆管理器初始化失败，则先释放多内存池，然后跳转到OUT标签处。
最后，函数调用OsSlabMemInit()初始化 Slab 内存管理器，并将返回值设置为成功的状态码LOS_OK。
在OUT标签处，函数会解锁之前保存的中断状态，并打印内存信息请求的跟踪日志。
最终，函数返回初始化结果，可能是LOS_NOK表示失败，或者LOS_OK表示成功。
这段代码主要实现了内存池的初始化逻辑，包括多内存池管理器、堆管理器和 Slab 内存管理器的初始化。*/
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemInit(VOID *pool, UINT32 size)
{
    UINT32 ret = LOS_NOK;
    UINT32 intSave;

    if ((pool == NULL) || (size <= sizeof(struct LosHeapManager))) {
        return ret;
    }

    if (!IS_ALIGNED(size, OS_MEM_ALIGN_SIZE) || !IS_ALIGNED(pool, OS_MEM_ALIGN_SIZE)) {
        PRINT_WARN("pool [%p, %p) size 0x%x should be aligned with OS_MEM_ALIGN_SIZE\n",
                   pool, (UINTPTR)pool + size, size);
        size = OS_MEM_ALIGN(size, OS_MEM_ALIGN_SIZE) - OS_MEM_ALIGN_SIZE;
    }

    MEM_LOCK(intSave);
    if (OsMemMulPoolInit(pool, size) != LOS_OK) {
        goto OUT;
    }

    if (OsHeapInit(pool, size) == FALSE) {
        (VOID)OsMemMulPoolDeinit(pool);
        goto OUT;
    }

    OsSlabMemInit(pool, size);
    ret = LOS_OK;
OUT:
    MEM_UNLOCK(intSave);

    LOS_TRACE(MEM_INFO_REQ, pool);
    return ret;
}

#ifdef LOSCFG_EXC_INTERACTION
LITE_OS_SEC_TEXT_INIT UINT32 OsMemExcInteractionInit(UINTPTR memStart)
{
    UINT32 ret;
    m_aucSysMem0 = (UINT8 *)memStart;
    g_excInteractMemSize = EXC_INTERACT_MEM_SIZE;
    ret = LOS_MemInit(m_aucSysMem0, g_excInteractMemSize);
    PRINT_INFO("LiteOS kernel exc interaction memory address:%p,size:0x%x\n", m_aucSysMem0, g_excInteractMemSize);
    return ret;
}
#endif

/*
 * Description : Initialize Dynamic Memory pool
 * Return      : LOS_OK on success or error code on failure
 */

/*这段代码是一个条件编译块，当定义了宏LOSCFG_EXC_INTERACTION时才会被编译。

LITE_OS_SEC_TEXT_INIT 是一个修饰符，用于指定函数所属的段（section）为.text.init，表示该函数在程序运行前会被初始化。

函数参数：

memStart 是一个无符号整数指针，表示内存起始地址。
函数内部逻辑：

首先，函数将全局变量m_aucSysMem0指向memStart，即将系统内存的起始地址设为memStart。
然后，函数将全局变量g_excInteractMemSize设置为宏定义EXC_INTERACT_MEM_SIZE的值，表示异常交互内存区域的大小。
接下来，函数调用LOS_MemInit()函数，将m_aucSysMem0和g_excInteractMemSize作为参数进行内存初始化操作，并将返回结果保存在变量ret中。
最后，函数打印一条信息，包含异常交互内存的地址和大小，并将初始化结果ret作为返回值返回。
这段代码主要是用于初始化异常交互内存，通过调用LOS_MemInit()函数来初始化系统内存，并打印初始化信息。条件编译的目的是根据是否定义了LOSCFG_EXC_INTERACTION宏来控制代码的编译和执行。*/
LITE_OS_SEC_TEXT_INIT UINT32 OsMemSystemInit(UINTPTR memStart)
{
    UINT32 ret;
    UINT32 memSize;

    m_aucSysMem1 = (UINT8 *)memStart;
    memSize = OS_SYS_MEM_SIZE;
    ret = LOS_MemInit((VOID *)m_aucSysMem1, memSize);
#ifndef LOSCFG_EXC_INTERACTION
    m_aucSysMem0 = m_aucSysMem1;
#endif
    return ret;
}

/*
 * Description : print heap information
 * Input       : pool --- Pointer to the manager, to distinguish heap
 */
/*这段代码是用于打印内存池（pool）信息的函数，接收一个pool指针作为参数。

函数参数：

pool 是一个指向内存池的指针，用于获取内存池的信息。
函数内部逻辑：

首先，函数将传入的pool指针转换为LosHeapManager结构体类型的指针，并赋值给变量heapMan。
然后，函数定义了一个LosHeapStatus类型的变量status，用于保存堆管理器的状态信息。
接着，函数调用OsHeapStatisticsGet()函数获取堆管理器的状态信息，并将其保存在status变量中。如果函数返回错误码LOS_NOK，则函数直接返回。
最后，函数打印一条包含内存池信息的日志信息，包括内存池地址、内存池大小、已使用内存大小、空闲内存大小、最大空闲节点大小、已分配节点数量和空闲节点数量。
这段代码主要是用于获取内存池的状态信息，并打印到控制台或日志文件中，方便调试和排查内存泄漏等问题。*/
VOID OsMemInfoPrint(const VOID *pool)
{
    struct LosHeapManager *heapMan = (struct LosHeapManager *)pool;
    LosHeapStatus status = {0};

    if (OsHeapStatisticsGet(heapMan, &status) == LOS_NOK) {
        return;
    }

    PRINT_INFO("pool addr    pool size    used size    free size    max free    alloc Count    free Count\n");
    PRINT_INFO("0x%-8x   0x%-8x   0x%-8x    0x%-8x   0x%-8x   0x%-8x     0x%-8x\n",
               pool, heapMan->size, status.totalUsedSize, status.totalFreeSize, status.maxFreeNodeSize,
               status.usedNodeNum, status.freeNodeNum);
}

/*这段代码是用于内存分配的函数，可以从指定的内存池中分配一块指定大小的内存。

函数参数：

pool 是一个指向内存池的指针，用于从该内存池中分配内存。
size 是需要分配的内存大小。
函数内部逻辑：

首先，函数定义了一个空指针ptr，用于保存分配到的内存块地址。
然后，函数检查传入的参数，如果pool为空或者size为0，则直接返回空指针。
接着，函数锁住中断，调用OsSlabMemAlloc()函数尝试从内存池的SLAB分配器中获取一块指定大小的内存。如果分配成功，则将返回的内存地址保存在ptr中。
如果从SLAB分配器中分配内存失败，则调用OsHeapAlloc()函数从堆内存中分配一块指定大小的内存，并将返回的内存地址保存在ptr中。
最后，函数解锁中断，记录内存分配操作的追踪日志，并返回分配到的内存地址。
这段代码主要是用于从内存池中分配内存，首先尝试从SLAB分配器中获取内存，如果失败则从堆内存中获取。在获取内存时还记录了内存分配操作的追踪日志，方便调试和内存优化。*/
LITE_OS_SEC_TEXT VOID *LOS_MemAlloc(VOID *pool, UINT32 size)
{
    VOID *ptr = NULL;
    UINT32 intSave;

    if ((pool == NULL) || (size == 0)) {
        return ptr;
    }

    MEM_LOCK(intSave);

    ptr = OsSlabMemAlloc(pool, size);
    if (ptr == NULL) {
        ptr = OsHeapAlloc(pool, size);
    }

    MEM_UNLOCK(intSave);

    LOS_TRACE(MEM_ALLOC, pool, (UINTPTR)ptr, size);
    return ptr;
}

/*这段代码是用于按指定对齐边界分配内存的函数，可以从指定的内存池中分配一块指定大小、按指定对齐边界对齐的内存。

函数参数：

pool 是一个指向内存池的指针，用于从该内存池中分配内存。
size 是需要分配的内存大小。
boundary 是需要对齐的边界大小。返回的内存地址将会是该边界的整数倍。
函数内部逻辑：

首先，函数定义了一个空指针ptr，用于保存分配到的内存块地址。
然后，函数锁住中断，调用OsHeapAllocAlign()函数从堆内存中按指定对齐边界分配一块指定大小的内存。如果分配成功，则将返回的内存地址保存在ptr中。
最后，函数解锁中断，记录内存分配操作的追踪日志，并返回分配到的内存地址。
这段代码主要是用于从内存池中按指定对齐边界分配内存，只能在堆内存上操作。在分配内存时还记录了内存分配操作的追踪日志，方便调试和内存优化。*/
LITE_OS_SEC_TEXT VOID *LOS_MemAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
{
    VOID *ptr = NULL;
    UINT32 intSave;

    MEM_LOCK(intSave);
    ptr = OsHeapAllocAlign(pool, size, boundary);
    MEM_UNLOCK(intSave);

    LOS_TRACE(MEM_ALLOC_ALIGN, pool, (UINTPTR)ptr, size, boundary);
    return ptr;
}


/*这段代码是用于重新分配内存大小的函数，主要有以下几个步骤：

首先判断需要重新分配大小的指针ptr是否为空，如果为空，说明需要分配一块新的内存，直接调用LOS_MemAlloc()函数从内存池中分配一块指定大小的内存并返回。
如果需要重新分配大小的指针ptr不为空且所需大小为0，则将该指针对应的内存块释放掉。
如果需要重新分配大小的指针ptr不为空且所需大小非0，则需要从堆内存中分配一块新的内存，并将原内存中的数据拷贝到新内存中。这里在拷贝数据之前，需要先判断原内存地址是否合法。具体方法是通过OsSlabMemCheck()函数检查该指针是否属于内存池中的某个内存块，若是，则复制原内存中的数据；否则，根据原内存指针前面存储的一个整数值（表示实际内存块的大小和对齐状态）找到真正的内存块，再进行内存拷贝。
将原内存块释放掉，返回分配到的新内存地址。
这段代码的作用是实现重新分配内存大小的功能，可以对已经分配的内存进行扩展或缩小。在实现过程中，需要考虑到原内存块中已经存储的数据，避免无意义的内存拷贝操作。*/
VOID *LOS_MemRealloc(VOID *pool, VOID *ptr, UINT32 size)
{
    VOID *retPtr = NULL;
    VOID *freePtr = NULL;
    UINT32 intSave;
    struct LosHeapNode *node = NULL;
    UINT32 cpySize;
    UINT32 gapSize;
    errno_t rc;

    /* Zero-size requests are treated as free. */
    if ((ptr != NULL) && (size == 0)) {
        if (LOS_MemFree(pool, ptr) != LOS_OK) {
            PRINT_ERR("LOS_MemFree error, pool[%p], pPtr[%p]\n", pool, ptr);
        }
    } else if (ptr == NULL) { // Requests with NULL pointers are treated as malloc.
        retPtr = LOS_MemAlloc(pool, size);
    } else {
        MEM_LOCK(intSave);

        UINT32 oldSize = OsSlabMemCheck(pool, ptr);
        if (oldSize != (UINT32)(-1)) {
            cpySize = (size > oldSize) ? oldSize : size;
        } else {
            /* find the real ptr through gap size */
            gapSize = *((UINTPTR *)((UINTPTR)ptr - sizeof(UINTPTR)));
            if (OS_MEM_GET_ALIGN_FLAG(gapSize)) {
                MEM_UNLOCK(intSave);
                return NULL;
            }

            node = ((struct LosHeapNode *)ptr) - 1;
            cpySize = (size > (node->size)) ? (node->size) : size;
        }

        MEM_UNLOCK(intSave);

        retPtr = LOS_MemAlloc(pool, size);
        if (retPtr != NULL) {
            rc = memcpy_s(retPtr, size, ptr, cpySize);
            if (rc == EOK) {
                freePtr = ptr;
            } else {
                freePtr = retPtr;
                retPtr = NULL;
            }

            if (LOS_MemFree(pool, freePtr) != LOS_OK) {
                PRINT_ERR("LOS_MemFree error, pool[%p], ptr[%p]\n", pool, freePtr);
            }
        }
    }

    LOS_TRACE(MEM_REALLOC, pool, (UINTPTR)ptr, size);
    return retPtr;
}

/*这段代码是用于释放内存的函数，主要有以下几个步骤：

首先判断内存池指针pool和需要释放的内存指针mem是否为空，如果其中任意一个为空，则返回错误码LOS_NOK表示释放失败。
获取并保存当前的中断状态，以便后续恢复。
调用OsSlabMemFree()函数尝试从内存池中释放指定的内存块。若成功释放，则将返回值设置为TRUE，否则继续执行下一步。
如果调用OsSlabMemFree()函数失败，说明该内存块不是由内存池分配的，需要调用OsHeapFree()函数尝试从堆内存中释放指定的内存块。同样，若成功释放，则将返回值设置为TRUE，否则返回值保持为FALSE。
恢复之前保存的中断状态。
根据最终的返回值，如果为TRUE，则返回成功码LOS_OK，否则返回失败码LOS_NOK。
这段代码的作用是实现内存的释放功能。首先尝试从内存池中释放内存，如果失败，则再尝试从堆内存中释放内存。通过这两种方式，可以确保能够释放从内存池或堆中分配的内存块。*/
LITE_OS_SEC_TEXT UINT32 LOS_MemFree(VOID *pool, VOID *mem)
{
    BOOL ret = FALSE;
    UINT32 intSave;

    if ((pool == NULL) || (mem == NULL)) {
        return LOS_NOK;
    }

    MEM_LOCK(intSave);

    ret = OsSlabMemFree(pool, mem);
    if (ret != TRUE) {
        ret = OsHeapFree(pool, mem);
    }

    MEM_UNLOCK(intSave);

    LOS_TRACE(MEM_FREE, pool, (UINTPTR)mem);
    return (ret == TRUE ? LOS_OK : LOS_NOK);
}

/*这段代码是用于获取内存池状态信息的函数，主要有以下几个步骤：

首先判断内存池指针pool和状态信息指针status是否为空，如果其中任意一个为空，则返回错误码LOS_NOK表示获取失败。
声明一个LosHeapStatus结构体类型的变量heapStatus，用于保存堆内存的状态信息。
声明一个错误码变量err和一个中断状态变量intSave。
获取并保存当前的中断状态，以便后续恢复。
调用OsHeapStatisticsGet()函数获取指定内存池的堆内存状态信息，将结果保存在heapStatus中。如果返回错误码不等于LOS_OK，则表示获取失败，释放锁并返回错误码LOS_NOK。
将获取到的堆内存状态信息赋值给传入的status参数，包括总使用大小、总空闲大小、最大空闲节点大小、已使用节点数量和空闲节点数量。
如果配置了任务内存统计，则还会将使用的峰值赋值给status的uwUsageWaterLine字段。
释放锁并返回成功码LOS_OK。
这段代码的作用是获取指定内存池的状态信息，包括已使用的内存大小、空闲的内存大小、最大空闲节点的大小等。通过这些状态信息，可以了解内存池的使用情况，并进行相应的优化和管理。*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemInfoGet(VOID *pool, LOS_MEM_POOL_STATUS *status)
{
    LosHeapStatus heapStatus;
    UINT32 err;
    UINT32 intSave;

    if ((pool == NULL) || (status == NULL)) {
        return LOS_NOK;
    }

    MEM_LOCK(intSave);

    err = OsHeapStatisticsGet(pool, &heapStatus);
    if (err != LOS_OK) {
        MEM_UNLOCK(intSave);
        return LOS_NOK;
    }

    status->uwTotalUsedSize   = heapStatus.totalUsedSize;
    status->uwTotalFreeSize   = heapStatus.totalFreeSize;
    status->uwMaxFreeNodeSize = heapStatus.maxFreeNodeSize;
    status->uwUsedNodeNum  = heapStatus.usedNodeNum;
    status->uwFreeNodeNum  = heapStatus.freeNodeNum;

#ifdef LOSCFG_MEM_TASK_STAT
    status->uwUsageWaterLine = heapStatus.usageWaterLine;
#endif

    MEM_UNLOCK(intSave);
    return LOS_OK;
}

/*这段代码是用于获取指定内存池已使用内存大小的函数，主要有以下几个步骤：

首先判断内存池指针pool是否为空，如果为空，则返回错误码OS_NULL_INT表示获取失败。
声明一个LosHeapStatus结构体类型的变量heapStatus，用于保存堆内存的状态信息。
声明一个错误码变量err和一个中断状态变量intSave。
获取并保存当前的中断状态，以便后续恢复。
调用OsHeapStatisticsGet()函数获取指定内存池的堆内存状态信息，将结果保存在heapStatus中。如果返回错误码不等于LOS_OK，则表示获取失败，释放锁并返回错误码OS_NULL_INT。
释放锁并返回堆内存的总使用大小。
这段代码的作用是获取指定内存池已使用的内存大小。通过该函数可以了解内存池的已使用情况，以便进行相应的管理和优化。*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemTotalUsedGet(VOID *pool)
{
    LosHeapStatus heapStatus;
    UINT32 err;
    UINT32 intSave;

    if (pool == NULL) {
        return OS_NULL_INT;
    }

    MEM_LOCK(intSave);
    err = OsHeapStatisticsGet(pool, &heapStatus);
    MEM_UNLOCK(intSave);

    if (err != LOS_OK) {
        return OS_NULL_INT;
    }

    return heapStatus.totalUsedSize;
}

/*这段代码是用于获取指定内存池的大小的函数，主要有以下几个步骤：

首先判断内存池指针pool是否为空，如果为空，则返回错误码OS_NULL_INT表示获取失败。
声明一个LosHeapManager结构体类型的指针变量heapManager，用于保存内存池的管理信息。
将传入的内存池指针转换为LosHeapManager类型的指针，并将结果保存在heapManager中。
返回内存池的大小，即heapManager->size。
这段代码的作用是获取指定内存池的大小。通过该函数可以了解内存池的大小，以便进行相应的管理和优化。*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemPoolSizeGet(const VOID *pool)
{
    struct LosHeapManager *heapManager = NULL;

    if (pool == NULL) {
        return OS_NULL_INT;
    }

    heapManager = (struct LosHeapManager *)pool;
    return heapManager->size;
}

/*这段代码是用于对指定内存池进行完整性检查的函数，主要有以下几个步骤：

首先判断内存池指针pool是否为空，如果为空，则返回错误码OS_NULL_INT表示检查失败。
声明一个中断状态变量intSave和一个无符号整型变量ret用于保存检查结果。
获取并保存当前的中断状态，以便后续恢复。
调用OsHeapIntegrityCheck()函数对指定的内存池进行完整性检查，并将检查结果保存在ret中。如果返回的结果不为0，则表示检查失败。
释放锁并返回检查结果。
这段代码的作用是对指定的内存池进行完整性检查，以确保内存池中的数据没有被破坏或溢出。通过该函数可以及时发现内存池中的问题，并采取相应的措施进行修复或处理。*/
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemIntegrityCheck(VOID *pool)
{
    UINT32 intSave;
    UINT32 ret;

    if (pool == NULL) {
        return OS_NULL_INT;
    }

    MEM_LOCK(intSave);
    ret = OsHeapIntegrityCheck(pool);
    MEM_UNLOCK(intSave);

    return ret;
}

/*这段代码是用于对多个内存池进行完整性检查的函数，主要有以下几个步骤：

首先调用LOS_MemIntegrityCheck()函数对系统内存池m_aucSysMem1进行完整性检查，并判断返回值是否为LOS_OK。
如果检查通过，则在控制台输出一条信息表示检查成功，并在需要时将该信息写入异常信息缓冲区。
如果系统内存池检查未通过，则不进行任何处理。
如果宏定义LOSCFG_EXC_INTERACTION被定义，则继续执行下面的代码，否则直接结束函数。
调用LOS_MemIntegrityCheck()函数对异常交互内存池m_aucSysMem0进行完整性检查，并判断返回值是否为LOS_OK。
如果检查通过，则在控制台输出一条信息表示检查成功，并在需要时将该信息写入异常信息缓冲区。
如果异常交互内存池检查未通过，则不进行任何处理。
这段代码的作用是对多个内存池进行完整性检查，以确保内存池中的数据没有被破坏或溢出。通过该函数可以及时发现内存池中的问题，并采取相应的措施进行修复或处理。*/
VOID OsMemIntegrityMultiCheck(VOID)
{
    if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) {
        PRINTK("system memcheck over, all passed!\n");
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
        WriteExcInfoToBuf("system memcheck over, all passed!\n");
#endif
    }
#ifdef LOSCFG_EXC_INTERACTION
    if (LOS_MemIntegrityCheck(m_aucSysMem0) == LOS_OK) {
        PRINTK("exc interaction memcheck over, all passed!\n");
#ifdef LOSCFG_SHELL_EXCINFO_DUMP
        WriteExcInfoToBuf("exc interaction memcheck over, all passed!\n");
#endif
    }
#endif
}

#ifdef __cplusplus
#if __cplusplus
}
#endif /* __cplusplus */
#endif /* __cplusplus */
