linux 内核链表简单的实验分析

#include 
#include 
#include 
#include 
#include 


struct student
{
    char name[100];
    int num;
    struct list_head list;
};

struct student *pstudent;
struct student *tmp_student;

//定义一个链表头.
struct list_head student_list;
//list_head 指针. 指向每一个节点
struct list_head *pos;

int mylist_init(void)
{
	int i = 0;

	printk("offsetof(name):%d\n",offsetof(struct student,  name));
	printk("offsetof(num):%d\n",offsetof(struct student,  num));
	printk("offsetof(list):%d\n",offsetof(struct student,  list));
	printk("sizeof(student):%d\n",sizeof(struct student));
	
	INIT_LIST_HEAD(&student_list);
	pstudent = kmalloc(sizeof(struct student)*5,GFP_KERNEL);
	memset(pstudent,0,sizeof(struct student)*5);

	//一次添加5个节点
	for(i=0;i<5;i++) {
	        sprintf(pstudent[i].name,"Student%d",i+1);
		pstudent[i].num = i+1; 
		#if 0
		list_add_tail( &(pstudent[i].list), &student_list);
		#else
		list_add( &(pstudent[i].list), &student_list);
		#endif
	} 
	
	//从前往后遍历. 获取有效的pos(list)
	list_for_each(pos,&student_list) {
		//通过list来偏移到结构提的首地址.
		tmp_student = list_entry(pos,struct student,list);
		printk("student %d name: %s\n",tmp_student->num,tmp_student->name);
	}
	
	return 0;
}


void mylist_exit(void)
{	
	int i ;
	for(i=0;i<5;i++) {
		list_del(&(pstudent[i].list));     
	}
	kfree(pstudent);
}
module_init(mylist_init);
module_exit(mylist_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("list@whpe");
MODULE_DESCRIPTION("List Module");

/************************************************************************
struct list_head {
	struct list_head *next, *prev;
};

static inline void INIT_LIST_HEAD(struct list_head *list)
{
	list->next = list;
	list->prev = list;
}

_list_add(新节点newnode, newnode->pre节点, newnode->next节点);
所以list_add_tail----(new, head->prev, head)
所以list_add---------(new, head, head->next)

static inline void __list_add(struct list_head *new,
			      struct list_head *prev,
			      struct list_head *next)
{
	next->prev = new;
	new->next = next; 
	new->prev = prev;
	prev->next = new;
}

static inline void list_add(struct list_head *new, struct list_head *head)
{
	__list_add(new, head, head->next);
}

static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
	__list_add(new, head->prev, head);
}


static inline void __list_del(struct list_head * prev, struct list_head * next)
{
	next->prev = prev;
	prev->next = next;
}

static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	entry->next = LIST_POISON1;
	entry->prev = LIST_POISON2;
}

static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}


//从前往后遍历.
#define list_for_each(pos, head) \
	for (pos = (head)->next; prefetch(pos->next), pos != (head); \
        	pos = pos->next)

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#define container_of(ptr, type, member) ({			\
	const typeof(((type *)0)->member) * __mptr = (ptr);	\
	(type *)((char *)__mptr - offsetof(type, member)); })
#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)


//typeof:获得数据的类型
//本来指向list的指针,通过这个宏,就可以指向strcut student的指针了. 通过偏移.
// char * (&list) - 104 ------>指向了.char *name的位置了.
tmp_student = list_entry(pos,struct student,list);
struct student
{
    char name[100];
    int num;
    struct list_head list;
};


******************************************************************************/

代码下载地址:

https://download.csdn.net/download/u010550992/10384422

你可能感兴趣的:(linux)