Linux内核中关于数据结构操作的一个问题

原创 2006年05月20日 20:52:00
        在Linux内核中的队列操作都是通过list_head来进行的,list_head称为“宿主结构”的“连接件”,但是我们真正需要的是宿主结构,而不是这个连接件,如果我们顺着一个队列取得了其中一项的list_head结构时,又怎样找到其宿主结构呢?
        刚开始看内核源码时,我对这个问题百思不得其解,后来看了浙大的那本《Linux内核源代码情景分析》之后,才找到答案。所以将关键部分摘录出来,为有此苦恼的朋友解惑。
        以内存页面管理的page数据结构作为“宿主结构”为例,它的定义如下:
        typedef struct page {
        struct list_head list;
         ......
        }mem_map_t;
       在内核源代码中是通过list_entry()函数来解决这个问题的,实例代码:
        page = list_entry(curr, struct page, list);
        如此就得到了其宿主结构。list_entry是一个宏,它的定义如下:
    #define list_entry(ptr, type, member) /
 ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
        和上面的实例代码作比较,此宏经过C预处理的文字替换,就成为:
    page=((struct page*)((char *)(curr)-(unsigned long)(&((struct page*)0)->list)));
       这里的curr是一个page结构的内部成员list的地址,而我们所需要的却是那个page结构本身的地址,所以从地址curr减去一个位移量,即成员list在page内部的偏移,才能达到要求。那么,这位移量到底是多少呢?&((struct page *)0)->list表示当结构page正好在地址0上时其成员list的地址,这就是位移量。
  
         在Windows内核中也采用了类似的队列操作,用DDK编写过Windows驱动程序的就知道,只不过换了个名字,将list_entry变成了CONTAINING_RECORD,在DDK头文件中也有此宏的定义:
    #define CONTAINING_RECORD(address, type, field) ((type *)( /
                                                  (PCHAR)(address) - /
                                                  (ULONG_PTR)(&((type *)0)->field)))
        可见,它们是完全一样的。

linux内核中常用的数据结构和操作详解

目前在学习研究linux系统,作为一名初学者,感觉很吃力,通过网友指点和自己琢磨,总结出,首先理解linux关键数据结构,对理解linux系统大有裨益,故总结下文——详述相关关键数据结构。   ...
  • u010245383
  • u010245383
  • 2014年06月06日 20:56
  • 1081

Linux内核常用数据结构要点

简单总结一下Linux Kernel常用数据结构和选取原则
  • ace_an
  • ace_an
  • 2016年12月22日 13:56
  • 1112

数据结构:图论:欧拉回路!一笔画问题

从无向图中的一个结点出发走出一条道路,每条边恰好经过一次。这样的路线称为欧拉道路。 奇点的概念:一个点的度数为奇数的时候,这个点就称为:奇点。 无向图中结论: 不难发现,在欧拉道路中,除了起点跟...
  • u010470972
  • u010470972
  • 2014年06月09日 14:47
  • 1053

linux 内核常用数据结构及算法——container_of

container_of是linux内核中常用的一个宏函数,其用途是通过结构体一个yu
  • vah101
  • vah101
  • 2014年11月15日 19:29
  • 1683

Linux内核常用数据结构

Linux内核链表、哈希链表、红黑树....
  • lincoln_2012
  • lincoln_2012
  • 2014年09月25日 17:21
  • 612

Linux内核数据结构——链表

目录目录 简介 单向链表 双向链表 环形链表 Linux内核中的链表实现 offsetof container_of container_of 第一部分 container_of 第二部分 链表初始化...
  • zinss26914
  • zinss26914
  • 2015年03月17日 22:02
  • 4511

linux内核中Wifi控制部分的通信框架

Wifi控制部分通信走两种接口: A、基于网口的ioctl机制,如wext接口,android或厂家的独有命令,通过register_netdev注册网络ioctl接口,每个网口注册一个; B、基...
  • zjli321
  • zjli321
  • 2016年07月20日 18:32
  • 1108

Linux内核数据结构分析

上一篇在分析Linux虚拟文件系统的过程中,我注意到了一个反复出现的数据结构——struct list_head,通过名称就可以确定这是一种链表数据结构,今天我们就以此为切入点,对内核数据结构的特点做...
  • u012927281
  • u012927281
  • 2016年07月06日 23:18
  • 584

数据结构——线性结构(2)——链栈中的push和pop操作

链栈尽管数组是堆栈最常见的底层表示形式,但也可以使用链表实现Stack类。 如果这样做,空堆栈的概念表示就是NULL指针: 当你将新元素推入堆栈时,该元素只会添加到链表的前端。因此,如果将元素e...
  • redRnt
  • redRnt
  • 2017年08月26日 20:46
  • 1021

数据结构:字符串的基本操作

字符串(string)是由0个或多个字符组成的有限序列。一般使用顺序存储结构,末尾以’\0’表示结束,但不计入字符串的长度。 示例程序:(改编自《大话数据结构》#include using na...
  • Sandeldeng
  • Sandeldeng
  • 2016年11月01日 21:26
  • 517
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Linux内核中关于数据结构操作的一个问题
举报原因:
原因补充:

(最多只允许输入30个字)