#ifndef __LIST_H__
#define __LIST_H__
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#endif
#ifndef container_of
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
#endif
struct dList {
struct dList *next, *prev;
};
//当我们知道dList的地址时,可以通过list_entry这个宏获取它的父结构的地址。
//所以这个宏的功能就是由结构体成员的地址求结构体的地址。其中ptr是所求结构体中
//dList成员的指针,type是所求结构体的类型,member是结构体dList成员名
#define dlist_entry(ptr, type, member) \
container_of(ptr, type, member)
#define LIST_HEAD_INIT(name) { &(name), &(name) }
//生成名字为name的双向链表的头节点
#define LIST_HEAD(name) \
struct dList name = LIST_HEAD_INIT(name)
//初始化链表头
static inline void INIT_LIST_HEAD(struct dList *list)
{
//链表的前一个节点和后一个节点都指向它自己
list->next = list;
list->prev = list;
}
static inline void __list_add(struct dList *_new, struct dList *prev, struct dList *next)
{
next->prev = _new;
_new->next = next;
_new->prev = prev;
prev->next = _new;
}
//双向链表插入节点的操作---在头节点head的下一个节点,即是头插
static inline void dlist_add(struct dList *_new, struct dList *head)
{
__list_add(_new, head, head->next);
}
//双向链表插入节点的操作---向尾部插入_new节点
static inline void dlist_add_tail(struct dList *_new, struct dList *head)
{
__list_add(_new, head->prev, head);
}
//判断链表是不是空的,如果空返回真,否则返回假
//也就是判断表头的节点的下一个节点是不是它本身
static inline int dlist_empty(const struct dList *head)
{
return head->next == head;
}
//获取双向链表的第一个节点
static inline struct dList* dlist_get_first(struct dList *head)
{
if (!head)
{
return NULL;
}
if (dlist_empty(head))
{
return NULL;
}
return head->next;
}
//获取双向链表的尾节点
static inline struct dList* dlist_get_tail(struct dList *head)
{
if (!head)
{
return NULL;
}
if (dlist_empty(head))
{
return NULL;
}
return head->prev;
}
static inline void __list_del(struct dList * prev, struct dList * next)
{
next->prev = prev;
prev->next = next;
}
//双向链表中节点删除 ,并把被删除的位置清0
static inline void dlist_del(struct dList *entry)
{
__list_del(entry->prev, entry->next);
entry->next = NULL;
entry->prev = NULL;
}
static inline void __list_del_entry(struct dList *entry)
{
__list_del(entry->prev, entry->next);
}
//将上面entry被删除的节点重新初始化
static inline void dlist_del_init(struct dList *entry)
{
__list_del_entry(entry);
INIT_LIST_HEAD(entry);
}
//将老的节点old换成新的节点_new
static inline void dlist_replace(struct dList *old,
struct dList *_new)
{
_new->next = old->next;
_new->next->prev = _new;
_new->prev = old->prev;
_new->prev->next = _new;
}
//将上面的过程进行重新初始化
static inline void dlist_replace_init(struct dList *old,
struct dList *_new)
{
dlist_replace(old, _new);
INIT_LIST_HEAD(old);
}
//将链表中的list节点移动到链表的头部
static inline void dlist_move(struct dList *list, struct dList *head)
{
__list_del_entry(list);
dlist_add(list, head);
}
//判断当前链表list节点是不是链表的最后一个节点
static inline int dlist_is_last(const struct dList *list,
const struct dList *head)
{
return list->next == head;
}
//判断链表是不是空的,如果空返回真,否则返回假 ,稍微和上面有区别的是
//判断表头的前一个节点和后一个节点是否为本身,是返回真,不是,返回假
//也就是prev和next
static inline int dlist_empty_careful(const struct dList *head)
{
struct dList *next = head->next;
return (next == head) && (next == head->prev);
}
/**
* 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 dlist_move_tail(struct dList *list,
struct dList *head)
{
__list_del(list->prev, list->next);
dlist_add_tail(list, head);
}
//将链表进行翻转,也就是将head的next和head的本身做交换
static inline void dlist_rotate_left(struct dList *head)
{
struct dList *first;
if (!dlist_empty(head)) {
first = head->next;
dlist_move_tail(first, head);
}
}
//判断链表中是否只有一个节点
static inline int dlist_is_singular(const struct dList *head)
{
return !dlist_empty(head) && (head->next == head->prev);
}
static inline void __list_cut_position(struct dList *list,
struct dList *head, struct dList *entry)
{
struct dList *_new_first = entry->next;
list->next = head->next;
list->next->prev = list;
list->prev = entry;
entry->next = list;
head->next = _new_first;
_new_first->prev = head;
}
//分割链表,以entry为界限进行分割,分割完后的另一半的那条链表被list所指
static inline void dlist_cut_position(struct dList *list,
struct dList *head, struct dList *entry)
{
if (dlist_empty(head))
return;
if (dlist_is_singular(head) &&
(head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}
static inline void __list_splice(const struct dList *list,
struct dList *prev,
struct dList *next)
{
struct dList *first = list->next;
struct dList *last = list->prev;
first->prev = prev;
prev->next = first;
last->next = next;
next->prev = last;
}
//将list和head这两条链表合并,注意,链表不能为空
static inline void dlist_splice(const struct dList *list,
struct dList *head)
{
if (!dlist_empty(list))
__list_splice(list, head, head->next);
}
//将list和head这两条链表合并后并初始化
static inline void dlist_splice_init(struct dList *list,
struct dList *head)
{
if (!dlist_empty(list)) {
__list_splice(list, head, head->next);
INIT_LIST_HEAD(list);
}
}
#define prefetch(x) __builtin_prefetch(x)
//双向链表的正向遍历,从前往后
#define dlist_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)
//双向链表的遍历,跟上面那个有所不同的是,下面这个添加了通过list_entry,方便很多
#define dlist_for_each_entry(pos, head, member) \
for (pos = dlist_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = dlist_entry(pos->member.next, typeof(*pos), member))
//如果遍历链表不是从头开始,而是从某个已知的节点pos开始, 从当前的位置往后遍历,注意和头的情况区分
#define dlist_for_each_entry_continue(pos, head, member) \
for (pos = dlist_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = dlist_entry(pos->member.next, typeof(*pos), member))
//双向链表的反向遍历,从后往前
#define dlist_for_each_prev(pos, head) \
for (pos = (head)->prev; pos != (head); pos = pos->prev)
//双向链表遍历的时候可以同时删除pos节点
#define dlist_for_each_safe(pos, n, head) \
for (pos = (head)->next, n = pos->next; pos != (head); \
pos = n, n = pos->next)
//提供一个和pos一样的指针n,在for循环中暂时保留pos的下一个节点的地址,避免因pos节点被释放而造成断链的结果
#define dlist_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = dlist_entry(n->member.next, typeof(*n), member))
#endif