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