MS-RTOS 链表

更新时间:
2023-08-09
下载文档

MS-RTOS 链表

本章将介绍 MS-RTOS 链表的使用。

MS-RTOS 实现了一个双向循环链表,除了在 MS-RTOS 内部广泛使用外,MS-RTOS 的应用程序也可以使用该双向循环链表。

链表介绍

双向循环链表的链头和节点都是 ms_list_head_t 类型,它可以是一个全局变量,也可以嵌入到其它数据类型当中(如结构体)作为一个成员变量。只要得到节点的地址(节点的指针),就可以使用形如 MS_CONTAINER_OF(pnode, xxx_struct, xxx_member) 的宏来获得容器(如结构体)的地址(容器的指针)。

链表的遍历有两个宏: ms_list_for_eachms_list_for_each_safe

  • ms_list_for_each_safe 是安全的,这里的安全指的是链表遍历过程如果有节点删除操作,链表遍历是安全的;
  • ms_list_for_each 是不安全的。

可以根据需要选择合适的链表遍历宏。

注意

以下的链表操作都不是线程安全的,如果需要线程安全,请在链表操作的外部加锁(如互斥量)。

链表相关数据类型

类型描述
ms_list_head_t双向链表节点类型

ms_list_head_t

MS-RTOS 中使用的通用双向链表节点类型为 ms_list_head_t,链表节点使用前需要定义,它可以是一个全局变量,也可以嵌入到其它数据类型当中(如结构体)作为一个成员变量。全局链表可以使用宏 MS_LIST_HEAD 进行定义,另外可以使用宏 MS_LIST_HEAD_INIT 对链表进行初始化。

typedef struct ms_list_head {
    struct ms_list_head *next;
    struct ms_list_head *prev;
} ms_list_head_t;
参数说明
next指向下一个节点
prev指向前一个节点

链表相关 API

下表展示了链表相关的 API 在两个权限空间下是否可用:

API用户空间内核空间
MS_LIST_HEAD
MS_LIST_HEAD_INIT
ms_list_is_empty
ms_list_is_head
ms_list_is_tail
ms_list_is_only_one
ms_list_add
ms_list_add_tail
ms_list_del
ms_list_del_init
ms_list_for_each
ms_list_for_each_safe

MS_LIST_HEAD()

  • 描述 定义一个链表

  • 宏实现

#define MS_LIST_HEAD(name) \
ms_list_head_t (name) = { &(name), &(name)}
  • 参数
输入/输出参数描述
[in]name链表变量名
  • 返回值

  • 注意事项

  • 示例

MS_LIST_HEAD_INIT()

  • 描述 初始化链表

  • 宏实现

#define MS_LIST_HEAD_INIT(p) \
    do {                     \
        (p)->next = (p);     \
        (p)->prev = (p);     \
    } while (0)
  • 参数
输入/输出参数描述
[in]p链表的指针
  • 返回值

  • 注意事项

  • 示例

ms_list_is_empty()

  • 描述 判断一个链表是否为空

  • 函数原型

static MS_FORCE_INLINE ms_bool_t ms_list_is_empty(const ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]list链表的指针
  • 返回值 MS_TRUE:链表为空,MS_FALSE:链表不为空

  • 注意事项

  • 示例

ms_list_is_head()

  • 描述 判断一个节点是否为链表的表头

  • 函数原型

static MS_FORCE_INLINE ms_bool_t ms_list_is_head(const ms_list_head_t *entry, 
                                                   const ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]entry节点
[in]list链表的指针
  • 返回值 MS_TRUE:节点是链表的表头,MS_FALSE:节点不是链表的表头

  • 注意事项

  • 示例

ms_list_is_tail()

  • 描述 判断一个节点是否为链表的末尾

  • 函数原型

static MS_FORCE_INLINE ms_bool_t ms_list_is_tail(const ms_list_head_t *entry, 
                                                   const ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]entry节点
[in]list链表指针
  • 返回值 MS_TRUE:节点是链表的末尾,MS_FALSE:节点不是链表的末尾

  • 注意事项

  • 示例

ms_list_is_only_one()

  • 描述 判断一个节点是否为链表的唯一节点

  • 函数原型

static MS_FORCE_INLINE ms_bool_t ms_list_is_only_one(const ms_list_head_t *entry, 
                                                       const ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]entry节点
[in]list链表的指针
  • 返回值 MS_TRUE:节点是链表的唯一节点,MS_FALSE:节点不是链表的唯一节点

  • 注意事项

  • 示例

ms_list_add()

  • 描述 在链表头插入一个节点

  • 函数原型

static MS_FORCE_INLINE void ms_list_add(ms_list_head_t *new_entry, 
                                          ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]new_entry需要插入的节点
[in]list链表的指针
  • 返回值

  • 注意事项

  • 示例

ms_list_add_tail()

  • 描述 在链表末尾插入一个节点

  • 函数原型

static MS_FORCE_INLINE void ms_list_add_tail(ms_list_head_t *new_entry, 
                                               ms_list_head_t *list);
  • 参数
输入/输出参数描述
[in]new_entry需要插入的节点
[in]list链表的指针
  • 返回值

  • 注意事项

  • 示例

ms_list_del()

  • 描述 从链表中移除一个节点

  • 函数原型

static MS_FORCE_INLINE void ms_list_del(ms_list_head_t *const entry);
  • 参数
输入/输出参数描述
[in]entry需要移除的节点
  • 返回值

  • 注意事项 被移除的节点的 prev、next 指针仍指向原节点

  • 示例

ms_list_del_init()

  • 描述 从链表中移除一个节点,并更新被移除节点中的 prev、next 指针

  • 函数原型

static MS_FORCE_INLINE void ms_list_del_init(ms_list_head_t *entry);
  • 参数
输入/输出参数描述
[in]entry需要移除的节点
  • 返回值

  • 注意事项 被移除的节点的 prev、next 指针指向 NULL

  • 示例

ms_list_for_each()

  • 描述 非安全方式遍历一个链表

  • 宏实现

#define ms_list_for_each(itervar, list) \
    for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
  • 参数
输入/输出参数描述
[in]itervar临时迭代变量
[in]list链表的指针
  • 返回值

  • 注意事项

  • 示例

ms_list_for_each_safe()

  • 描述 安全方式遍历一个链表

  • 宏实现

#define ms_list_for_each_safe(itervar, save_var, list) \
    for (itervar = (list)->next, save_var = (list)->next->next; \
        itervar != (list); \
        itervar = save_var, save_var = save_var->next)
  • 参数
输入/输出参数描述
[in]itervar临时迭代变量
[in]save_var临时保存变量
[in]list链表的指针
  • 返回值

  • 注意事项

  • 示例

文档内容是否对您有所帮助?
有帮助
没帮助