Linux内核中的list_head

一般我们想要实现一种数据结构的双链队列,一般都是这样操作:

  typedef struct Datastructure
{
    struct Datastructure *next;
    struct Datastructure *prev;
    //......
}datastructure;

然而在Linux内核中,使用了大量不同的数据结构的双链队列。
因此,内核作者们把指针prev和next从具体的宿主中抽象出来成为了一种数据结构list_head。

struct list_head
{
    struct list_head *next, *prev;
};

在其宿主结构中:

typedef struct page
{
    struct list_head list;
    //.......
    struct page *next_hash;
    //.......
    struct list_head lru;
};

数据结构之间的连接操作都通过list_head执行。
接着内核定义了如下的一个函数:
memlist_entry(cur, struct page, list);
这个函数将list_head的指针curr换算成了宿主结构的其实地址,也就是其宿主page结构的指针。
但事实上,同一文件中将memlist_entry定义为list_entry。
page = (struct page*)((char*)(curr) - (usigned long)(& (struct page*)0) -> list));
其中curr是page结构中成分list的地址,page本身的地址,通过curr减去一个位移量就能得出,而这个位移量,就是page刚好在地址0时其成分list的地址,既:
& (struct page*)0) -> list)

原文地址:https://www.cnblogs.com/zyf3855923/p/12016371.html

时间: 2025-01-06 14:31:56

Linux内核中的list_head的相关文章

linux内核中的hlist_head、list_head、hlist_node结构体

在linux内核中经常会看到这几个结构体: struct list_head; struct hlist_head; struct hlist_node; 在linux内核源代码中对这三个结构体的定义如下: struct list_head { struct list_head *prev; struct list_head *next; } struct hlist_node { struct hlist_node **prev; struct hlist_node *next; } stru

向linux内核中添加外部中断驱动模块

本文主要介绍外部中断驱动模块的编写,包括:1.linux模块的框架及混杂设备的注册.卸载.操作函数集.2.中断的申请及释放.3.等待队列的使用.4.工作队列的使用.5.定时器的使用.6.向linux内核中添加外部中断驱动模块.7.完整驱动程序代码.linux的内核版本为linux2.6.32.2. 一.linux模块的框架以及混杂设备相关知识 1.内核模块的框架如下图所示,其中module_init()(图中有误,不是modules_init)只有在使用insmod命令手动加载模块时才会被调用,

Linux内核中的软中断、tasklet和工作队列详解

[TOC] 本文基于Linux2.6.32内核版本. 引言 软中断.tasklet和工作队列并不是Linux内核中一直存在的机制,而是由更早版本的内核中的"下半部"(bottom half)演变而来.下半部的机制实际上包括五种,但2.6版本的内核中,下半部和任务队列的函数都消失了,只剩下了前三者. 介绍这三种下半部实现之前,有必要说一下上半部与下半部的区别. 上半部指的是中断处理程序,下半部则指的是一些虽然与中断有相关性但是可以延后执行的任务.举个例子:在网络传输中,网卡接收到数据包这

linux 内核 中链表list

这个结构从list.h 移到了types.h, 可见内核对循环链表的重视 include/linux/types.h中定义 struct list_head {        struct list_head *next, *prev;}; include/linux/list.h 中的宏 初始化 一个叫name的链表节点 #define LIST_HEAD_INIT(name) { &(name), &(name) } #define LIST_HEAD(name) \        s

linux内核中与进程相关的数据结构(基于linux-mainline-rc4)

1.进程描述符    struct task_struct {  volatile long state; ....... struct list_head tasks; ....... struct mm_struct *mm, *active_mm; ....... struct vm_area_struct *vmacache[VMACACHE_SIZE]; ...... pid_t pid; pid_t tgid; .......   }所在文件:include/linux/sched.

Linux内核中的软中断、tasklet和工作队列具体解释

[TOC] 本文基于Linux2.6.32内核版本号. 引言 软中断.tasklet和工作队列并非Linux内核中一直存在的机制,而是由更早版本号的内核中的"下半部"(bottom half)演变而来. 下半部的机制实际上包含五种,但2.6版本号的内核中.下半部和任务队列的函数都消失了,仅仅剩下了前三者. 介绍这三种下半部实现之前.有必要说一下上半部与下半部的差别. 上半部指的是中断处理程序,下半部则指的是一些尽管与中断有相关性可是能够延后运行的任务. 举个样例:在网络传输中.网卡接收

linux内核中的等待队列的基本操作

   在linux内核中进程的状态主要有几种状态:    1.运行态:即进程正在CPU上进行运行,它此刻正在占有CPU:    2.就绪态:即进程除了CPU之外,已经具备了运行的所有条件,在就绪队列中等待调度器(schedule)的调度:    3.阻塞态:即进程除了缺少CPU外,还缺少其他条件,在等待队列中等待所需要的条件:    介绍linux内核中的等待队列的组织结构以及各种对等待队列的操作:    等待队列由两部分构成:等待队列头 + 等待队列中的等待项:    等待队列头的结构:   

Linux内核中的GPIO系统之(3):pin controller driver代码分析--devm_kzalloc使用【转】

转自:http://www.wowotech.net/linux_kenrel/pin-controller-driver.html 一.前言 对于一个嵌入式软件工程师,我们的软件模块经常和硬件打交道,pin control subsystem也不例外,被它驱动的硬件叫做pin controller(一般ARM soc的datasheet会把pin controller的内容放入GPIO controller的章节中),主要功能包括: (1)pin multiplexing.基于ARM core

Linux内核中双向链表的经典实现

Linux内核中双向链表的经典实现 概要 前面一章"介绍双向链表并给出了C/C++/Java三种实现",本章继续对双向链表进行探讨,介绍的内容是Linux内核中双向链表的经典实现和用法.其中,也会涉及到Linux内核中非常常用的两个经典宏定义offsetof和container_of.内容包括:1. Linux中的两个经典宏定义2. Linux中双向链表的经典实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p/3562146.html 更多