1. 程式人生 > 其它 >linux驅動裡面雙向連結串列

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);
}

}