linux内核_list
概述
内核有一个include/linux/list.h头文件是一个经典简单的双向连表实现,在内核使用及其广泛。
list使用方式:
- 将list结构体list_head定义在私有结构体的任意位置
struct rapl_pmu { raw_spinlock_t lock; int n_active; int cpu; struct list_head active_list; //> 在私有结构体中添加链表结构体 struct pmu *pmu; ktime_t timer_interval; struct hrtimer hrtimer; };
- 调用list链表操作接口,即可将操作链表
list应用场景:
- 需要通过连表存储数据
- 需要增,删,改,查的连表操作
- 简化链表操作
常用接口说明
- LIST_HEAD_INIT: 初始化节点,会将next,prev指针指向实例本身地址, 声明实例时使用 | INIT_LIST_HEAD: 初始化节点, 内链函数实现
#define LIST_HEAD_INIT(name) { &(name), &(name) }
- LIST_HEAD: 定义一个list_head实例并初始化
#define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name)
- list_add_tail: 追加节点到链表尾部
- list_del: 从链表中将当前节点删除
- list_empty: 空链表判断 | list_empty_careful 比前者判断更加严谨
- list_entry: 从成员(这里指list成员)的地址获取结构体的地址,同container_of
#define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ !__same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); })
- list_for_each: 遍历链表(仅读)
- list_for_each_safe: 遍历链表(有珊链表操作时使用)
使用场景举例
linux-5.9/fs/ext4/super.c
printk(KERN_ERR "sb_info orphan list:\n");
list_for_each(l, &sbi->s_orphan) {
struct inode *inode = orphan_list_entry(l);
printk(KERN_ERR " "
"inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
inode->i_sb->s_id, inode->i_ino, inode,
inode->i_mode, inode->i_nlink,
NEXT_ORPHAN(inode));
}
"list_for_each(l, &sbi->s_orphan)" : 等同for循环,将复杂的判断和迭代过程封装, 便于使用# 概述
内核有一个include/linux/list.h头文件是一个简单的双向连表实现,在内核使用及其广泛。
list使用方式:
- 将list结构体list_head定义在私有结构体的任意位置
struct rapl_pmu { raw_spinlock_t lock; int n_active; int cpu; struct list_head active_list; //> 在私有结构体中添加链表结构体 struct pmu *pmu; ktime_t timer_interval; struct hrtimer hrtimer; };
- 调用list链表操作接口,即可将操作链表
list应用场景:
- 需要通过连表存储数据
- 需要增,删,改,查的连表操作
- 简化链表操作
常用接口说明
- LIST_HEAD_INIT: 初始化节点,会将next,prev指针指向实例本身地址 | 声明实例时使用
#define LIST_HEAD_INIT(name) { &(name), &(name) }
- INIT_LIST_HEAD: 初始化节点, 内链函数实现
- LIST_HEAD: 定义一个list_head实例并初始化
#define LIST_HEAD(name) \ struct list_head name = LIST_HEAD_INIT(name)
- list_add_tail: 追加节点到链表尾部
- list_del: 从链表中将当前节点删除
- list_empty: 空链表判断 | list_empty_careful 比前者判断更加严谨
- list_entry: 从成员(这里指list成员)的地址获取结构体的地址,同container_of
#define container_of(ptr, type, member) ({ \ void *__mptr = (void *)(ptr); \ BUILD_BUG_ON_MSG(!__same_type(*(ptr), ((type *)0)->member) && \ !__same_type(*(ptr), void), \ "pointer type mismatch in container_of()"); \ ((type *)(__mptr - offsetof(type, member))); })
- list_for_each: 遍历链表(仅读)
- list_for_each_safe: 遍历链表(有珊链表操作时使用)
使用场景举例
linux-5.9/fs/ext4/super.c
printk(KERN_ERR "sb_info orphan list:\n");
list_for_each(l, &sbi->s_orphan) {
struct inode *inode = orphan_list_entry(l);
printk(KERN_ERR " "
"inode %s:%lu at %p: mode %o, nlink %d, next %d\n",
inode->i_sb->s_id, inode->i_ino, inode,
inode->i_mode, inode->i_nlink,
NEXT_ORPHAN(inode));
}
"list_for_each(l, &sbi->s_orphan)" : 等同for循环,将复杂的判断和迭代过程封装, 便于使用
本文来自博客园,作者:whilewell,转载请注明原文链接:https://www.cnblogs.com/viiv/p/16336240.html