对静态内存实现注解

    百图画鸿蒙 + 百文说内核 + 百万注源码  => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 f966bf13
......@@ -120,8 +120,8 @@ LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);///< 初始化软时钟自旋锁,
typedef struct {
SortLinkAttribute swtmrSortLink;
LosTaskCB *swtmrTask; /* software timer task id */
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */
LosTaskCB *swtmrTask; /* software timer task id | 定时器任务ID */
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id | 定时器超时队列*/
} SwtmrRunQue;
STATIC SwtmrRunQue g_swtmrRunQue[LOSCFG_KERNEL_CORE_NUM];
......
......@@ -39,7 +39,7 @@
#ifdef LOSCFG_SECURITY_VID
#include "vid_api.h"
#else
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID //最大支持的软件定时器数量 <65535
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID //最大支持的软件定时器数量 < 65535
#endif
#ifdef __cplusplus
......@@ -53,9 +53,9 @@ extern "C" {
* Software timer state
*/
enum SwtmrState { //定时器状态
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */ //定时器未使用,系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */ //定时器创建后未启动,或已停止.定时器创建后,不处于计数状态时,定时器将变成该状态。
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */ //定时器处于计数状态,在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. | 定时器未使用,系统在定时器模块初始化时,会将系统中所有定时器资源初始化成该状态。 */
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. | 定时器创建后未启动,或已停止.定时器创建后,不处于计数状态时,定时器将变成该状态。 */
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. | 定时器处于计数状态,在定时器创建后调用LOS_SwtmrStart接口启动,定时器将变成该状态,是定时器运行时的状态。 */
};
/**
......@@ -63,10 +63,10 @@ enum SwtmrState { //定时器状态
* Structure of the callback function that handles software timer timeout
*/
typedef struct {//处理软件定时器超时的回调函数的结构体
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */ //处理软件定时器超时的回调函数
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout | 处理软件定时器超时的回调函数*/
UINTPTR arg; /**< Parameter passed in when the callback function
that handles software timer timeout is called */ //调用处理软件计时器超时的回调函数时传入的参数
LOS_DL_LIST node;
that handles software timer timeout is called | 调用处理软件计时器超时的回调函数时传入的参数*/
LOS_DL_LIST node; ///< 挂入定时器超时队列,详见 SwtmrWake( ... )
#ifdef LOSCFG_SWTMR_DEBUG
UINT32 swtmrID;
#endif
......
/*!
* @file los_membox.c
* @brief 静态内存池主文件
* @link
@verbatim
使用场景
当用户需要使用固定长度的内存时,可以通过静态内存分配的方式获取内存,一旦使用完毕,
通过静态内存释放函数归还所占用内存,使之可以重复使用。
开发流程
通过make menuconfig配置静态内存管理模块。
规划一片内存区域作为静态内存池。
调用LOS_MemboxInit初始化静态内存池。
初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。
调用LOS_MemboxAlloc接口分配静态内存。
系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。
调用LOS_MemboxClr接口。将入参地址对应的内存块清零。
调用LOS_MemboxFree接口。将该内存块加入空闲链表。
注意事项
静态内存池区域,如果是通过动态内存分配方式获得的,在不需要静态内存池时,
需要释放该段内存,避免发生内存泄露。
静态内存不常用,因为需要使用者去确保不会超出使用范围
@endverbatim
* @version
* @author weharmonyos.com | 鸿蒙研究站 | 每天死磕一点点
* @date 2022-04-02
*/
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
......@@ -33,27 +64,6 @@
#include "los_hwi.h"
#include "los_spinlock.h"
/******************************************************************************
使用场景
当用户需要使用固定长度的内存时,可以通过静态内存分配的方式获取内存,一旦使用完毕,
通过静态内存释放函数归还所占用内存,使之可以重复使用。
开发流程
通过make menuconfig配置静态内存管理模块。
规划一片内存区域作为静态内存池。
调用LOS_MemboxInit初始化静态内存池。
初始化会将入参指定的内存区域分割为N块(N值取决于静态内存总大小和块大小),将所有内存块挂到空闲链表,在内存起始处放置控制头。
调用LOS_MemboxAlloc接口分配静态内存。
系统将会从空闲链表中获取第一个空闲块,并返回该内存块的起始地址。
调用LOS_MemboxClr接口。将入参地址对应的内存块清零。
调用LOS_MemboxFree接口。将该内存块加入空闲链表。
注意事项
静态内存池区域,如果是通过动态内存分配方式获得的,在不需要静态内存池时,
需要释放该段内存,避免发生内存泄露。
静态内存不常用,因为需要使用者去确保不会超出使用范围
******************************************************************************/
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5 //魔法数字,@note_good 点赞,设计的很精巧,node内容从下一个节点地址变成魔法数字
#else
......@@ -67,12 +77,12 @@
#define OS_MEMBOX_USER_ADDR(addr) \
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE)) //@note_good 使用之前要去掉节点信息,太赞了! 很艺术化!!
#define OS_MEMBOX_NODE_ADDR(addr) \
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //释放之前要加上节点信息
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE)) //节块 = (节头 + 节体) addr = 节体
/* spinlock for mem module, only available on SMP mode */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin);
#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state))
#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))
//检查静态内存块
#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state)) ///< 获取静态内存池自旋锁
#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))///< 释放静态内存池自旋锁
/// 检查静态内存块
STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node)
{
UINT32 offset;
......@@ -92,10 +102,10 @@ STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *n
return OS_MEMBOX_CHECK_MAGIC(node);//检查魔法数字是否被修改过了
}
///初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小
/// 初始化一个静态内存池,根据入参设定其起始地址、总大小及每个内存块大小
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处放置控制
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;//在内存起始处安置池
LOS_MEMBOX_NODE *node = NULL;
UINT32 index;
UINT32 intSave;
......@@ -113,19 +123,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32
}
MEMBOX_LOCK(intSave);
boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE);
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//分块
boxInfo->uwBlkSize = LOS_MEMBOX_ALIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE); //节块总大小(节头+节体)
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;//总节块数量
boxInfo->uwBlkCnt = 0; //已分配的数量
if (boxInfo->uwBlkNum == 0) {//只有0块的情况
MEMBOX_UNLOCK(intSave);
return LOS_NOK;
}
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除控制头,找到第一个节点
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);//去除池头,找到第一个节块位置
boxInfo->stFreeList.pstNext = node;//头结点指向boxInfo长度尾部位置
boxInfo->stFreeList.pstNext = node;//池头空闲链表指向第一个节块
for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {
for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {//切割节块,挂入空闲链表
node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);//按块大小切割好,统一由pstNext指向
node = node->pstNext;//node存储了下一个节点的地址信息
}
......@@ -136,7 +146,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32
return LOS_OK;
}
///从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存.
/// 从指定的静态内存池中申请一块静态内存块,整个内核源码只有 OsSwtmrScan中用到了静态内存.
LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
......@@ -153,14 +163,14 @@ LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
if (node->pstNext != NULL) {//不需要遍历链表,因为这是空闲链表
nodeTmp = node->pstNext;//先记录要使用的节点
node->pstNext = nodeTmp->pstNext;//不再空闲了,把节点摘出去了.
OS_MEMBOX_SET_MAGIC(nodeTmp);//设置节点魔法数字
OS_MEMBOX_SET_MAGIC(nodeTmp);//为已使用的节块设置魔法数字
boxInfo->uwBlkCnt++;//已使用块数增加
}
MEMBOX_UNLOCK(intSave);
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的内存地址
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);//返回可用的虚拟地址
}
///释放指定的一块静态内存块
/// 释放指定的一块静态内存块
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
......@@ -173,13 +183,13 @@ LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
MEMBOX_LOCK(intSave);
do {
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//归还静态内存
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);//通过节体获取节块首地址
if (OsCheckBoxMem(boxInfo, node) != LOS_OK) {
break;
}
node->pstNext = boxInfo->stFreeList.pstNext;//将节点挂入单向链表
boxInfo->stFreeList.pstNext = node;
node->pstNext = boxInfo->stFreeList.pstNext;//节块指向空闲链表表头
boxInfo->stFreeList.pstNext = node;//空闲链表表头反指向它,意味节块排到第一,下次申请将首个分配它
boxInfo->uwBlkCnt--;//已经使用的内存块减一
ret = LOS_OK;
} while (0);//将被编译时优化
......@@ -187,7 +197,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
return ret;
}
///清零指定静态内存块的内容
/// 清零指定静态内存块的内容
LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box)
{
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
......@@ -199,8 +209,8 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box)
(VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0,
(boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE));
}
///打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、
//内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址
/// 打印指定静态内存池所有节点信息(打印等级是LOS_INFO_LEVEL),包括内存池起始地址、
/// 内存块大小、总内存块数量、每个空闲内存块的起始地址、所有内存块的起始地址
LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool)
{
UINT32 index;
......@@ -227,7 +237,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool)
}
MEMBOX_UNLOCK(intSave);
}
///获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小
/// 获取指定静态内存池的信息,包括内存池中总内存块数量、已经分配出去的内存块数量、每个内存块的大小
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk,
UINT32 *blkCnt, UINT32 *blkSize)
{
......
......@@ -54,18 +54,18 @@ extern "C" {
* Structure of a free node in a memory pool
*/
typedef struct tagMEMBOX_NODE { //内存池中空闲节点的结构,是个单向的链表
struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool *///指向内存池中下一个空闲节点的指针
struct tagMEMBOX_NODE *pstNext; /**< Free node's pointer to the next node in a memory pool | 指向内存池中下一个空闲节点的指针*/
} LOS_MEMBOX_NODE;
/**
* @ingroup los_membox
* Memory pool information structure
*/
typedef struct {//静态内存池信息结构体
UINT32 uwBlkSize; /**< Block size */ //块大小
UINT32 uwBlkNum; /**< Block number */ //块数量
UINT32 uwBlkCnt; /**< The number of allocated blocks */ //已经被分配的块数量
LOS_MEMBOX_NODE stFreeList; /**< Free list */ //空闲链表
typedef struct {//静态内存池结构体
UINT32 uwBlkSize; /**< Block size | 块大小*/
UINT32 uwBlkNum; /**< Block number | 块数量*/
UINT32 uwBlkCnt; /**< The number of allocated blocks | 已经被分配的块数量*/
LOS_MEMBOX_NODE stFreeList; /**< Free list | 空闲链表*/
} LOS_MEMBOX_INFO;
typedef LOS_MEMBOX_INFO OS_MEMBOX_S;
......
git add -A
git commit -m ' 对动态内存切割,合并,扩展功能注解
git commit -m ' 对静态内存实现注解
百图画鸿蒙 + 百文说内核 + 百万注源码 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册