aboutsummaryrefslogtreecommitdiffstats
path: root/lib/sort.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 12:52:05 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-06-26 12:52:05 -0400
commit47a469421d792dcb91a1e73319d26134241953d2 (patch)
tree6a388381a434ebe87fed2fbb10a53ced7a7ce8b5 /lib/sort.c
parentc13c81006314ad76c2b31824960a900385601b8b (diff)
parent51229b495340bd7a02ce3622d1966829b67054ea (diff)
Merge branch 'akpm' (patches from Andrew)
Merge second patchbomb from Andrew Morton: - most of the rest of MM - lots of misc things - procfs updates - printk feature work - updates to get_maintainer, MAINTAINERS, checkpatch - lib/ updates * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (96 commits) exit,stats: /* obey this comment */ coredump: add __printf attribute to cn_*printf functions coredump: use from_kuid/kgid when formatting corename fs/reiserfs: remove unneeded cast NILFS2: support NFSv2 export fs/befs/btree.c: remove unneeded initializations fs/minix: remove unneeded cast init/do_mounts.c: add create_dev() failure log kasan: remove duplicate definition of the macro KASAN_FREE_PAGE fs/efs: femove unneeded cast checkpatch: emit "NOTE: <types>" message only once after multiple files checkpatch: emit an error when there's a diff in a changelog checkpatch: validate MODULE_LICENSE content checkpatch: add multi-line handling for PREFER_ETHER_ADDR_COPY checkpatch: suggest using eth_zero_addr() and eth_broadcast_addr() checkpatch: fix processing of MEMSET issues checkpatch: suggest using ether_addr_equal*() checkpatch: avoid NOT_UNIFIED_DIFF errors on cover-letter.patch files checkpatch: remove local from codespell path checkpatch: add --showfile to allow input via pipe to show filenames ...
Diffstat (limited to 'lib/sort.c')
-rw-r--r--lib/sort.c23
1 files changed, 21 insertions, 2 deletions
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 @@
8#include <linux/export.h> 8#include <linux/export.h>
9#include <linux/sort.h> 9#include <linux/sort.h>
10 10
11static int alignment_ok(const void *base, int align)
12{
13 return IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) ||
14 ((unsigned long)base & (align - 1)) == 0;
15}
16
11static void u32_swap(void *a, void *b, int size) 17static void u32_swap(void *a, void *b, int size)
12{ 18{
13 u32 t = *(u32 *)a; 19 u32 t = *(u32 *)a;
@@ -15,6 +21,13 @@ static void u32_swap(void *a, void *b, int size)
15 *(u32 *)b = t; 21 *(u32 *)b = t;
16} 22}
17 23
24static void u64_swap(void *a, void *b, int size)
25{
26 u64 t = *(u64 *)a;
27 *(u64 *)a = *(u64 *)b;
28 *(u64 *)b = t;
29}
30
18static void generic_swap(void *a, void *b, int size) 31static void generic_swap(void *a, void *b, int size)
19{ 32{
20 char t; 33 char t;
@@ -50,8 +63,14 @@ void sort(void *base, size_t num, size_t size,
50 /* pre-scale counters for performance */ 63 /* pre-scale counters for performance */
51 int i = (num/2 - 1) * size, n = num * size, c, r; 64 int i = (num/2 - 1) * size, n = num * size, c, r;
52 65
53 if (!swap_func) 66 if (!swap_func) {
54 swap_func = (size == 4 ? u32_swap : generic_swap); 67 if (size == 4 && alignment_ok(base, 4))
68 swap_func = u32_swap;
69 else if (size == 8 && alignment_ok(base, 8))
70 swap_func = u64_swap;
71 else
72 swap_func = generic_swap;
73 }
55 74
56 /* heapify */ 75 /* heapify */
57 for ( ; i >= 0; i -= size) { 76 for ( ; i >= 0; i -= size) {