当前位置:   article > 正文

linux源码分析之list的实现_linux list_empty

linux list_empty

目录

list_add

list_add_tail

list_del

list_empty

list_splice

list_entry

list_for_each


  1. struct list_head {
  2. struct list_head *next, *prev;
  3. };

list_add

头插法,将新元素new使用头插法插入到head后面

  1. /*
  2. * Insert a new entry between two known consecutive entries.
  3. *
  4. * This is only for internal list manipulation where we know
  5. * the prev/next entries already!
  6. */
  7. static inline void __list_add(struct list_head *new,
  8. struct list_head *prev,
  9. struct list_head *next)
  10. {
  11. next->prev = new;
  12. new->next = next;
  13. new->prev = prev;
  14. prev->next = new;
  15. }
  16. /**
  17. * list_add - add a new entry
  18. * @new: new entry to be added
  19. * @head: list head to add it after
  20. *
  21. * Insert a new entry after the specified head.
  22. * This is good for implementing stacks.
  23. */
  24. static inline void list_add(struct list_head *new, struct list_head *head)
  25. {
  26. __list_add(new, head, head->next);
  27. }

list_add_tail

尾插法,将新元素插入尾部,因为是循环链表,直接插在head前面也就相当于插在链表

  1. static inline void __list_add(struct list_head *new,
  2. struct list_head *prev,
  3. struct list_head *next)
  4. {
  5. next->prev = new;
  6. new->next = next;
  7. new->prev = prev;
  8. prev->next = new;
  9. }
  10. /**
  11. * list_add_tail - add a new entry
  12. * @new: new entry to be added
  13. * @head: list head to add it before
  14. *
  15. * Insert a new entry before the specified head.
  16. * This is useful for implementing queues.
  17. */
  18. static inline void list_add_tail(struct list_head *new, struct list_head *head)
  19. {
  20. __list_add(new, head->prev, head);
  21. }

list_del

删除链表中的指定元素

  1. /*
  2. * These are non-NULL pointers that will result in page faults
  3. * under normal circumstances, used to verify that nobody uses
  4. * non-initialized list entries.
  5. */
  6. #define LIST_POISON1 ((void *) 0x00100100)
  7. #define LIST_POISON2 ((void *) 0x00200200)
  8. /*
  9. * Delete a list entry by making the prev/next entries
  10. * point to each other.
  11. *
  12. * This is only for internal list manipulation where we know
  13. * the prev/next entries already!
  14. */
  15. static inline void __list_del(struct list_head * prev, struct list_head * next)
  16. {
  17. next->prev = prev;
  18. prev->next = next;
  19. }
  20. /**
  21. * list_del - deletes entry from list.
  22. * @entry: the element to delete from the list.
  23. * Note: list_empty() on entry does not return true after this, the entry is
  24. * in an undefined state.
  25. */
  26. static inline void list_del(struct list_head *entry)
  27. {
  28. __list_del(entry->prev, entry->next);
  29. entry->next = LIST_POISON1;
  30. entry->prev = LIST_POISON2;
  31. }

list_empty

判断链表是否为空

  1. /**
  2. * list_empty - tests whether a list is empty
  3. * @head: the list to test.
  4. */
  5. static inline int list_empty(const struct list_head *head)
  6. {
  7. return head->next == head;
  8. }

list_splice

合并链表,将list链表头插到head链表

  1. /**
  2. * list_empty - tests whether a list is empty
  3. * @head: the list to test.
  4. */
  5. static inline int list_empty(const struct list_head *head)
  6. {
  7. return head->next == head;
  8. }
  9. static inline void __list_splice(const struct list_head *list,
  10. struct list_head *head)
  11. {
  12. struct list_head *first = list->next;
  13. struct list_head *last = list->prev;
  14. struct list_head *at = head->next;
  15. first->prev = head;
  16. head->next = first;
  17. last->next = at;
  18. at->prev = last;
  19. }
  20. /**
  21. * list_splice - join two lists
  22. * @list: the new list to add.
  23. * @head: the place to add it in the first list.
  24. */
  25. static inline void list_splice(const struct list_head *list,
  26. struct list_head *head)
  27. {
  28. if (!list_empty(list))
  29. __list_splice(list, head);
  30. }

list_entry

获取结构体实例的首地址

  1. #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
  2. /**
  3. * container_of - cast a member of a structure out to the containing structure
  4. * @ptr: the pointer to the member.
  5. * @type: the type of the container struct this is embedded in.
  6. * @member: the name of the member within the struct.
  7. *
  8. */
  9. #define container_of(ptr, type, member) ({ \
  10. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
  11. (type *)( (char *)__mptr - offsetof(type,member) );})
  12. /**
  13. * list_entry - get the struct for this entry
  14. * @ptr: the &struct list_head pointer.
  15. * @type: the type of the struct this is embedded in.
  16. * @member: the name of the list_struct within the struct.
  17. */
  18. #define list_entry(ptr, type, member) \
  19. container_of(ptr, type, member)
  1. //最终的宏定义如下:
  2. //ptr:结构体实例中特定成员的地址
  3. //type:结构体类型
  4. //member:结构体实例中特定成员的名称
  5. #define list_entry(ptr, type, member) ({ \
  6. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
  7. (type *)( (char *)__mptr - &((type *)0)->member) );})
  8. /*
  9. &(type *)0)->member: 在0x0地址上面建立sizeof(type)个字节的type结构体, ->member 取出这个0地址上type结构体里的member成员,最后获取到member距离0x0的偏移.
  10. typeof( ((type *)0)->member ): 获取member的类型
  11. const typeof( ((type *)0)->member ) *__mptr = (ptr): 定义一个指针__mptr指向实际地址
  12. (type *)( (char *)__mptr - &((type *)0)->member) ):m_ptr代表的地址减去member在结构体中的偏移,即为结构体实例的首地址
  13. */

写到这,突然有个感慨:有些自己觉得不合理的东西,可能是因为自己的无知造成的.

list_for_each

遍历链表

  1. //__builtin_prefetch() 是 gcc 的一个内置函数。它通过对数据手工预取的方法,减少了读取延迟,从而提高了性能,但该函数也需要 CPU 的支持。
  2. void __builtin_prefetch (const void *addr, ...);
  3. #define prefetch(x) __builtin_prefetch(x)
  4. /**
  5. * list_for_each - iterate over a list
  6. * @pos: the &struct list_head to use as a loop cursor.
  7. * @head: the head for your list.
  8. */
  9. #define list_for_each(pos, head) \
  10. for (pos = (head)->next; prefetch(pos->next), pos != (head); \
  11. pos = pos->next)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/128103
推荐阅读
相关标签
  

闽ICP备14008679号