在linux内核list.h中包含了关于LRU链表的很多操作,可以方便调用。在此总结如下。(linux版本为4.3)
一、初始化
1. 初始化链表头:
a) LIST_HEAD(name)
b) INIT_LIST_HEAD(struct list_head *list)
二、添加
1. 在链表头添加:
list_add(struct list_head *new, struct list_head *head)b)
2. 在链表尾添加:
list_add_tail(struct list_head *new, struct list_head*head)
三、删除
1. 删除某元素:
list_del(struct list_head *entry)
2. 删除某元素,并初始化:
list_del_init(struct list_head *entry)
四、替换
1. 替换某旧元素为新元素:
list_replace(struct list_head *old,
structlist_head *new)
2. 替换某旧元素为新元素,并初始化旧元素:
list_replace_init(struct list_head *old,
struct list_head *new)
五、迁移
1. 将某旧元素从旧链表加到新链表头,旧链表中将其删除:
list_move(struct list_head *list, struct list_head*head)
2. 将某旧元素从旧链表加到新链表尾,旧链表中将其删除:
list_move_tail(struct list_head *list,
struct list_head *head)
六、判断
1. 是否某元素在链表尾:
list_is_last(conststruct list_head *list,
const struct list_head *head)
2. 是否链表为空:
list_empty(const struct list_head *head)
3. 双重判断是否链表为空:
list_empty_careful(const struct list_head *head)
4. 是否链表只有一个元素:
list_is_singular(const struct list_head *head)
七、特殊
1. 将链表头元素放到链表尾:
list_rotate_left(struct list_head *head)
2. 将链表按某元素分为两个链表:
list_cut_position(struct list_head *list,
structlist_head *head, struct list_head *entry)
3. 将两个链表合并为一个链表(插入到head与head->next之间位置):
a) list_splice(const struct list_head *list,
struct list_head *head)
b) list_splice_init(struct list_head *list,
struct list_head *head)
4. 将两个链表合并为一个链表(插入到head->prev与head之间位置):
a) list_splice_tail(struct list_head *list,
structlist_head *head)
b) list_splice_tail_init(struct list_head *list,
struct list_head *head)
5. 链表遍历(尾到头)for循环:
a) list_for_each(pos, head)
b) list_for_each_safe(pos, n, head)
6. 链表遍历(头到尾)for循环:
a) list_for_each_prev(pos, head)
b) list_for_each_prev_safe(pos, n, head)
7. 链表遍历(头到尾)for循环,获取每一个元素:
a) list_for_each_entry(pos, head, member)
b) list_for_each_entry_safe(pos, n, head, member)
8. 链表遍历(尾到头)for循环,获取每一个元素:
a) list_for_each_entry_reverse(pos, head, member)
b) list_for_each_entry_safe_reverse(pos, n, head, member)
9. 链表遍历(从某元素之后开始向尾)for循环,获取每一个元素:
a) list_for_each_entry_continue(pos, head, member)
b) list_for_each_entry_safe_continue(pos, n, head, member)
10. 链表遍历(从某元素之前开始向头)for循环,获取每一个元素:
list_for_each_entry_continue_reverse(pos, head, member)
11. 为上面两个遍历,准备一个元素:
list_prepare_entry(pos, head, member)
12. 链表遍历(从某元素开始向尾)for循环,获取每一个元素:
a) list_for_each_entry_from(pos, head, member)
b) list_for_each_entry_safe_from(pos, n, head, member)
13. 链表遍历(从某元素开始向头)for循环,获取每一个元素:
list_for_each_entry_safe(pos, n, head, member)
八、查询
1. 查询该元素:
list_entry(ptr, type, member)
2. 查询链表第一个元素:
a) list_first_entry(ptr, type, member)
b) list_first_entry_or_null(ptr, type, member)
3. 查询链表最后一个元素:
list_last_entry(ptr, type, member)
4. 查询链表中某元素的下一个元素:
list_next_entry(pos, member)
5. 查询链表中某元素的上一个元素:
list_prev_entry(pos, member)
这里只列出了对应kernel版本常用的list函数,对于新版本可到对应list.h进行查看。