首页 > 其他分享 >内核链表常用宏——container_of()

内核链表常用宏——container_of()

时间:2024-08-13 21:05:58浏览次数:11  
标签:member container struct list 链表 内核 type ptr 结构

定义

#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)

#define container_of(ptr, type, member) ({			\
	const typeof( ((type *)0)->member ) *__mptr = (ptr);	\
	(type *)( (char *)__mptr - offsetof(type,member) );})

container_of(ptr, type, member)

  • 作用:通过小结构体地址得到其所在的大结构体地址

  • 参数:

    • ptr:从外面输入进来的小结构体指针struct list_head*)(即小结构体的首地址)
    • type:大结构体类型(struct kernel
    • member:大结构体中的小结构体变量的名字(list
  • 使用:

    struct kernel
    {
        datatype data;
        struct list_head list; 
    };
    
    struct list_head *p = (struct list_head *)0x22; 		// 假设小结构体地址为0x22
    struct kernel *xp = list_entry(p, struct kernel, list); // 得到大结构体地址
    
  • 在linux中,依次执行每个语句,然后将最后一条语句的值作为整个的值

    #define xx ({;;;}) 
    
  • 详细分析:

    • const typeof( ((type *)0)->member ) *__mptr = (ptr);

      • typestruct kernelmember为小结构体变量的名字list

      • typeof( ((type *)0)->member )得到小结构体的类型

        • ((TYPE *)0) 将0转换为struct kernel类型的结构体指针,换句话说就是让编译器认为这个结构体是开始于程序段起始位置0
        • (((type *)0)->member) 引用结构体中list成员
      • 整条语句等价于const struct list_head *__mptr = (ptr);

      • 总结:用typeof()获取结构体里list成员属性的类型,然后定义一个该类型的临时指针变量__mptr,并将ptr所指向的list的地址赋给__mptr

        为什么不直接使用 ptr 而要多此一举呢?我想可能是为了避免对 ptr 及prt 指向的内容造成破坏。

    • (type *)( (char *)__mptr - offsetof(type,member) );

      • offsetof(type,member),即((size_t) &((TYPE *)0)->MEMBER)

        • (TYPE *)0 首先将地址 0 强制转换为 struct kernel 类型的指针。这是一个虚拟的地址操作,目的是在逻辑上构建一个指向 struct kernel 类型的指针,但实际上并不真的访问地址 0

        • &((TYPE *)0)->MEMBER 接着取这个虚拟指针所指向的结构体中 list 成员的地址。由于是从地址 0 开始计算,所以得到的地址值实际上就是 list 成员在 struct kernel 结构体中的偏移量

        • 得到小结构体起始位置 到大结构体的起始位置之间的字节数

      • 通过小结构体指针 __mptr 减去(小结构体起始位置到大结构体的起始位置之间的字节数),得到了大结构体的地址

标签:member,container,struct,list,链表,内核,type,ptr,结构
From: https://www.cnblogs.com/General-xd/p/18357684

相关文章

  • windows核心编程 第三章,跨越进程边界共享内核对象,对象句柄的继承性,改变句柄的标志,命名
    windows核心编程3.3跨越进程边界共享内核对象3.3.1对象句柄的继承性3.3.2改变句柄的标志3.3.3命名对象3.3.4终端服务器的名字空间3.3.5复制对象句柄文章目录windows核心编程3.3跨越进程边界共享内核对象3.3.1对象句柄的继承性3.3.2改变句柄的标志3.3.3命名......
  • [YM]模板-单链表(超详细简洁模板)
    概念:链表是一种用于存储数据的数据结构,通过如链条一般的指针来连接元素。它的特点是插入与删除数据十分方便,但寻找与读取数据的表现欠佳,复杂度几乎是O(n)但其还是有很大的重要性是数据结构的开端模板:题目概述:相信大家对于单链表的操作已经游刃有余了,我们知道,对于一个单......
  • 让程序既能正序也能逆序显示电影列表。使用双向链表
    /让程序既能正序也能逆序显示电影列表。使用双向链表/#include<stdio.h>#include<stdlib.h>#include<string.h>typedefstructMovie{chartitle[100];structMovie*prev;structMovie*next;}Movie;typedefstructMovieList{Movie*head;......
  • containerd配置镜像加速器
    目录Containerd配置镜像加速器1.旧版本配置方法1.1生成containerd配置文件1.2修改配置文件2.新版本配置方法2.1创建目录2.2配置加速器3.测试拉取镜像Containerd配置镜像加速器为什么要给containerd配置镜像加速器?因为k8s1.24以后的容器运行时是containerd,也就是说k8s会......
  • 【Linux系列】内核参数
    sysctl命令常用参数RAID性能参数调优网络协议栈调整:单位是字节TCP并发性能优化对于用不上IPV6的建议直接禁用TCPkeepalive时长控制memoryOOM控制安全防护模块保障TCP通信质量IO密集性服务器优化参数路由器选项控制路由机制控制内存大页面使用策略内核参数主要......
  • 单链表与双链表的代码实现
    单链表链表的概念链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表比数组的优势在于,它可以提供高效的重排数据的能力。这种灵活性的代价是不能快速访问表中的任意数据项,访问链表中数据项的唯一方式是沿着链表,一个......
  • C++提高编程—4、STL常用容器—list(链表)和queue(队列)
    7list容器 7.1基本概念 7.2 构造函数 7.3 赋值和交换 7.4 大小操作  使用10000来填充。7.5 插入与删除 7.6 数据存取 7.7 反转与排序  8set/multset容器 7.1基本概念7.2 构造和赋值7.3大小和交换7.4 插入与删除7.5 查......
  • 记一次TCP请求游戏服接口偶发超时问题处理:Linux内核网络参数调优
    记一次TCP请求游戏服接口偶发超时问题处理:Linux内核网络参数调优原创 国文 三七互娱技术团队  2024年07月08日18:00 广东 听全文01问题现象A云主机公网访问B云游戏服的一个接口出现偶发超时的问题。02问题原因经抓包定位到B云游戏服接口未响应请求报文导致,具体......
  • 链表
    1.概念链表是数据结构中的一种,其中的数据是呈线性排列的,第一个数据会指向第二个数据,第二个数据指向第三个数据....单向链表2.操作添加只需要断掉原来的链接,然后建立新的链接即可删除断掉原来的链接,原来的数据不需要处理,后续有新数据存储,直接覆盖即可查找3.......
  • linux内核级性能调优
    1.Linux内核级性能调优常见选项Linux内核级性能调优是一个广泛的话题,涉及多个方面。以下是一些关键的调优领域和技术:1.CPU调度优化:  -调整CFS(完全公平调度器)参数  -使用CPU亲和性(CPUaffinity)  -配置NUMA(非统一内存访问)策略  -调整进程优先......