Sorting interface in Linux kernel -- sort function
The sort function in the Linux kernel is actually very similar to the qsort function. Let's take a look at qsort:
Qsort function prototype is
Void qsort (void * base, size_t num, size_t width, int (_ cdecl * compare) (const void *, const void *));
Parameters:
1. First address of the array to be sorted
2. Number of elements to be sorted in the array
3. space occupied by each element
4. pointer to the function to determine the order of sorting.
The compare function should be written as follows:
| 1 2 3 4 |
intcomp(constvoid*a,constvoid*b) { return*(int*)a-*(int*)b; } |
In fact, qsort is a typical interface function for fast sorting.
Next let's take a look at the sorting interface function sort in the Linux kernel:
Void sort (void * base, size_t num, size_t size,
Int (* cmp_func) (const void *, const void *),
Void (* swap_func) (void *, void *, int size ));
Similarly:
1. First address of the array to be sorted
2. Number of elements to be sorted in the array
3. space occupied by each element
4. pointer to the function to determine the order of sorting.
5. pointer to the function, used to swap the order of elements (in fact, this can be dispensable, generally can be set to NULL (NULL) value ).
Next, let's take a look at its implementation:
Similar to the source code of the qsort function:
void sort(void *base, size_t num, size_t size, int (*cmp_func)(const void *, const void *), void (*swap_func)(void *, void *, int size)){/* pre-scale counters for performance */int i = (num/2 - 1) * size, n = num * size, c, r;if (!swap_func)swap_func = (size == 4 ? u32_swap : generic_swap);/* heapify */for ( ; i >= 0; i -= size) {for (r = i; r * 2 + size < n; r = c) {c = r * 2 + size;if (c < n - size &&cmp_func(base + c, base + c + size) < 0)c += size;if (cmp_func(base + r, base + c) >= 0)break;swap_func(base + r, base + c, size);}}/* sort */for (i = n - size; i > 0; i -= size) {swap_func(base, base + i, size);for (r = 0; r * 2 + size < i; r = c) {c = r * 2 + size;if (c < i - size &&cmp_func(base + c, base + c + size) < 0)c += size;if (cmp_func(base + r, base + c) >= 0)break;swap_func(base + r, base + c, size);}}}Next let's look at an instance program:
Extract the code from the Linux kernel and write the program:
# Include
# Include
Typedef int u32;/* fri: sort arraysec: array num thr: array only num sizefunction: function: */void sort (void * base, size_t num, size_t size, int (* cmp_func) (const void *, const void *), void (* swap_func) (void *, void *, int size); int cmpint (const void *, const void * B); static void u32_swap (void * a, void * B, int size); static void generic_swap (void * a, void * B, int size ); int main (void) {int Array [10] = {0}; int I = 0; printf ("randomly generate 10 numbers less than 100: \ n"); for (I = 0; I <10; I ++) {array [I] = rand () % 100; printf ("array [% d] = % d \ n", I, array [I]);} sort (array, 10, sizeof (int), cmpint, u32_swap); putchar ('\ n'); printf ("Number of sorted items: \ n "); for (I = 0; I <10; I ++) {printf (" arr [% d] = % d \ n ", I, array [I]);} return 0;} void sort (void * base, size_t num, size_t size, int (* cmp_func) (const void *, const void *), void (* Swap_func) (void *, void *, int size) {/* pre-scale counters for performance */int I = (num/2-1) * size, n = num * size, c, r; if (! Swap_func) swap_func = (size = 4? U32_swap: generic_swap);/* heapify */for (; I> = 0; I-= size) {for (r = I; r * 2 + size <n; r = c) {c = r * 2 + size; if (c <n-size & cmp_func (base + c, base + c + size) <0) c + = size; if (cmp_func (base + r, base + c)> = 0) break; swap_func (base + r, base + c, size );}} /* sort */for (I = n-size; I> 0; I-= size) {swap_func (base, base + I, size); for (r = 0; r * 2 + size <I; r = c) {c = r * 2 + size; if (c <I-size & cmp_func (base + c, base + c + size) <0) c + = size; if (cmp_func (base + r, base + c)> = 0) break; swap_func (base + r, base + c, size) ;}} int cmpint (const void * a, const void * B) {return * (int *) a-* (int *) B ;} static void u32_swap (void * a, void * B, int size) {u32 t = * (u32 *) a; * (u32 *) a = * (u32 *) B; * (u32 *) B = t;} static void generic_swap (void * a, void * B, int size) {char t; do {t = * (char *); * (char *) a ++ = * (char *) B; * (char *) B ++ = t;} while (-- size> 0 );}
Running result:
Generate a random number of 10 or less than 100. The following result is obtained after sorting through the sort interface sort. The verification is successful!