diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 12:52:05 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-06-26 12:52:05 -0400 |
commit | 47a469421d792dcb91a1e73319d26134241953d2 (patch) | |
tree | 6a388381a434ebe87fed2fbb10a53ced7a7ce8b5 /lib/sort.c | |
parent | c13c81006314ad76c2b31824960a900385601b8b (diff) | |
parent | 51229b495340bd7a02ce3622d1966829b67054ea (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.c | 23 |
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 | ||
11 | static 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 | |||
11 | static void u32_swap(void *a, void *b, int size) | 17 | static 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 | ||
24 | static 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 | |||
18 | static void generic_swap(void *a, void *b, int size) | 31 | static 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) { |