• linux内核中list的实现


    目录

    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)

  • 相关阅读:
    【数据结构与算法系列5】螺旋矩阵II (C++ & Python)
    react中预览excel表格
    vue2+vite+vue-cli5 实现vite开发webpack打包
    ansible中waring处理方式
    基于VUE3+Layui从头搭建通用后台管理系统(前端篇)十一:通用表单组件封装实现
    linux在非联网、无网络环境下,使用yumdownload、reportrack方法安装rpm包
    【QT】Windows 编译并使用 QT 5.12.7源码
    macOS通过钥匙串访问找回WiFi密码
    3 ThreadLocal-TransmittableThreadLocal
    再手写线程池以及性能分析
  • 原文地址:https://blog.csdn.net/weixin_40179091/article/details/126798028