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