linux驱动里面双向链表

在驱动开发,或者linux内核,里面有很多双向队列的使用。

里面自己简单自己模仿写了一下代码,记录双向队列的实现。

include <stdio.h>

include<stdlib.h>

define offsetof(type,member) (int)(&((type *)0)->member)

if 1

define container_of(ptr,type,member) ({ \

const char* __mptr = (ptr); \
(type *)(((char *)__mptr) - offsetof(type,member)); \

})

else

define container_of(ptr, type, member) ({ \

const char* __mptr = (ptr); \ 
(type *)((char *)__mptr - offsetof(type, member)); })

endif

struct list_head {
struct list_head* prev;
struct list_head* next;
};
//初始化,就是让next和prev指向head自己。在判断链表结束的时候, 就是看next是否指向head.指向head,说明链表已经遍历完成

define list_init(head) \

((struct list_head *)head)->prev = head;
((struct list_head *)head)->next=head;

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

define list_for_each_entry(pos, head, member) \

for (pos = list_entry((head)->next, typeof(*pos), member); &pos->member != (head); pos = list_entry(pos->member.next, typeof(*pos), member)) 

void list_add_head(struct list_head* new_node, struct list_head* head);

//因为是非空的双向队列,head这个元素是一直存在的。
//头部插入
void list_add_head(struct list_head* new_node, struct list_head* head)
{
struct list_head* next = head->next;//知道head 指向的第一个元素
next->prev = new_node; //新元素,插入在头部,所以之前head指向的第一个元素,就需要指向new的节点
new_node->next = next;//新元素的next指向了之前head指向的第一个元素
new_node->prev = head;//新元素的prev指向了head
head->next = new_node;//head的next,就需要指向新的元素。
}
//尾部插入
void list_add_tail(struct list_head* new_node, struct list_head* head)
{

struct list_head* prev = head->prev; //知道head 指向的第后一个元素
prev->next = new_node; //最后一个元素的next,指向这个新的元素
new_node->prev = head->prev;//new元素,的prev,指向之前的最后一个元素,就head->prev指向的元素
new_node->next = head; //new元素,next,z指向了head
head->prev = new_node; //head元素的prev,就需要指向新的元素了

}

void list_del(struct list_head *old_node)
{
old_node->prev->next = old_node->next;
old_node->next->prev = old_node->prev;
}
struct list_test {
int cnt;
struct list_head head;
};

int main(int argc, char* argv[])
{
struct list_test mytest;

list_init(&mytest.head);

for (int i = 0;i < 5;i++) {
	struct list_test* p = (struct list_test*)malloc(sizeof(struct list_test));
	p->cnt = i+10;
	//list_add_head(&p->head, &mytest.head);
	list_add_tail(&p->head, &mytest.head);
}
struct list_test* p;
struct list_head * t=mytest.head.next;

while(t != &mytest.head)
{
	p = container_of(t, struct list_test, head);
	printf("%d\n",p->cnt);
	t = t->next;
}

list_for_each_entry(p,&mytest.head,head) {
	if(p->cnt == 13)
		list_del(&p->head);
}

list_for_each_entry(p,&mytest.head,head) {
	printf("%d\n",p->cnt);
}

}

posted @   高山小路  阅读(108)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示