X-Git-Url: http://git.cascardo.info/?a=blobdiff_plain;f=lib%2Fsort.c;h=fc20df42aa6f2945aae8586c3c4d3599ca6d67f0;hb=6f3cdb380f429af47ad6635568c22ba28df83a48;hp=43c9fe73ae2e2f8e4de7d6b419369133719ae36f;hpb=cb8a4deaf9b2778653c4391d8ccb24c5ab159f9d;p=cascardo%2Flinux.git diff --git a/lib/sort.c b/lib/sort.c index 43c9fe73ae2e..fc20df42aa6f 100644 --- a/lib/sort.c +++ b/lib/sort.c @@ -8,6 +8,12 @@ #include #include +static int alignment_ok(const void *base, int align) +{ + return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) || + ((unsigned long)base & (align - 1)) == 0; +} + static void u32_swap(void *a, void *b, int size) { u32 t = *(u32 *)a; @@ -15,6 +21,13 @@ static void u32_swap(void *a, void *b, int size) *(u32 *)b = t; } +static void u64_swap(void *a, void *b, int size) +{ + u64 t = *(u64 *)a; + *(u64 *)a = *(u64 *)b; + *(u64 *)b = t; +} + static void generic_swap(void *a, void *b, int size) { char t; @@ -50,8 +63,14 @@ void sort(void *base, size_t num, size_t 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); + if (!swap_func) { + if (size == 4 && alignment_ok(base, 4)) + swap_func = u32_swap; + else if (size == 8 && alignment_ok(base, 8)) + swap_func = u64_swap; + else + swap_func = generic_swap; + } /* heapify */ for ( ; i >= 0; i -= size) {