zoukankan      html  css  js  c++  java
  • 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
    




  • 相关阅读:
    【笔记】黄如花.信息检索.学习心得
    【心得】Lattice和Xilinx工具关键特性对比(Diamond、ISE)
    【导航】FPGA相关
    【笔记】黄如花.信息检索.前4章心得(新增大牛汇总的公开课资源)
    python正则表达式练习题
    python正则表达式(1)--特殊字符
    【转】什么时候 i = i + 1 并不等于 i += 1?
    Linux查看文件指定行数内容
    python mysqldb批量执行语句executemany
    linux命令行常用快捷键
  • 原文地址:https://www.cnblogs.com/youngerchina/p/5624637.html
Copyright © 2011-2022 走看看