鸿蒙轻内核M核源码分析系列一 数据结构-双向循环链表

在学习OpenHarmony鸿蒙轻内核源代码的时候,常常会遇到一些数据结构的使用。如果没有掌握它们的用法,会导致阅读源代码时很费解、很吃力。本文会给读者介绍源码中重要的数据结构,双向循环链表Doubly Linked List。在讲解时,会结合数据结构相关绘图,培养读者们的数据结构的平面想象能力,帮助更好的学习和理解这些数据结构的用法。

1 双向循环链表

双向链表LOS_DL_LIST的源代码在utils\los_list.h双向链表头文件中,包含LOS_DL_LIST结构体定义、inline内联函数LOS_ListXXX,还有相关的函数宏定义LOS_DL_LIST_XXXX。双向链表头文件可以网页访问utils/los_list.h,也可以检出到本地阅读。


1.1 双向链表结构体

双向链表节点结构体LOS_DL_LIST定义如下。其结构非常简单、通用、抽象,只包含前驱、后继两个节点,负责承上启下的双向链表作用。双向链表不包含任何业务数据信息,一般不会单独使用。通常,双向链表节点和业务数据信息作为结构体成员,一起组成业务结构体来使用,使用示例稍后会有讲述。

typedef struct LOS_DL_LIST {
    struct LOS_DL_LIST *pstPrev; /** 指向当前链表节点的前驱节点的指针 */
    struct LOS_DL_LIST *pstNext; /** 指向当前链表节点的后继节点的指针 */
} LOS_DL_LIST;

从双向链表中的任意一个节点开始,都可以很方便地访问它的前驱节点和后继节点,这种环状数据结构形式使得双向链表在查找、插入、删除等操作上非常方便。业务场景使用双向链表时,可以定义一个LOS_DL_LIST类型的全局变量作为双向循环链表Head头结点,业务结构体的链表成员节点依次挂载在头结点上。还有些业务结构体的双向链表节点作为Head头节点,依次挂载其他业务结构体的链表成员节点。从Head节点可以依次遍历下一个节点,Head节点的前驱节点就是Tail尾节点。

下面通过鸿蒙轻内核代码中互斥锁结构体LosMuxCB定义,来了解如何使用双向链表结构体:

typedef struct {
    UINT8 muxStat;       /**< 互斥锁状态  */
    UINT16 muxCount;     /**< 互斥锁当前被持有的次数 */
    UINT32 muxID;        /**< 互斥锁编号ID */
    LOS_DL_LIST muxList; /**< 互斥锁的双向链表 */
    LosTaskCB *owner;    /**< 当前持有锁的任务TCB */
    UINT16 priority;     /**< 持有互斥锁的任务优先级 */
} LosMuxCB;

互斥锁结构体中包括双向链表LOS_DL_LIST muxList成员变量和其他包含互斥锁业务信息的成员变量,这里通过双向链表把各个互斥锁链接起来,挂载在头结点LOS_DL_LIST g_unusedMuxList;通过其他业务成员变量承载业务数据,链表和其他业务成员关系如下图所示:


2 初始化双向链表

2.1 LOS_ListInit(LOS_DL_LIST *list)

LOS_DL_LIST的两个成员pstPrevpstNext, 是LOS_DL_LIST结构体类型的指针。需要为双向链表节点申请长度为sizeof(LOS_DL_LIST)的一段内存空间。为链表节点申请到内存后,可以调用初始化LOS_ListInit(LOS_DL_LIST *list)方法,把这个节点链接为环状的双向链表。初始化链表时,只有一个链表节点,这个节点的前驱和后继节点都是自身。链表节点初始化为链表,如图所示:

源码如下:

LITE_OS_SEC_ALW_INLINE STATIC INLINE VOID LOS_ListInit(LOS_DL_LIST *list)
{
    list->pstNext = list;
    list->pstPrev = list;
}

2.2 LOS_DL_LIST_HEAD(LOS_DL_LIST list)

除了LOS_ListInit(),还提供了一个相同功能的函数式宏LOS_DL_LIST_HEAD,通过直接定义一个双向链表节点,实现将该节点初始化为双向链表。区别于LOS_ListInit(),在调用函数式宏前,不需要动态申请内存空间。

#define LOS_DL_LIST_HEAD(list) LOS_DL_LIST li
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值