在用户态实现linux内核链表机制

来源:互联网 发布:勃朗宁m1910淘宝 编辑:程序博客网 时间:2024/05/01 15:28

转载:http://my.chinaunix.net/space.php?uid=25052030&do=blog&id=65337

 

Linux内核的链表机制简单易用,而且与特写的结构分离,具有一整套的链表接口。不需要人为的根据特定的结构而编写相应的链表处理方法,是一种很好的机制。

为什么要将linux内核的链表机制应用于用户态呢。这主要是在做项目的时候的经验教训。因为做的项目,有大量的链表操作。初期我使用的是类似于数据结构书中介绍的那种链表机制,如图所示。

struct data

{

int a;

struct data *prev;

struct data *next;

};

用这种格式的话,对于每一个结构都要编写相应的链表处理函数。即使用相关函数来统一实现,也不便于理解,所以就彩用的内核中的链表结构,大大的减少了代码量。

新的结构如下

struct data、、

{

int a;

struct list_head list;

};

相应的操作时限是对list_head结构进行的。下面是我自已写的一个小的测试程序,但对链表的合并等相关代码,还没有加进去。

 

list_head.h文件

 

#include <stdio.h>

#include <stdlib.h>

 

//分配空间并初使化链表头

#define LIST_HEAD_INIT(name) {&(name),&(name)}//作用?????????????

#define LIST_HEAD(name)     struct list_head name= LIST_HEAD_INIT(name)

 

//对已经分配了空间的list头指针进行初使化

#define INIT_LIST_HEAD(ptr) do {/

(ptr)->next = (ptr);/

(ptr)->prev = (ptr);/

}while(0)

 

//链表结构

struct list_head

{

struct list_head *prev;

struct list_head *next;

};

 

//获得包含list的相应结构(由链表结点到数据项对象)

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

#define container_of(ptr,type,member)  ({/

const typeof(((type *)0)->member)* __mptr = (ptr);/

(type *)((char *)__mptr - offsetof(type,member));})

#define offsetof(TYPE,MEMBER) ((size_t)&((TYPE *)0)->MEMBER)

 

list_head.c文件

 

#include "list_head.h"

 

//临时测试结构

struct test

{

int a;

struct list_head list;

};

 

struct list_head test_head;

 

//在prev和next之间插入一个新的结点new

static inline void in_list_add(struct list_head *new,struct list_head *prev,struct list_head *next)

{

prev->next = new;

new->next = next;

new->prev = prev;

next->prev = new;

}

 

//删除prev和next之间的结点

static inline void in_list_del(struct list_head *prev,struct list_head *next)

{

prev->next = next;

next->prev = prev;

}

 

//清空链表

static inline int list_empty(const struct list_head *head)

{

return head->next==head;

}

 

//在链表头插入结点

static inline void list_add(struct list_head *new,struct list_head *head)

{

in_list_add(new,head,head->next);

}

 

//在链表尾插入结点

static inline void list_add_tail(struct list_head *new,struct list_head *head)

{

in_list_add(new,head->prev,head);

}

 

//删除结点

static inline void list_del(struct list_head *entry)

{

in_list_del(entry->prev, entry->next);

}

 

//测试删除结点

int test_del_entry(int a)

{

     struct list_head *ptr;

     struct test *entry;

 

    for (ptr = test_head.next; ptr != &test_head; ptr = ptr->next)

        {

            entry = list_entry(ptr, struct test, list);

            if (entry->a == a)

           {

                 list_del(&entry->list);

                 free(entry);

                  return 0;

           }

        }

return -1;

}

、、//删除整个链表

while( 0 == list_empty(head))、、传入链表的空头

{

     struct list_head *p;

     p = head;

     p = p->next;

     linklist_view = list_entry (p,linknode_me,list);//linklist linklist_view;我的结构体指针,linknode我的结构节点

     printk ();

     list_del (p);

     kfree(linklist_view);

}


 

//测试在链表尾插入结点

void test_add_entry_down(struct test *new)

{

struct list_head *ptr;

struct test *entry;

 

for (ptr = test_head.next; ptr != &test_head; ptr = ptr->next)

{

entry = list_entry(ptr, struct test, list);

if (entry->a > new->a)

{

list_add_tail(&new->list, ptr);

return;

}

}

list_add_tail(&new->list, ptr);

return;

}

 

//测试在链表头插入结点

void test_add_entry_up(struct test *new)

{

struct list_head *ptr;

struct test *entry;

 

for (ptr = test_head.next; ptr != &test_head; ptr = ptr->next)

{

entry = list_entry(ptr, struct test, list);

if (entry->a < new->a)

{

list_add_tail(&new->list, ptr);

return;

}

}

list_add_tail(&new->list, ptr);

return;

}

 

//输出结点

void test_print_allentry(struct list_head *head)

{

struct list_head *ptr;

struct test *entry;

for (ptr = head->next; ptr != head; ptr = ptr->next)

{

entry = list_entry(ptr, struct test, list);

printf("**********%d**********/n",entry->a);

}

return;

}

 

//测试

int main(void)

{

INIT_LIST_HEAD(&test_head);

struct test *tmp;

tmp = (struct test*)malloc(sizeof(struct test));

tmp->a = 5;

test_add_entry_down(tmp);

 

tmp = (struct test*)malloc(sizeof(struct test));

tmp->a = 3;

test_add_entry_down(tmp);

 

tmp = (struct test*)malloc(sizeof(struct test));

tmp->a = 2;

test_add_entry_down(tmp);

 

tmp = (struct test*)malloc(sizeof(struct test));

tmp->a = 6;

test_add_entry_down(tmp);

 

tmp = (struct test*)malloc(sizeof(struct test));

tmp->a = 4;

test_add_entry_down(tmp);

 

int ff = 2;

test_del_entry(ff);

test_print_allentry(&test_head);

ff = 4;

test_del_entry(ff);

test_print_allentry(&test_head);

ff = 5;

test_del_entry(ff);

test_print_allentry(&test_head);

return 0;

}