* td_list_sort - sort a list * @head: the list to sort * @cmp: the elements comparison function * * This function implements "merge sort", which has O(nlog(n)) * complexity. * * The comparison function @cmp must return a negative value if @a * should sort before @b, and a positive value if @a should sort after * @b. If @a and @b are equivalent, and their original relative * ordering is t
| 129 | * ordering is to be preserved, @cmp must return 0. |
| 130 | */ |
| 131 | void td_list_sort(struct td_list_head *head, |
| 132 | int (*cmp)(const struct td_list_head *a, const struct td_list_head *b)) |
| 133 | { |
| 134 | struct td_list_head *part[MAX_LIST_LENGTH_BITS+1]; /* sorted partial lists |
| 135 | -- last slot is a sentinel */ |
| 136 | unsigned int lev; /* index into part[] */ |
| 137 | unsigned int max_lev = 0; |
| 138 | struct td_list_head *list; |
| 139 | |
| 140 | if (td_list_empty(head)) |
| 141 | return; |
| 142 | |
| 143 | memset(part, 0, sizeof(part)); |
| 144 | |
| 145 | head->prev->next = NULL; |
| 146 | list = head->next; |
| 147 | |
| 148 | /*@ |
| 149 | @ loop invariant \valid_function(cmp); |
| 150 | @*/ |
| 151 | while (list) { |
| 152 | struct td_list_head *cur = list; |
| 153 | list = list->next; |
| 154 | cur->next = NULL; |
| 155 | |
| 156 | /*@ |
| 157 | @ loop invariant \valid_function(cmp); |
| 158 | @*/ |
| 159 | for (lev = 0; part[lev]; lev++) { |
| 160 | cur = merge(cmp, part[lev], cur); |
| 161 | part[lev] = NULL; |
| 162 | } |
| 163 | if (lev > max_lev) { |
| 164 | if (lev >= MAX_LIST_LENGTH_BITS) |
| 165 | { |
| 166 | // list passed to td_list_sort() too long for efficiency |
| 167 | lev--; |
| 168 | } |
| 169 | max_lev = lev; |
| 170 | } |
| 171 | part[lev] = cur; |
| 172 | } |
| 173 | |
| 174 | /*@ |
| 175 | @ loop invariant \valid_function(cmp); |
| 176 | @*/ |
| 177 | for (lev = 0; lev < max_lev; lev++) |
| 178 | if (part[lev]) |
| 179 | list = merge(cmp, part[lev], list); |
| 180 | |
| 181 | merge_and_restore_back_links(cmp, head, part[max_lev], list); |
| 182 | } |
no test coverage detected