linux 内核链表练习

        linux 内核链表使用案例:

链表源码:test_list.c

/**********************************************
 * Author: lewiyon@hotmail.com
 * File name: test_list.c
 * Description: test the macroes in the core.h 
 * Date: 2011-12-14
 *********************************************/

#include <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#include "list.h"

#define MAX_LEN	20

struct student{
    char name[MAX_LEN];
    unsigned long long id;
    struct list_head ls_stu;
};

static struct list_head stu_list;

static struct student *id_stu(unsigned long *id_no)
{
    return (container_of(id_no, struct student, id));
}

static void stu_init(struct student **stu)
{
	*stu = (struct student *)malloc(sizeof(struct student));
	INIT_LIST_HEAD(&(*stu)->ls_stu); 
}

static void list_print()
{
	struct student *pos;
	if (list_empty(&stu_list)) {
		printf("stu_list is NULL!\n");
		return ;
	}
			
	list_for_each_entry(pos, &stu_list, ls_stu) {
		printf("Name:%s, id:%lu;\n", pos->name, pos->id);
	}
    printf("-------------------------------\n");
}

int main(int argc, char *argv[])
{
    unsigned long offset;
    char *name_fst = "aaaa";
    char *name_sec = "bbbb";
    char *name_tmp = "zzzz";
    struct student *stu_fst, *stu_sec, *stu_tmp;
	
	INIT_LIST_HEAD(&stu_list); /* 全局链表初始化 */
	if (list_empty(&stu_list)) /* 判断链表是否为NULL */
		printf("stu_list is NULL\n");
	
	/* 初始化3个stu实例,用于链表操作练习 */
	stu_init(&stu_fst);
	memcpy(stu_fst->name, name_fst, strlen(name_fst));
	stu_fst->id = 2004035001;

	stu_init(&stu_sec);
	memcpy(stu_sec->name, name_sec, strlen(name_sec));
	stu_sec->id = 2004035002;
	
	stu_init(&stu_tmp);
	memcpy(stu_tmp->name, name_tmp, strlen(name_tmp));
	stu_tmp->id = 2004035000;

	/* 将stu_sec->ls_stu添加到链表stu_list */
	printf("Insert entry:2004035002.\n");
	list_add(&stu_sec->ls_stu, &stu_list); 
	list_print();

	/* 将stu_fst->ls_stu添加到链表stu_list */
	printf("Insert entry in the front of stu_list: 2004035001.\n");
	list_add(&stu_fst->ls_stu, &stu_list); 
	list_print();
	
	/* 将stu_tmp->ls_stu添加到链表stu_list */
	printf("Insert entry in the front of stu_list: 2004035000.\n");
	list_add_tail(&stu_tmp->ls_stu, &stu_list); 
	list_print();
	
	/* 将stu_tmp->ls_stu从链表stu_list中删除 */
	printf("Delete entry : 2004035000.\n");
	list_del(&stu_tmp->ls_stu); 
	list_print();
	
    return 0;
}

输出结果:

[root@RedHat list_sample]# ./main
stu_list is NULL
Insert entry:2004035002.
Name:bbbb, id:2004035002;
-------------------------------
Insert entry in the front of stu_list: 2004035001.
Name:aaaa, id:2004035001;
Name:bbbb, id:2004035002;
-------------------------------
Insert entry in the front of stu_list: 2004035000.
Name:aaaa, id:2004035001;
Name:bbbb, id:2004035002;
Name:zzzz, id:2004035000;
-------------------------------
Delete entry : 2004035000.
Name:aaaa, id:2004035001;
Name:bbbb, id:2004035002;
-------------------------------
[root@RedHat list_sample]#


链表源码:list.h 原来摘自内核(3.1.6版本)

/**********************************************
 * Author: lewiyon@hotmail.com
 * File name: list.h
 * Description: define some macroes
 * Date: 2011-12-29
 *********************************************/
#ifndef __CORE_H
#define __CORE_H

//typedef unsigned long size_t;

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

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

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

/**
 * list_empty - tests whether a list is empty
 * @head: the list to test.
 */
static inline int list_empty(const struct list_head *head)
{
	return head->next == head;
}

/* Insert a new entry between two known consecutive entries */
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;
}

/* add a new entry in the front of head */
static inline void list_add(struct list_head *new, struct list_head *head)
{
    __list_add(new, head, head->next);
}

/* insert a new entry in the end of head */
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
        __list_add(new, head->prev, head);
}

/* deletes entry from list */
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
	next->prev = prev;
	prev->next = next;
}
/* deletes entry from list */
static inline void list_del(struct list_head *entry)
{
	__list_del(entry->prev, entry->next);
	entry->next = (void *)0xDEADBEEF;
	entry->prev = (void *)0xBEEFDEAD;
}

/* replace old entry by new one */
static inline void list_replace(struct list_head *old, struct list_head *new)
{
	new->next = old->next;
	new->next->prev = new;
	new->prev = old->prev;
	new->prev->next = new;
}

/* 
 * delete from one list and add as another's head
 * @list: the entry to move
 * @head: the head that will precede our entry
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
	__list_del(list->prev, list->next);
	list_add(list, head);
}

/**
 * list_move_tail - delete from one list and add as another's tail
 * @list: the entry to move
 * @head: the head that will follow our entry
 */
static inline void list_move_tail(struct list_head *list,
				  struct list_head *head)
{
	__list_del(list->prev, list->next);
	list_add_tail(list, head);
}

static inline void __list_splice(const struct list_head *list,
				 struct list_head *prev, struct list_head *next)
{
	struct list_head *first = list->next;
	struct list_head *last = list->prev;

	first->prev = prev;
	prev->next = first;

	last->next = next;
	next->prev = last;
}

/**
 * list_splice - join two lists, this is designed for stacks
 * @list: the new list to add.
 * @head: the place to add it in the first list.
 */
static inline void list_splice(const struct list_head *list,
			       struct list_head *head)
{
	if (!list_empty(list))
		__list_splice(list, head, head->next);
}

/**
 * list_entry - get the struct for this entry
 * @ptr:	the &struct list_head pointer.
 * @type:	the type of the struct this is embedded in.
 * @member:	the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \
	container_of(ptr, type, member)

/**
 * list_for_each_entry	-	iterate over list of given type
 * @pos:	the type * to use as a loop cursor.
 * @head:	the head for your list.
 * @member:	the name of the list_struct within the struct.
 */
#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))

#endif




原文地址:https://www.cnblogs.com/youngerchina/p/5624637.html