歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> Linux內核 >> linux內核鏈表學習筆記

linux內核鏈表學習筆記

日期:2017/3/1 11:57:18   编辑:Linux內核
//
//  coreList.h
//  hehe
//
//  Created by yin on 16/8/24.
//  Copyright © 2016年 yin. All rights reserved.
//

#ifndef coreList_h
#define coreList_h

#define LIST_POISON1  ((struct list_head *) 0x0)
#define LIST_POISON2  ((struct list_head *) 0x0)

struct list_head {
    struct list_head *next, *prev;/* next後指針,prev前指針 */
};

/** \brief 鏈表頭初始化 */
#define LIST_HEAD_INIT(name) { &(name), &(name) }

/** \brief 鏈表頭初始化 */
#define LIST_HEAD(name) \
struct list_head name = LIST_HEAD_INIT(name)

/** \brief 初始化鏈表頭
 \param[in] ptr 鏈表結構指針
 \return 無
 */
#define INIT_LIST_HEAD(ptr) { \
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
}

static inline void __list_add(struct list_head *new_head,
                              struct list_head *prev,
                              struct list_head *next)
{
    /* 添加到鏈表 */
    next->prev = new_head;
    new_head->next = next;
    new_head->prev = prev;
    prev->next = new_head;
}

/** \brief 添加新的鏈表元素到鏈表頭
 \param[in] new_head 待添加鏈表結構指針
 \param[in] head 鏈表頭結構指針
 \\return 無
 */
static inline void list_add(struct list_head *new_head, struct list_head *head)
{
    /* 添加到鏈表頭 */
    __list_add(new_head, head, head->next);
}

/** \brief 添加新的鏈表元素到鏈表尾
 \param[in] new_head 待添加鏈表結構指針
 \param[in] head 鏈表頭結構指針
 \\return 無
 */
static inline void list_add_tail(struct list_head *new_head, struct list_head *head)
{
    /* 添加到鏈表尾 */
    __list_add(new_head, head->prev, head);
}

static inline void __list_del(struct list_head * prev, struct list_head * next)
{
    /* 從鏈表刪除 */
    next->prev = prev;
    prev->next = next;
}

/** \brief 從鏈表刪除節點
 \param[in] entry 待刪除鏈表結構指針
 \\return 無
 */
static inline void list_del(struct list_head *entry)
{
    /* 刪除鏈表記錄 */
    __list_del(entry->prev, entry->next);
    entry->next = LIST_POISON1;
    entry->prev = LIST_POISON2;
}

/** \brief 判斷鏈表是否為空
 \param[in] head 鏈表頭指針
 \return 無
 */
static inline int list_empty(struct list_head *head)
{
    /* 判斷鏈表是否為空 */
    return head->next == head;
}

/** \brief 刪除指定鏈表元素並初始化
 \param[in] entry 待刪除並初始化的鏈表元素
 \\return 無
 */
static inline void list_del_init(struct list_head *entry)
{
    __list_del(entry->prev, entry->next);
    INIT_LIST_HEAD(entry);
}

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

/** \brief 合並鏈表
 \param[in] list 待合並的新鏈表
 \param[in] head 合並的舊鏈表
 \\return 無
 */
static inline void list_splice(struct list_head *list, struct list_head *head)
{
    if (!list_empty(list))
        __list_splice(list, head);
}

/** \brief 合並鏈表並初始化新鏈表頭
 \param[in] list 待添加的新鏈表頭
 \param[in] head 合並新鏈表的位置
 \\return 無
 */
static inline void list_splice_init(struct list_head *list,
                                    struct list_head *head)
{
    if (!list_empty(list)) {
        __list_splice(list, head);
        INIT_LIST_HEAD(list);
    }
}

/** \brief 轉移鏈表元素到新鏈表頭
 \param[in] list 舊鏈表的鏈表頭
 \param[in] head 新鏈表的鏈表頭
 \\return 無
 */
static inline void list_move(struct list_head *list, struct list_head *head)
{
    __list_del(list->prev, list->next);
    list_add(list, head);
}

/** \brief 轉移鏈表元素到新鏈表尾
 \param[in] list 舊鏈表的鏈表頭
 \param[in] head 新鏈表的鏈表頭
 \\return 無
 */
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);
}

/** \brief 通過鏈表地址獲得結構體指針
 \param[in] ptr 鏈表結構指針
 \param[in] type 結構體類型
 \param[in] member 結構體中鏈表所表示的字段
 \return 無
 */
#define list_entry(ptr, type, member)  ((type *)(void *)((char *)(ptr) - (char*)(void*)(&((type*)0)->member)))

/** \brief 向後遍歷鏈表
 \attention 遍歷過程中不允許刪除鏈表元素
 \param[in] pos 當前所指向的鏈表節點
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = pos->next)

/** \brief 從pos的下一個節點, 向後遍歷鏈表
 \attention 遍歷過程中不允許刪除鏈表元素
 \param[in] pos 指定的鏈表節點
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_each_continue(pos, head)\
for ((pos) = (pos)->next; (pos) != (head); (pos) = (pos)->next)

/** \brief 向後遍歷鏈表
 \attention 用戶必須自行在遍歷過程中刪除鏈表元素,否則將導致死循環
 \param[in] pos 當前所指向的鏈表節點
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_del_each(pos, head) \
for (pos = (head)->next; pos != (head); \
pos = (head)->next)

/** \brief 向後遍歷鏈表
 \attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除
 \param[in] pos 當前所指向的鏈表節點
 \param[in] n   循環臨時值
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_each_safe(pos, n, head) for (pos = (head)->next, n = pos->next; pos != (head); pos = n, n = pos->next)

/** \brief 從pos的下一個節點開始, 向後遍歷鏈表
 \attention 遍歷過程中支持用戶自行刪除鏈表元素,用戶可自行決定是否刪除
 \param[in] pos 指定的鏈表節點
 \param[in] n   循環臨時值
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_each_safe_continue(pos, n, head)\
for ((pos) = (pos)->next, n = (pos)->next; pos != (head); \
(pos) = n, n = (pos)->next)

#define list_for_each_prev_safe(pos, p, head)\
for(pos = (head)->prev, p = pos->prev; pos != (head);\
pos = p, p = pos->prev)

/** \brief 向前遍歷鏈表
 \attention 遍歷過程中不允許刪除鏈表元素
 \param[in] pos 當前所指向的鏈表節點
 \param[in] head 鏈表頭指針
 \return 無
 */
#define list_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)

/** \brief 向後遍歷鏈表,並獲得鏈表所在結構體指針
 \attention 遍歷過程中不允許刪除鏈表元素
 \param[in] pos 鏈表所在結構體指針
 \param[in] type 結構體類型
 \param[in] head 鏈表頭指針
 \param[in] member 結構體成員名
 \return 無
 */
#define list_for_each_entry(pos, head, member,type)                \
for (pos = list_entry((head)->next, type, member);    \
&pos->member != (head);                     \
pos = list_entry(pos->member.next, type, member))


#define INIT_LIST_NODE(ptr)   { (ptr)->next = LIST_POISON1; (ptr)->prev = LIST_POISON2; }
#define IS_LIST_NODE_INIT(ptr)  ((LIST_POISON1 == (ptr)->next) && (LIST_POISON2 == (ptr)->prev))


#endif /* coreList_h */
實例:
#include 
#include 
#include "coreList.h"

typedef struct tagCAR_S
{
	struct list_head node;

	int id;
}CAR_S;

typedef struct tagPOLICE_S
{
	int serNum;

	struct list_head carHead;
	int carNum;
}POLICE_S;

int main(void)
{
	struct list_head *cur = NULL;
	POLICE_S *p = NULL;
	CAR_S *car = NULL;

	p = (POLICE_S *)malloc(sizeof(POLICE_S));
	if (NULL == p)
	{
		return -1;
	}

	INIT_LIST_HEAD(&p->carHead);

	for (int i = 0; i < 10; ++i)
	{
		car = (CAR_S*)malloc(sizeof(CAR_S));
		if (NULL == car)
		{
			return -1;
		}

		car->id = i;

		list_add_tail(&car->node, &p->carHead);
		p->carNum++;
	}

	list_for_each(cur, &p->carHead)
	{
		car = list_entry(cur, CAR_S, node);

		printf("id = %d\n", car->id);
	}

	return 0;
}
Copyright © Linux教程網 All Rights Reserved