Linux內核的list_head民用改造

修復博客:http://blog.csdn.net/lh806732/article/details/53946839

list_head.h

#pragma once
#ifndef __LIST_HEAD_H__
#define __LIST_HEAD_H__



#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>


#define offsetof(TYPE, MEMBER)					(((size_t)(&((TYPE *)0)->MEMBER)))// 得到結構體成員在結構體中的偏移量
#define container_of(ptr, type, member)			((type *)((char *)ptr - offsetof(type, member)))// 得到指向結構體指針的首地址
#define list_for_each(pos, head)				        for (pos = (head)->next; pos != (head); pos = pos->next)// for循環
#define list_for_each_r(pos, head)				    for (pos = (head)->prev; pos != (head); pos = pos->prev)// 反向for循環
#define list_entry(ptr, type, member)			    container_of(ptr, type, member)// 根據‘指向結構體list_head_t成員指針’和‘結構體類型’以及結構體中‘list_head_t成員名’得到結構體首地址




	typedef struct list_head
	{
		struct list_head *prev;
		struct list_head *next;
	} list_head_t, *plist_head_t;


	typedef enum list_type
	{
		TYPE_UNKNOWN = -1,// 未知類型
		TYPE_STACK,// 棧類型的列表
		TYPE_QUEUE,// 隊列類型的列表
	} list_type_t;




	extern int list_head_init(list_head_t *head);// 初始化表頭,使用列表前必須初始化表頭
	extern int list_push_stack(list_head_t *entry, list_head_t *head);// 作爲棧使用,把entry壓入到以head爲表頭的列表中
	extern list_head_t *list_pop_stack(list_head_t *head);// 作爲棧使用,把以head爲表頭的列表中的棧頂節點出棧
	extern int list_enqueue(list_head_t *entry, list_head_t *head);// 作爲隊列使用,把entry入列到以head爲表頭的列表中
	extern list_head_t *list_dequeue(list_head_t *head);// 作爲隊列使用,把以head爲表頭的列表中隊列頭的節點出列
	extern int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type);// 在ref節點的前面插入entry節點
	extern int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type);// 在ref節點的後面插入entry節點
	extern int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next);// 在prev和next節點之間插入entry節點
	extern list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head);// 從以head爲表頭的列表中刪除entry節點,僅僅斷開節點,返回斷開節點後調用者釋放內存
	extern int list_is_empty(const list_head_t *head);// 以head爲表頭的列表是否爲空
	extern int list_size(const list_head_t *head);// 獲取以head爲表頭的列表的大小
	extern int list_splice_to_head(list_head_t *_new, list_head_t *head);// 把新的列表_new合併到以head爲表頭的列表的頭部
	extern int list_splice_to_tail(list_head_t *_new, list_head_t *head);// 把新的列表_new合併到以head爲表頭的列表的尾部
	extern int list_replace(list_head_t *_new, list_head_t *old);// 把列表中old節點替換爲新的_new節點
	extern int list_revese(list_head_t *head);// 把以head爲表頭的列表中的所有節點前後順序倒置,倒置後仍然以head爲表頭





#ifdef __cplusplus
}
#endif

#endif

list_head.c


#include "list_head.h"
#include <stdio.h>






#define LIST_POINT1				((void *)0x00100100)
#define LIST_POINT2				((void *)0x00200200)




typedef enum splice_mode
{
	SPLICE_UNKNOWN = -1,
	SPLICE_HEAD, // 合併列表時把新的列表合併都原有列表的表頭
	SPLICE_TAIL, // 合併列表時把新的列表合併都原有列表的表尾
} splice_mode_t;




static void __list_add(list_head_t *entry, list_head_t *prev, list_head_t *next);
static void __list_del(list_head_t *entry, list_head_t *prev, list_head_t *next);
static int __list_splice(list_head_t *list, list_head_t *head, splice_mode_t mode);






/***************************************************************************************************
* 函數名:int list_head_init(list_head_t *head)
* 功能描述:初始化表頭,使用列表前必須初始化表頭
* 輸入參數:
* 	head	:列表表頭
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_head_init(list_head_t *head)
{
	if (NULL == head)
	{
		return -1;
	}

	head->prev = head;
	head->next = head;

	return 0;
}

/***************************************************************************************************
* 函數名:int list_push_stack(list_head_t *entry, list_head_t *head)
* 功能描述:作爲棧使用,把entry壓入到以head爲表頭的列表中
* 輸入參數:
* 	entry	:待壓棧節點
*	head	: 以head爲表頭的列表
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_push_stack(list_head_t *entry, list_head_t *head)
{
	if (NULL == entry || NULL == head)
	{
		return -1;
	}

	__list_add(entry, head, head->next);

	return 0;
}

/***************************************************************************************************
* 函數名:list_head_t *list_pop_stack(list_head_t *head)
* 功能描述:作爲棧使用,把以head爲表頭的列表中的棧頂節點出棧
* 輸入參數:
*	head	: 以head爲表頭的列表
* 輸出參數:
*	無
* 返回值:
*	非NULL	:成功
*	NULL	:失敗
***************************************************************************************************/
inline list_head_t *list_pop_stack(list_head_t *head)
{
	if (list_is_empty(head))
	{
		return NULL;
	}

	list_head_t *entry = head->next;
	if (head != entry)
	{
		//list_head_t *next = entry->next;
		//head->next = next;
		//next->prev = head;

		__list_del(entry, entry->prev, entry->next);

		return entry;
	}

	return NULL;
}

/***************************************************************************************************
* 函數名:int list_enqueue(list_head_t *entry, list_head_t *head)
* 功能描述:作爲隊列使用,把entry入列到以head爲表頭的列表中
* 輸入參數:
* 	entry	:待入列節點
*	head	: 以head爲表頭的列表
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_enqueue(list_head_t *entry, list_head_t *head)
{
	if (NULL == entry || NULL == head)
	{
		return -1;
	}

	__list_add(entry, head->prev, head);

	return 0;
}

/***************************************************************************************************
* 函數名:list_head_t *list_dequeue(list_head_t *head)
* 功能描述:作爲隊列使用,把以head爲表頭的列表中隊列頭的節點出列
* 輸入參數:
*	head	: 以head爲表頭的列表
* 輸出參數:
*	無
* 返回值:
*	非NULL	:成功
*	NULL	:失敗
***************************************************************************************************/
inline list_head_t *list_dequeue(list_head_t *head)
{
	return list_pop_stack(head);
}

inline void __list_add(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
	next->prev = entry;
	entry->next = next;
	entry->prev = prev;
	prev->next = entry;
}

/***************************************************************************************************
* 函數名:int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type)
* 功能描述:在ref節點的前面插入entry節點
* 輸入參數:
*	entry	: 待插入節點
*	ref		: 插入點的參考節點
*	type	: 是否以棧還是隊列方式進行操作
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_insert_before(list_head_t *entry, list_head_t *ref, list_type_t type)
{
	if (NULL == entry || NULL == ref || TYPE_UNKNOWN == type)
	{
		return -1;
	}

	if (ref->prev == ref->next && ref == ref->prev)// 空列表
	{
		return -1;
	}

	if (TYPE_STACK == type)// 棧
	{
		__list_add(entry, ref, ref->next);
	}
	else if (TYPE_QUEUE == type)// 隊列
	{
		__list_add(entry, ref->prev, ref);
	}

	return 0;
}

/***************************************************************************************************
* 函數名:int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type)
* 功能描述:在ref節點的後面插入entry節點
* 輸入參數:
*	entry	: 待插入節點
*	ref		: 插入點的參考節點
*	type	: 是否以棧還是隊列方式進行操作
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_insert_after(list_head_t *entry, list_head_t *ref, list_type_t type)
{
	if (NULL == entry || NULL == ref || TYPE_UNKNOWN == type)
	{
		return -1;
	}

	if (ref->prev == ref->next && ref == ref->prev)// 空列表
	{
		return -1;
	}

	if (TYPE_STACK == type)// 棧
	{
		__list_add(entry, ref->prev, ref);
	}
	else if (TYPE_QUEUE == type)// 隊列
	{
		__list_add(entry, ref, ref->next);
	}

	return 0;
}

/***************************************************************************************************
* 函數名:int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next)
* 功能描述:在prev和next節點之間插入entry節點
* 輸入參數:
*	entry	: 待插入節點
*	prev	: entry前節點
*	next	: entry後節點
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_insert(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
	if (NULL == entry || NULL == prev || NULL == next)
	{
		return -1;
	}

	if ((prev == next) || // 空列表
		(prev->prev == prev->next && prev->prev == next))// 列表只有1個節點
	{
		return -1;// 無節點或1個節點沒法插入,返回失敗
	}

	if (prev->next == next)
	{
		__list_add(entry, prev, next);
	}
	else if (prev->prev == next)// 調用者把插入點前後傳錯了
	{
		__list_add(entry, next, prev);
	}
	else // 前後節點不相鄰
	{
		return -1;
	}

	return 0;
}

/***************************************************************************************************
* 函數名:list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head)
* 功能描述:從以head爲表頭的列表中刪除entry節點,僅僅斷開節點,返回斷開節點後調用者釋放內存
* 輸入參數:
*	entry	: 待插入節點
*	head	: 列表表頭
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline list_head_t *list_delete_entry(list_head_t *entry, list_head_t *head)
{
	if (list_is_empty(head) || NULL == entry || head == entry)
	{
		return NULL;
	}

	__list_del(entry, entry->prev, entry->next);

	return entry;
}

inline void __list_del(list_head_t *entry, list_head_t *prev, list_head_t *next)
{
	next->prev = prev;
	prev->next = next;

#if 0// 編譯段錯誤(內核中)?
	entry->prev = LIST_POINT1;
	entry->next = LIST_POINT2;
#else
	entry->prev = NULL;
	entry->next = NULL;
#endif
}

/***************************************************************************************************
* 函數名:int list_is_empty(const list_head_t *head)
* 功能描述:以head爲表頭的列表是否爲空
* 輸入參數:
*	head	: 列表表頭
* 輸出參數:
*	無
* 返回值:
*	1		:空
*	0		:非空
***************************************************************************************************/
inline int list_is_empty(const list_head_t *head)
{
	if (NULL == head)
	{
		return 1;
	}

	return head->next == head;
}

/***************************************************************************************************
* 函數名:int list_size(const list_head_t *head)
* 功能描述:獲取以head爲表頭的列表的大小
* 輸入參數:
*	head	: 列表表頭
* 輸出參數:
*	無
* 返回值:
*	>0		:非空
*	0		:空
***************************************************************************************************/
inline int list_size(const list_head_t *head)
{
	int size = 0;
	list_head_t *entry = NULL;

	if (NULL == head)
	{
		return 0;
	}

	list_for_each(entry, head)
	{
		size++;
	}

	return size;
}

/***************************************************************************************************
* 函數名:int list_splice_to_head(list_head_t *_new, list_head_t *head)
* 功能描述:把新的列表_new合併到以head爲表頭的列表的頭部
* 輸入參數:
*	_new	: 待合併列表
*	head	: 原有列表
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_splice_to_head(list_head_t *_new, list_head_t *head)
{
	return __list_splice(_new, head, SPLICE_HEAD);
}

/***************************************************************************************************
* 函數名:int list_splice_to_tail(list_head_t *_new, list_head_t *head)
* 功能描述:把新的列表_new合併到以head爲表頭的列表的尾部
* 輸入參數:
*	_new	: 待合併列表
*	head	: 原有列表
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_splice_to_tail(list_head_t *_new, list_head_t *head)
{
	return __list_splice(_new, head, SPLICE_TAIL);
}

inline int __list_splice(list_head_t *list, list_head_t *head, splice_mode_t mode)
{
	list_head_t *first = NULL;
	list_head_t *last = NULL;

	if (NULL == list || list_is_empty(list) || list_is_empty(head) || SPLICE_UNKNOWN == mode)
	{
		return -1;
	}

	first = list->next;
	last = list->prev;

	if (SPLICE_HEAD == mode)
	{
		list_head_t *at = head->next;

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

		last->next = at;
		at->prev = last;
	}
	else if (SPLICE_TAIL == mode)
	{
		list_head_t *at = head->prev;

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

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

	return 0;
}

/***************************************************************************************************
* 函數名:int list_replace(list_head_t *_new, list_head_t *old)
* 功能描述:把列表中old節點替換爲新的_new節點
* 輸入參數:
*	_new	: 待替換節點
*	old		: 被替換節點
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_replace(list_head_t *_new, list_head_t *old)
{
	if (NULL == _new || NULL == old)
	{
		return -1;
	}
	_new->next = old->next;
	_new->next->prev = _new;

	_new->prev = old->prev;
	_new->prev->next = _new;

	return 0;
}

/***************************************************************************************************
* 函數名:int list_revese(list_head_t *head)
* 功能描述:把以head爲表頭的列表中的所有節點前後順序倒置,倒置後仍然以head爲表頭
* 輸入參數:
*	head	: 表頭
* 輸出參數:
*	無
* 返回值:
*	0		:成功
*	-1		:失敗
***************************************************************************************************/
inline int list_revese(list_head_t *head)
{
	list_head_t *first = NULL;
	list_head_t *entry = NULL;

	if (NULL == head)
	{
		return -1;
	}

	if (list_is_empty(head))
	{
		return -1;
	}

	first = head->next;

	while (head != first->next)
	{
		entry = first->next;

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

		head->next->prev = entry;
		entry->next = head->next;

		head->next = entry;
		entry->prev = head;
	}

	return 0;
}

 

發佈了32 篇原創文章 · 獲贊 5 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章