本文仅仅记录比较常用的操作内核链表接口
static inline void __list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
struct list_head *new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = new_first;
new_first->prev = head;
}
/**
* list_cut_position - cut a list into two
* @list: a new list to add all removed entries
* @head: a list with entries
* @entry: an entry within head, could be the head itself
* and if so we won't cut the list
*
* This helper moves the initial part of @head, up to and
* including @entry, from @head to @list. You should
* pass on @entry an element you know is on @head. @list
* should be an empty list or a list you do not care about
* losing its data.
*
*/
/* 该函数是将head头结点的链表切隔为两个链表,分割点为entry, list是一个
* 新的链表头,list后面的第一个节点是原head头节点的第一个节点,list的尾节点
* 是entry节点。原head链表的首节点变为entry的下一个节点,head链表的尾节点还是原来的尾节点。
*/
static inline void list_cut_position(struct list_head *list,
struct list_head *head, struct list_head *entry)
{
if (list_empty(head))
return;
if (list_is_singular(head) &&
(head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}
static inline void __list_splice(const struct list_head *list,
struct list_head *prev,
struct list_head *next)
{
struct list_head *first = list->next;
struct list_head *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
/**
* list_splice - join two lists, this is designed for stacks
* @list: the new list to add.
* @head: the place to add it in the first list.
*/
/* 将list链表中的节点添加到head的头部,此时list就只是一个空的链表头 */
static inline void list_splice(const struct list_head *list,
struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head, head->next);
}
/**
* container_of - cast a member of a structure out to the containing structure
* @ptr: the pointer to the member.
* @type: the type of the container struct this is embedded in.
* @member: the name of the member within the struct.
*
*/
/* 该函数实现原理就是利用偏移 */
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
/**
* list_entry - get the struct for this entry
* @ptr: the &struct list_head pointer.
* @type: the type of the struct this is embedded in.
* @member: the name of the list_head within the struct.
*/
/* 该函数的功能是根据结构体中的某个成员地址,得到该结构体的首地址,使用结构体的
* 首地址可以访问结构体中的其他成员。
* ptr是结构体中的成员地址,也就是member的地址
* type是结构体的类型,member是list_head结构体类型的名字。
*/
#define list_entry(ptr, type, member) \
container_of(ptr, type, 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_head within the struct.
*
* Note, that list is expected to be not empty.
*/
/* 获得链表头的第一个节点,ptr一般是链表头的list_head地址 */
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
/**
* list_last_entry - get the last 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_head within the struct.
*
* Note, that list is expected to be not empty.
*/
/* 获得链表头的最后一个节点,ptr一般是链表头的list_head地址 */
#define list_last_entry(ptr, type, member) \
list_entry((ptr)->prev, type, member)
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
/* 用于遍历head链表的所有成员,pos是中间临时变量,从链表中取出的每个节点使用pos变量临时保存
* 遍历过程是从head的下一个节点开始依次遍历。这种方式有一个缺点:就是在使用list_del(pos)时,
* pos的前驱指针和后继指针都指向了非法地址,因此无法执行pos = pos->next。
*/
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); pos = pos->next)
/**
* list_for_each_prev - iterate over a list backwards
* @pos: the &struct list_head to use as a loop cursor.
* @head: the head for your list.
*/
/* 用于遍历head链表的所有成员,pos是中间临时变量,从链表中取出的每个节点使用pos变量临时保存
* 遍历过程是从head的上一个节点开始依次遍历,也就是反向遍历。
*/
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
/**
* list_for_each_safe - iterate over a list safe against removal of list entry
* @pos: the &struct list_head to use as a loop cursor.
* @n: another &struct list_head to use as temporary storage
* @head: the head for your list.
*/
/* 带有safe的接口,就防止了list_for_each接口不能删除pos节点的问题,因为该接口中有两个临时节
* 点。pos是当前使用的临时节点,n是pos的下一个节点,当删除pos节点后,依然可以得到pos的后一个节
* 点。 因此带有safe的接口,是可以执行删除操作的。而list_for_each接口是不能执行list_del(pos)
* 操作的。
*/
#define list_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
/**
* list_for_each_entry - iterate over list of given type
* @pos: the type * to use as a loop cursor.
* @head: the head for your list.
* @member: the name of the list_head within the struct.
*/
/* 该接口是依次从head链表中正向取出元素,但是该接口不能删除pos,原因list_entry */
#define list_for_each_entry(pos, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member); \
&pos->member != (head); \
pos = list_next_entry(pos, member))
/**
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
* @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_head within the struct.
*/
/* 该接口与list_for_each_entry接口功能相同,但是此接口可以适用于删除pos节点 */
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_first_entry(head, typeof(*pos), member), \
n = list_next_entry(pos, member); \
&pos->member != (head); \
pos = n, n = list_next_entry(n, member))