static inline void list_add(struct list_head *new,struct list_head *head) { __list_add(new,head,head->next); }
类似于list_add_tail.令人惊讶的是,它没有返回任何内容(void),因此它意味着使用此API在内核中添加列表总是成功的.我知道这里没有完整的概念,但如果新节点的内存分配不可用以及其他可能的原因怎么办?
解决方法
您定义了一些结构,它应该是列表的成员.与您通常会想到链接列表的方式相反,通过分配一些不透明的列表项并且指针指向您的实际对象,不会将此对象放入列表中,您将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的原因.
我也需要一些时间来解决这个问题.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。