在学习OpenHarmony
鸿蒙轻内核源代码的时候,常常会遇到一些数据结构的使用。如果没有掌握它们的用法,会导致阅读源代码时很费解、很吃力。本文会给读者介绍源码中重要的数据结构,双向循环链表Doubly Linked List
。在讲解时,会结合数据结构相关绘图,培养读者们的数据结构的平面想象能力,帮助更好的学习和理解这些数据结构的用法。
本文中所涉及的源码,以OpenHarmony LiteOS-A
内核为例,均可以在开源站点 https://gitee.com/openharmony/kernel_liteos_a 获取。
1 双向循环链表
双向循环链表Doubly Linked List
的源代码在kernel\include\los_list.h
双向链表头文件中,包含LOS_DL_LIST
结构体定义、inline
内联函数LOS_ListXXX
,还有相关的函数宏定义LOS_DL_LIST_XXXX
。双向链表头文件可以网页访问 kernel/include/los_list.h ,也可以检出到本地阅读。
1.1 双向链表结构体
双向链表节点结构体LOS_DL_LIST
定义如下。双向链表的定义,如何使用,这在OpenHarmony LiteOS-A
内核和OpenHarmony LiteOS-M
内核里是一致的,不再赘述。
typedef struct LOS_DL_LIST {
struct LOS_DL_LIST *pstPrev; /** 指向当前链表节点的前驱节点的指针 */
struct LOS_DL_LIST *pstNext; /** 指向当前链表节点的后继节点的指针 */
} LOS_DL_LIST;
2 初始化双向链表
OpenHarmony LiteOS-A
内核和OpenHarmony LiteOS-M
内核中的双向链表的初始化也是一致的,都提供了内联函数LOS_ListInit()
,还提供了一个相同功能的函数式宏LOS_DL_LIST_HEAD
。可以查看OpenHarmony LiteOS-M
内核源码剖析的双向链表部分。
3 判断空链表
3.1 LOS_ListEmpty(LOS_DL_LIST *list)
该内联函数用于判断链表是否为空。和OpenHarmony LiteOS-M
内核的函数一致。
源码如下:
LITE_OS_SEC_ALW_INLINE STATIC INLINE BOOL LOS_ListEmpty(LOS_DL_LIST *list)
{
return (BOOL)(list->pstNext == list);
}
4 插入双向链表节点
双向链表提供三种链表节点插入方法,在指定链表节点后面插入LOS_ListAdd
、尾部插入LOS_ListTailInsert
、头部插入LOS_ListHeadInsert
。在头部插入的节点,从头部开始遍历时第一个遍历到,从尾部插入的节点,最后一个遍历到。OpenHarmony LiteOS-A
内核除了提供链表节点插入还提供了方法把一个链表插入另外一个双向链表的方法,在指定链表节点后面插入新链表LOS_ListAddList
、尾部插入新链表LOS_ListTailInsertList
、头部插入新链表LOS_ListHeadInsertList
。
4.1 INLINE VOID LOS_ListAddList(LOS_DL_LIST *oldList, LOS_DL_LIST *newList)
该内联函数往双向链表节点*oldList