一、是什么?
作用:让各种松散的对象弄的有条理化
二、接口的说明
内核链表的类型:
struct list_head
{
struct list_head*next,*prev;
};
内核链表使用参考:
struct todo_struct
{
struct list_head list; //
int priority; //
};
内核链表的初始化:
struct list_head todo_list;
INIT_LIST_HEAD(&todo_list);
内核链表加法:
list_add(struct list_head*new,struct list_head*head);// 可用来建立stack
list_add_tail(struct list_head*new,struct list_head*head);//可用来建立队列
list_splice(struct list_head*list,struct list_head*head);//将list紧接在head之后来连接2个链表
内核链表减法:
list_del(struct list_head*entry);
list_del_init(struct list_head*entry); //
内核链表逻辑:真与假
list_empty(struct list_head*head);//如果给定链表是空,返回一个空值
内核链表查找:
list_entry(struct list_head*ptr,type_of_struct,field_name);找到包含list_head结构体首地址
struct todo_struct*todo_ptr = list_entry(listptr,struct todo_struct,list);
list_for_each(struct list_head*cursor,struct list_head*list);
list_for_each_prev(struct list_head*cursor,struct list_head*list);
list_for_each_entry(type*cursor,struct list_head*list,member);
void todo_add_entry(struct todo_struct*new)
{
struct list_head*ptr;
struct todo_struct*entry;
for(ptr=todo_list.next;ptr!=&todo_list;ptr=ptr->next)
{
entry = list_entry(ptr,struct todo_struct,list);
if(entry->priority<new->priority)
{
list_add_tail(&new->list,ptr);
return;
}
list_add_tail(&new->list,&todo_struct);
}
}
void todo_add_entry(struct todo_struct*new)
{
struct list_head*ptr;
struct todo_struct*entry;
list_for_each(ptr,&todo_list)
{
entry = list_entry(ptr,struct todo_struct,list);
if(entry->priority < new->priority)
{
list_add_tail(&new->list,ptr);
return ;
}
}
list_add_tail(&new->list,&todo_struct);
}
三、移植
源码在include/linux/list.h
增加如下代码:
#define LIST_POISON1 ((void *) 0x0)
#define LIST_POISON2 ((void *) 0x0)
#ifndef ARCH_HAS_PREFETCH
#define ARCH_HAS_PREFETCH
static inline void prefetch(const void *x) {;}
#endif
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
三、使用
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include "list.h"
struct usb_function_driver
{
char*name;
struct usb_function_instance *(*alloc_inst)(const char *name);
struct usb_function *(*alloc_func)(struct usb_function_instance *inst);
struct list_head list;
};
struct usb_function_instance
{
struct list_head cfs_list;
struct usb_function_driver *fd;
int (*set_inst_name)(struct usb_function_instance *inst,const char *name);
void (*free_func_inst)(struct usb_function_instance *inst);
};
static LIST_HEAD(func_list);
int usb_function_register(struct usb_function_driver *newf)
{
struct usb_function_driver *fd;
static int i = 1;
int ret;
ret = -1;
if((newf == NULL) || ((newf->name) == NULL))
{
return -1;
}
list_for_each_entry(fd, &func_list, list)
{
if (!strcmp(fd->name, newf->name))
{
printf("add already %d fd name is %s\n",i++,fd->name);
goto out;
}
}
ret = 0;
printf("add function\n");
list_add_tail(&newf->list, &func_list);
out:
return ret;
}
struct usb_function_instance* alloc_inst(const char *name)
{
printf("usb_function_instance alloc_inst alloc_inst is %s\n",name);
}
void usb_function_unregister(struct usb_function_driver *fd)
{
list_del(&fd->list);
}
struct usb_function_instance *try_get_usb_function_instance(const char *name)
{
struct usb_function_driver *fd;
struct usb_function_instance *fi;
if(list_empty(&func_list))
{
printf("func_list is empty\n");
return ((struct usb_function_instance *)NULL);
}
list_for_each_entry(fd, &func_list, list)
{
if (strcmp(name, fd->name))
continue;
fi = fd->alloc_inst(name);
break;
}
return fi;
}
struct usb_function_driver usb_func[3] =
{
{
.name = "uvc",
.alloc_inst = alloc_inst,
},
{
.name = "rndis",
.alloc_inst = alloc_inst,
},
{
.name = "f_serial",
.alloc_inst = alloc_inst,
},
};
int main()
{
struct list_head plist_head;
int i = 0;
INIT_LIST_HEAD(&plist_head);
for(i=0;i<3;i++)
{
usb_function_register(&usb_func[i]);
try_get_usb_function_instance(usb_func[i].name);
}
for(i=0;i<3;i++)
{
usb_function_unregister(&usb_func[i]);
}
for(i=0;i<5;i++)
{
try_get_usb_function_instance(usb_func[i].name);
}
return 0;
}
root@ubuntu:/nfsroot/list# ./a.out
add function
usb_function_instance alloc_inst alloc_inst is uvc
add function
usb_function_instance alloc_inst alloc_inst is rndis
add function
usb_function_instance alloc_inst alloc_inst is f_serial
func_list is empty
func_list is empty
func_list is empty
func_list is empty
func_list is empty