1.概述
链表是在程序设计过程中经常使用的数据结构,bcos系统内部的调度和tasklet的实现都是基于链表。所以,对链表的支持是bcos与生俱来的特性。bcos的链表设计参考了Linux内核链表的设计思想,如果用户想使用链表只需要在自己的数据结构中包含链表头,然后便可以开始使用链表来实现自己的数据结构了。
2.双向循环链表
下面展示了双向循环链表的所有接口并附有简单的解释。每个接口的参数都易于理解,读者很容易理解并使用接口实现利用双向循环链表进行数据的管理。
链表头:
struct list_head{
struct list_head *next, *prev;
};
初始化链表:
//静态初始化链表
#define LIST_HEAD_INIT(name) \
{ \
&(name), \
&(name), \
}
//定义并静态初始化链表
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)
//动态初始化链表
static inline void INIT_LIST_HEAD(struct list_head *list)
链表节点的添加
//将新节点添加到head后面,如果head为链表头则将新节点添加到链表的最前面
static inline void list_add(struct list_head *new_, struct list_head *head)
//将新节点添加到head前面,如果head为链表头则将新节点添加到链表的最后面
static inline void list_add_tail(struct list_head *new_, struct list_head *head)
链表节点的删除
//将节点从链表中删除并将该节点的prev和next指针赋值为NULL
static inline void list_del(struct list_head *entry)
//将节点从链表中删除并将该节点的prev和next指针指向它自己
static inline void list_del_init(struct list_head *entry)
链表遍历
//从链表头遍历到链表尾
/**
* list_for_each_entry_safe - iterate over list of given type safe against
* removal of list enty.
* @pos: the type * to use as a loop sursor.
* @n: another type * to use as temporary storage.
* @head: the head for your list.
* @member: the name of the list_struct within the strut.
*/
#define list_for_each_entry_safe(pos, n, head, member)
//从链表尾逆向遍历到链表头
/**
* list_for_each_entry_safe_reverse
* @pos: the type * to use as a loop cursor.
* @n another type * to use as temporary storage.
* @head: the head for your list.
* @member: the name of the list_struct within the struct.
*
* Iterate backwards over list of given type, safe against removal
* of list entry.
*/
#define list_for_each_entry_safe_reverse(pos, n, head,member)
获取链表的第一个节点
/**
* list_first_entry - get the first element from a list.
* @ptr: the list head to take the element from.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_struct within the struct.
*
* Note, that list is expected to be not empty.
*/
#define list_first_entry(ptr, type, member)
判断是否是链表最后一个节点
/**
* list_is_last - tests whether @list is the last entry in list @head
* @list: the entry to test.
* @head: the head of the list.
*/
static inline int list_is_last(const struct list_head *list,
const struct list_head *head)
判断链表是否为空
/**
* list_empty - tests whether a list is empty.
* @head: the list to test.
*/
static inline int list_empty(const struct list_head *head)
以链表中某个元素为依据,升序的插入节点
/**
* 在列表中升序插入,值更小的靠近链表头
*/
#define list_ascending_order_add(new_, pos, n, head, member, condition_member)
3.单向循环链表
单向循环链表的实现与双向循环链表类似,它的接口实现与双向循环链表也基本类似。接口如下:
链表头及初始化:
typedef struct slist_s {
struct slist_s *next;
}slist_t;
//链表的静态初始化
#define SLIST_HEAD_INIT(name) {&name}
//链表的动态初始化
static inline void slist_init_head(slist_t *head)
链表添加一个节点
//将新节点添加到head的后面
static inline void slist_add(slist_t *new_, slist_t *head)
链表删除节点:
//仅将节点从链表中移除,需要提供将被删除节点的上一个节点
static inline void slist_del(slist_t *prev, slist_t *node)
//将节点从链表中移除并初始化(将节点的next指针指向节点自己)
static inline void slist_del_init(slist_t *prev, slist_t *node)
判断节点是否是链表的最后一个节点
/*
* list:被判断的链表节点
* head:链表头
*/
static inline int slist_is_last(const slist_t *list, const slist_t *head)
判断链表是否为空
static inline int slist_empty(const slist_t *head)
对链表进行遍历
#define slist_for_each_entry_safe(pos, n, head, member)
单向循环链表的使用示例具体可以参考内存管理模块的实现。