将项添加到Linux内核链表

将项添加到Linux内核链表,第1张

概述我在我的代码中使用 linux / list.h来实现队列/堆栈行为.用于添加头/尾的API如下: static inline void list_add(struct list_head *new, struct list_head *head){ __list_add(new, head, head->next);} 类似于list_add_tail.令人惊讶的是,它没有 我在我的代码中使用 linux / List.h来实现队列/堆栈行为.用于添加头/尾的API如下:

static inline voID List_add(struct List_head *new,struct List_head *head){         __List_add(new,head,head->next);}

类似于List_add_tail.令人惊讶的是,它没有返回任何内容(voID),因此它意味着使用此API在内核中添加列表总是成功的.我知道这里没有完整的概念,但如果新节点的内存分配不可用以及其他可能的原因怎么办?

解决方法 列表API不会动态分配任何内存.我发现这件事有点令人费解,我自己.这里的问题是linux是用C语言编写的,而不是C语言,但是以一种非常面向对象的方式实现,但在C语言中,它看起来像是在里面.它的工作原理如下(这也适用于其他几个linux API,例如kobj):

您定义了一些结构,它应该是列表的成员.与您通常会想到链接列表的方式相反,通过分配一些不透明的列表项并且指针指向您的实际对象,不会将此对象放入列表中,您将struct List_head设置为结构的实际成员:

struct something {    struct List_head List;    uint8_t some_datum;    uint16_t some_other_datum;    voID *a_pointer;};

你的列表将是一些独立的struct List_head:

static List_head(List_of_somethings);

要向List_of_somethings添加元素,您现在可以执行类似的 *** 作

struct something *s = kmalloc(sizeof(*s),GFP_KERNEL);s->some_datum = 23;s->some_other_datum = 0xdeadbeef;s->a_pointer = current;List_add(&s->List,&List_of_somethings);

换句话说,您已经分配了元素.这看起来很奇怪,但是像f * ck一样优雅.这种“设计模式”允许在C中使用类型不透明的列表,这在另一种方式下并不容易:列表本身就是一堆指向彼此的struct List_heads.如您所知,作为程序员正在使用哪个实际结构,您知道该结构的哪个元素是实际的List_head,并且可以使用container_of宏来获取指向您放入列表的最终结构的指针:

struct List_head *p = &List_of_somethings.next;struct something *s = container_of(p,struct something,List);pr_notice("some data = %i\n",s->some_data);

请注意,表示列表本身的实际struct List_head是由< linux / List.h>中定义的迭代宏专门处理的,即

#define List_for_each(pos,head) \        for (pos = (head)->next; pos != (head); pos = pos->next)

List_of_somethings的地址将用于确定迭代是否到达列表的末尾(或实际上是List-object).
这也是为什么将空列表定义为具有struct List_head本身的next和prev的原因.

我也需要一些时间来解决这个问题. 总结

以上是内存溢出为你收集整理的将项添加到Linux内核链表全部内容,希望文章能够帮你解决将项添加到Linux内核链表所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/1027705.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-23
下一篇2022-05-23

发表评论

登录后才能评论

评论列表(0条)

    保存