5 删除双向链表节点
双向链表提供两种链表节点的删除方法,删除指定节点LOS_ListDelete()
、删除并初始化为一个新链表LOS_ListDelInit()
。
6 获取双向链表节点
双向链表还提供宏定义获取指定链表节点的前驱节点LOS_DL_LIST_LAST
,获取指定链表节点的后继节点LOS_DL_LIST_FIRST
。OpenHarmony LiteOS-M
内核源码分析时,已经了解这2个宏,我们继续看下2个判断的宏,即LOS_DL_LIST_IS_END
和LOS_DL_LIST_IS_ON_QUEUE
。
6.1 LOS_DL_LIST_IS_END
通过判断两个链表节点是否相等,通常第一个为尾节点,第二个是变化的链表节点,判断是否遍历到尾节点。
源码如下:
#define LOS_DL_LIST_IS_END(list, node) ((list) == (node) ? TRUE : FALSE)
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
6.2 LOS_DL_LIST_IS_ON_QUEUE
用于判断链表节点是否在循环链表中,即前序、后继节点都不为空。
源码如下:
#define LOS_DL_LIST_IS_ON_QUEUE(node) ((node)->pstPrev != NULL && (node)->pstNext != NULL)
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
7 遍历双向循环链表节点
双向循环链表提供两种遍历双向链表的方法,LOS_DL_LIST_FOR_EACH
和LOS_DL_LIST_FOR_EACH_SAFE
。OpenHarmony LiteOS-M
内核源码分析时,已经分析过这2个宏。
8 获取链表节点所在结构体
通过宏LOS_DL_LIST_ENTRY
可以获取成员变量相对于结构体的内存地址偏移量。通过宏LOS_DL_LIST_ENTRY``即可以获取双向链表节点所在的业务结构体的内存地址。
OpenHarmony LiteOS-M内核源码分析时,已经分析过这2个宏。我们分析下
OpenHarmony LiteOS-A内核中独有的三个宏,即
LOS_ListPeekHeadType、
LOS_ListRemoveHeadType和
LOS_ListNextType`。
8.1 LOS_ListPeekHeadType
函数宏中的三个参数分别为:业务结构体类型名称type
,作为结构体成员的双向链表成员变量名称element
,双向链表头节点指针list
。通过调用该宏函数LOS_ListPeekHeadType
即可以获取双向链表第一个业务链表节点所在的业务结构体的内存地址。
⑴处表示如果是只有头链表结点的空双向循环链表,则返回NULL。⑵如果链表不为空,调用宏LOS_DL_LIST_ENTRY
获取业务结构体的内存地址。该宏相对宏LOS_DL_LIST_ENTRY
更安全,如果是空的双向链表,调用后者,返回的内存地址不是业务结构体的地址,会发生踩内存错误。
源码如下:
#define LOS_ListPeekHeadType(list, type, element) ({ \
type *__t; \
⑴ if ((list)->pstNext == list) { \
__t = NULL; \
} else { \
⑵ __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \
} \
__t; \
})
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
8.2 LOS_ListRemoveHeadType
函数宏中的三个参数分别为:业务结构体类型名称type
,作为结构体成员的双向链表成员变量名称element
,双向链表头节点指针list
。通过调用该宏函数LOS_ListRemoveHeadType
即可以获取双向链表第一个业务链表节点所在的业务结构体的内存地址,并把第一个业务链表节点从双向链表中删除。
⑴处表示如果是只有头链表结点的空双向循环链表,则返回NULL。⑵如果链表不为空,获取业务结构体的内存地址,然后调用LOS_ListDelete
删除链表节点。
源码如下:
#define LOS_ListRemoveHeadType(list, type, element) ({ \
type *__t; \
if ((list)->pstNext == list) { \
⑴ __t = NULL; \
} else { \
⑵ __t = LOS_DL_LIST_ENTRY((list)->pstNext, type, element); \
LOS_ListDelete((list)->pstNext); \
} \
__t; \
})
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
8.3 LOS_ListNextType
函数宏中的四个参数分别为:业务结构体类型名称type
,作为结构体成员的双向链表成员变量名称element
,双向链表头节点指针list
,双向链表中的一个节点item
。通过调用该宏函数LOS_ListNextType
即可以获取双向链表指定链表节点的下一个节点所在的业务结构体的内存地址。
⑴处表示如果指定链表节点的下一个节点是头结点,则返回NULL。否则执行⑵,获取指定链表节点的下一个节点所在的业务结构体的内存地址。
源码如下:
#define LOS_ListNextType(list, item, type, element) ({ \
type *__t; \
if ((item)->pstNext == list) { \
⑴ __t = NULL; \
} else { \
⑵ __t = LOS_DL_LIST_ENTRY((item)->pstNext, type, element); \
} \
__t; \
})
class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
9 遍历包含双向链表的结构体
双向链表提供三个宏定义来遍历包含双向链表成员的结构体,LOS_DL_LIST_FOR_EACH_ENTRY
、LOS_DL_LIST_FOR_EACH_ENTRY_SAFE
和LOS_DL_LIST_FOR_EACH_ENTRY_HOOK
。OpenHarmony LiteOS-M
内核源码分析时,已经分析过这3个宏。
小结
掌握鸿蒙轻内核的双向循环链表LOS_DL_LIST
这一重要的数据结构,会给进一步学习、分析鸿蒙轻内核源代码打下了基础,让后续的学习更加容易。
如果大家想更加深入的学习 OpenHarmony 开发的内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

- 搭建开发环境
- Windows 开发环境的搭建
- Ubuntu 开发环境搭建
- Linux 与 Windows 之间的文件共享
- ……

- 构建子系统
- 启动流程
- 子系统
- 分布式任务调度子系统
- 分布式通信子系统
- 驱动子系统
- ……



data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/maniuT/article/details/139598879","extend1":"pc","ab":"new"}">>
id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"> class="blog_extension blog_extension_type2" id="blog_extension">
class="extension_official" data-report-click="{"spm":"1001.2101.3001.6471"}" data-report-view="{"spm":"1001.2101.3001.6471"}">
class="blog_extension_card_left">
class="blog_extension_card_cont">
鸿蒙开发学习资料领取!!!
class="blog_extension_card_cont_r">
微信名片
评论记录:
回复评论: