linux 内核链表使用案例:
链表源码:test_list.c
/********************************************** * Author: [email protected] * 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: [email protected] * 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