linux内核list.h

1.返回TYPE类型结构中MEMBER的偏移量
#define    offsetof(TYPE, MEMBER)    ((size_t) &((TYPE *)0)->MEMBER)


2.构造一个包含member成员的type类型的结构体,并返回结构体的首地址,其中ptr为指向member的指针
#define container_of(ptr, type, member) ({          \
const typeof(((type *)0)->member)*__mptr = (ptr);    \
(type *)((char *)__mptr - offsetof(type, member)); })


3.初始化一个链表
struct list_head {
struct list_head *next, *prev;
};


4.初始化一个空链表
#define    LIST_HEAD_INIT(name)    { &(name), &(name) }


5.定义并初始化一个空的双向循环链表
#define    LIST_HEAD(name)     struct list_head name = LIST_HEAD_INIT(name)


6.初始化一个空链表
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}


7.在prev节点和next节点之间插入new节点
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;
}


8.在指定的head节点后插入一个新节点(entry:条目(节点))构成一个栈结构:后进先出
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}


9.在指定的head节点前插入一个新节点,构成一个队列结构:先进先出
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}


10.通过使某个节点的prev节点和next节点指向对方而删除此节点(只能用来操作已经知道prev节点和next节点的内部链表)
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}


11.删除entry节点(执行此操作后,节点变成未定义状态,若再执行list_empty(),将不能返回true.LIST_POISON1和LIST_POISON2指向的地址不可访问,访问会出错。)
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
entry->next = LIST_POISON1;
entry->prev = LIST_POISON2;
}


12.新节点取代旧节点(若旧节点为空,就会被新节点覆盖)
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;
}


13.新节点取代旧节点后,并将旧节点置为空链表
static inline void list_replace_init(struct list_head *old,struct list_head *new)
{
list_replace(old, new);
INIT_LIST_HEAD(old);
}


14.删除entry节点后,将entry节点置为空链表
static inline void list_del_init(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
INIT_LIST_HEAD(entry);
}


15.将list节点从链表中删除并将list节点插入到链表头部
static inline void list_move(struct list_head *list, struct list_head *head)
{
__list_del(list->prev, list->next);
list_add(list, head);
}


16.将list节点从链表中删除并将list节点插入到链表尾部
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);
}


17.检测list节点是否是以head开始的链表的最后一个节点
static inline int list_is_last(const struct list_head *list,const struct list_head *head)
{
return list->next == head;
}


18.检测以head开头的链表是否是空链表
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}


19.它同时判断头指针的next和prev,仅当两者都指向自己时才返回真。这主要是为了应付另一个cpu正在处理同一个链表而造成next、prev不一致的情况。  
但这一安全保障能力有限:除非其他cpu的链表操作只有list_del_init(),另一CPU不能重新list_add(),否则仍然不能保证安全,也就是说,还是需要加锁保护。

static inline int list_empty_careful(const struct list_head *head)
{
struct list_head *next = head->next;
return (next == head) && (next == head->prev);
}


20.测试链表是否仅有一个节点(仅有head的话为空链表)
static inline int list_is_singular(const struct list_head *head)
{
return !list_empty(head) && (head->next == head->prev);
}


21.分割链表,将原链表头结点head后至entry(包括entry结点)之间的所有结点与entry后面的其它结点切割开,使他们成为一个以list为头结点的新链表。
static inline void __list_cut_position(struct list_head *list,struct list_head *head,struct list_head *entry)
{
struct list_head *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;
}


22.分割链表
static inline void list_cut_position(struct list_head *list,struct list_head *head,struct list_head *entry)
{
if (list_empty(head))
return;
if (list_is_singular(head) && (head->next != entry && head != entry))
return;
if (entry == head)
INIT_LIST_HEAD(list);
else
__list_cut_position(list, head, entry);
}


23.拼接链表,
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;
}


24.拼接链表,将list合并到head链表的表头(栈)
初级:
static inline void list_splice(const struct list_head *list,struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head, head->next);
}
进阶:
static inline void list_splice_init(struct list_head *list,struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head, head->next);
INIT_LIST_HEAD(list);//为避免引起混乱,调用INIT_LIST_HEAD(list)将list设置为空链
}
}


25.拼接链表,将list合并到head链表的表尾(队列)
初级:
static inline void list_splice_tail(struct list_head *list,struct list_head *head)
{
if (!list_empty(list))
__list_splice(list, head->prev, head);
}
进阶:
static inline void list_splice_tail_init(struct list_head *list,struct list_head *head)
{
if (!list_empty(list)) {
__list_splice(list, head->prev, head);
INIT_LIST_HEAD(list);
}
}


26.获得此节点的结构体。ptr:指向list_struct的指针;type:构造的结构体的类型;member:构造的结构体中的list_struct的名字
#define    list_entry(ptr, type, member)    container_of(ptr, type, member)


27.获得链表中的第一个成员
#define    list_first_entry(ptr, type, member)    list_entry((ptr)->next, type, member)


28.遍历链表
#define    list_for_each(pos, head)    for (pos = (head)->next; pos != (head); pos = pos->next)


29逆序(向前)遍历链表
#define    list_for_each_prev(pos, head)    for (pos = (head)->prev; pos != (head); pos = pos->prev)


30.安全的遍历链表。多了一个与pos同类型的n,每次将下一个结点的指针暂存起来,防止pos被释放时引起的链表断裂。
#define     list_for_each_safe(pos, n, head)     for (pos = (head)->next, n = pos->next; pos != (head);pos = n, n = pos->next)


31.安全的逆序(向前)遍历链表
#define    list_for_each_prev_safe(pos, n, head)    for (pos = (head)->prev, n = pos->prev;pos != (head); pos = n, n = pos->prev)


32.遍历链表并直接使pos指向构造的结构体
#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))


33.逆序遍历链表并直接使pos指向构造的结构体

#define list_for_each_entry_reverse(pos, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member);&pos->member != (head);pos = list_entry(pos->member.prev, typeof(*pos), member))


34.准备一个节点的位置,作为list_for_each_entry_continue()的开始指针
#define    list_prepare_entry(pos, head, member)    ((pos) ? : list_entry(head, typeof(*pos), member))


35.从当前位置pos处继续遍历给定类型的链表
#define list_for_each_entry_continue(pos, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member);&pos->member != (head);pos = list_entry(pos->member.next, typeof(*pos), member))


36.逆序从当前位置pos处继续遍历给定类型的链表
#define list_for_each_entry_continue_reverse(pos, head, member) \
for (pos = list_entry(pos->member.prev, typeof(*pos), member);&pos->member != (head);pos = list_entry(pos->member.prev, typeof(*pos), member))


37.从指定位置pos遍历给定类型的链表
#define list_for_each_entry_from(pos, head, member) \
for (; &pos->member != (head);pos = list_entry(pos->member.next, typeof(*pos), member))


38.安全的遍历链表并直接使pos指向构造的结构体
#define list_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 = list_entry(n->member.next, typeof(*n), member))


39.安全的从当前位置pos处继续遍历给定类型的链表
#define list_for_each_entry_safe_continue(pos, n, head, member) \
for (pos = list_entry(pos->member.next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
    &pos->member != (head); \
    pos = n, n = list_entry(n->member.next, typeof(*n), member))


40.安全的从指定位置pos遍历给定类型的链表
#define list_for_each_entry_safe_from(pos, n, head, member) \
for (n = list_entry(pos->member.next, typeof(*pos), member); \
    &pos->member != (head); \
   pos = n, n = list_entry(n->member.next, typeof(*n), member))

41.安全的逆序遍历链表并直接使pos指向构造的结构体
#define list_for_each_entry_safe_reverse(pos, n, head, member) \
for (pos = list_entry((head)->prev, typeof(*pos), member), \
n = list_entry(pos->member.prev, typeof(*pos), member); \
    &pos->member != (head); \
    pos = n, n = list_entry(n->member.prev, typeof(*n), member))









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值