阅读 Linux 核心源代码 lib/list_sort.c
Linux 核心代码中,对链表的排序算法是一种归并排序的变种。采用的排序方式为自下而上 的排序,这种方式可以避免 cache thrashing。 合并时机 Linux 中的对归并排序的改进主要是改变了两个链表的合并时机。该算法会有一个 pending 链表用来记录排序好的子链表,且保证每个子链表的长度都为 $2^k$。当 pending 中 即将出现第三个 $2^k$ 长度的链表时,就会合并已存在的两个 $2^k$ 长度的链表使其 变为一个 $2^{k+1}$ 长度的链表,所以在 pending 链表中永远不会存在超过 2 个 长度为 $2^k$ 的链表。 使用一个变量 count 来追踪 pending 中 $2^k$ 长度链表的个数,可以通过 count 中 k+1 k k-1 这 3 个 bits 来确定 pending 中 $2^k$ 长度链表的个数。下表 中的 3 个 bits 分别表示 k+1 k k-1,当 k 为 0 时,认为 -1 bit 为 1。 count $2^k$ 长度链表个数 …000… 0 …001… 0 …010… 0 …011… 1 …100… 1 …101… 2 源码分析 __attribute__((nonnull(2,3))) void list_sort(void *priv, struct list_head *head, list_cmp_func_t cmp) { struct list_head *list = head->next, *pending = NULL; size_t count = 0; /* Count of pending */ if (list == head->prev) /* Zero or one elements */ return; /* Convert to a null-terminated singly-linked list. */ head->prev->next = NULL; // .... } 函数的参数: ...