linux c操作之内核链表的使用


一、是什么?

作用:让各种松散的对象弄的有条理化

二、接口的说明

内核链表的类型:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今天6点半起床10点半睡觉和今天早晚运动

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值