Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

lib: Introduce generic list_sort function

There are two copies of list_sort() in the tree already, one in the DRM
code, another in ubifs. Now XFS needs this as well. Create a generic
list_sort() function from the ubifs version and convert existing users
to it so we don't end up with yet another copy in the tree.

Signed-off-by: Dave Chinner <david@fromorbit.com>
Acked-by: Dave Airlie <airlied@redhat.com>
Acked-by: Artem Bityutskiy <dedekind@infradead.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Dave Chinner and committed by
Linus Torvalds
2c761270 dbf004d7

+119 -182
+4 -86
drivers/gpu/drm/drm_modes.c
··· 1 1 /* 2 - * The list_sort function is (presumably) licensed under the GPL (see the 3 - * top level "COPYING" file for details). 4 - * 5 - * The remainder of this file is: 6 - * 7 2 * Copyright © 1997-2003 by The XFree86 Project, Inc. 8 3 * Copyright © 2007 Dave Airlie 9 4 * Copyright © 2007-2008 Intel Corporation ··· 31 36 */ 32 37 33 38 #include <linux/list.h> 39 + #include <linux/list_sort.h> 34 40 #include "drmP.h" 35 41 #include "drm.h" 36 42 #include "drm_crtc.h" ··· 851 855 852 856 /** 853 857 * drm_mode_compare - compare modes for favorability 858 + * @priv: unused 854 859 * @lh_a: list_head for first mode 855 860 * @lh_b: list_head for second mode 856 861 * ··· 865 868 * Negative if @lh_a is better than @lh_b, zero if they're equivalent, or 866 869 * positive if @lh_b is better than @lh_a. 867 870 */ 868 - static int drm_mode_compare(struct list_head *lh_a, struct list_head *lh_b) 871 + static int drm_mode_compare(void *priv, struct list_head *lh_a, struct list_head *lh_b) 869 872 { 870 873 struct drm_display_mode *a = list_entry(lh_a, struct drm_display_mode, head); 871 874 struct drm_display_mode *b = list_entry(lh_b, struct drm_display_mode, head); ··· 882 885 return diff; 883 886 } 884 887 885 - /* FIXME: what we don't have a list sort function? */ 886 - /* list sort from Mark J Roberts (mjr@znex.org) */ 887 - void list_sort(struct list_head *head, 888 - int (*cmp)(struct list_head *a, struct list_head *b)) 889 - { 890 - struct list_head *p, *q, *e, *list, *tail, *oldhead; 891 - int insize, nmerges, psize, qsize, i; 892 - 893 - list = head->next; 894 - list_del(head); 895 - insize = 1; 896 - for (;;) { 897 - p = oldhead = list; 898 - list = tail = NULL; 899 - nmerges = 0; 900 - 901 - while (p) { 902 - nmerges++; 903 - q = p; 904 - psize = 0; 905 - for (i = 0; i < insize; i++) { 906 - psize++; 907 - q = q->next == oldhead ? NULL : q->next; 908 - if (!q) 909 - break; 910 - } 911 - 912 - qsize = insize; 913 - while (psize > 0 || (qsize > 0 && q)) { 914 - if (!psize) { 915 - e = q; 916 - q = q->next; 917 - qsize--; 918 - if (q == oldhead) 919 - q = NULL; 920 - } else if (!qsize || !q) { 921 - e = p; 922 - p = p->next; 923 - psize--; 924 - if (p == oldhead) 925 - p = NULL; 926 - } else if (cmp(p, q) <= 0) { 927 - e = p; 928 - p = p->next; 929 - psize--; 930 - if (p == oldhead) 931 - p = NULL; 932 - } else { 933 - e = q; 934 - q = q->next; 935 - qsize--; 936 - if (q == oldhead) 937 - q = NULL; 938 - } 939 - if (tail) 940 - tail->next = e; 941 - else 942 - list = e; 943 - e->prev = tail; 944 - tail = e; 945 - } 946 - p = q; 947 - } 948 - 949 - tail->next = list; 950 - list->prev = tail; 951 - 952 - if (nmerges <= 1) 953 - break; 954 - 955 - insize *= 2; 956 - } 957 - 958 - head->next = list; 959 - head->prev = list->prev; 960 - list->prev->next = head; 961 - list->prev = head; 962 - } 963 - 964 888 /** 965 889 * drm_mode_sort - sort mode list 966 890 * @mode_list: list to sort ··· 893 975 */ 894 976 void drm_mode_sort(struct list_head *mode_list) 895 977 { 896 - list_sort(mode_list, drm_mode_compare); 978 + list_sort(NULL, mode_list, drm_mode_compare); 897 979 } 898 980 EXPORT_SYMBOL(drm_mode_sort); 899 981
+1 -95
fs/ubifs/gc.c
··· 54 54 */ 55 55 56 56 #include <linux/pagemap.h> 57 + #include <linux/list_sort.h> 57 58 #include "ubifs.h" 58 59 59 60 /* ··· 106 105 c->gc_lnum = -1; 107 106 err = ubifs_wbuf_seek_nolock(wbuf, gc_lnum, 0, UBI_LONGTERM); 108 107 return err; 109 - } 110 - 111 - /** 112 - * list_sort - sort a list. 113 - * @priv: private data, passed to @cmp 114 - * @head: the list to sort 115 - * @cmp: the elements comparison function 116 - * 117 - * This function has been implemented by Mark J Roberts <mjr@znex.org>. It 118 - * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted 119 - * in ascending order. 120 - * 121 - * The comparison function @cmp is supposed to return a negative value if @a is 122 - * than @b, and a positive value if @a is greater than @b. If @a and @b are 123 - * equivalent, then it does not matter what this function returns. 124 - */ 125 - static void list_sort(void *priv, struct list_head *head, 126 - int (*cmp)(void *priv, struct list_head *a, 127 - struct list_head *b)) 128 - { 129 - struct list_head *p, *q, *e, *list, *tail, *oldhead; 130 - int insize, nmerges, psize, qsize, i; 131 - 132 - if (list_empty(head)) 133 - return; 134 - 135 - list = head->next; 136 - list_del(head); 137 - insize = 1; 138 - for (;;) { 139 - p = oldhead = list; 140 - list = tail = NULL; 141 - nmerges = 0; 142 - 143 - while (p) { 144 - nmerges++; 145 - q = p; 146 - psize = 0; 147 - for (i = 0; i < insize; i++) { 148 - psize++; 149 - q = q->next == oldhead ? NULL : q->next; 150 - if (!q) 151 - break; 152 - } 153 - 154 - qsize = insize; 155 - while (psize > 0 || (qsize > 0 && q)) { 156 - if (!psize) { 157 - e = q; 158 - q = q->next; 159 - qsize--; 160 - if (q == oldhead) 161 - q = NULL; 162 - } else if (!qsize || !q) { 163 - e = p; 164 - p = p->next; 165 - psize--; 166 - if (p == oldhead) 167 - p = NULL; 168 - } else if (cmp(priv, p, q) <= 0) { 169 - e = p; 170 - p = p->next; 171 - psize--; 172 - if (p == oldhead) 173 - p = NULL; 174 - } else { 175 - e = q; 176 - q = q->next; 177 - qsize--; 178 - if (q == oldhead) 179 - q = NULL; 180 - } 181 - if (tail) 182 - tail->next = e; 183 - else 184 - list = e; 185 - e->prev = tail; 186 - tail = e; 187 - } 188 - p = q; 189 - } 190 - 191 - tail->next = list; 192 - list->prev = tail; 193 - 194 - if (nmerges <= 1) 195 - break; 196 - 197 - insize *= 2; 198 - } 199 - 200 - head->next = list; 201 - head->prev = list->prev; 202 - list->prev->next = head; 203 - list->prev = head; 204 108 } 205 109 206 110 /**
+11
include/linux/list_sort.h
··· 1 + #ifndef _LINUX_LIST_SORT_H 2 + #define _LINUX_LIST_SORT_H 3 + 4 + #include <linux/types.h> 5 + 6 + struct list_head; 7 + 8 + void list_sort(void *priv, struct list_head *head, 9 + int (*cmp)(void *priv, struct list_head *a, 10 + struct list_head *b)); 11 + #endif
+1 -1
lib/Makefile
··· 21 21 22 22 obj-y += bcd.o div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ 23 23 bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o \ 24 - string_helpers.o gcd.o 24 + string_helpers.o gcd.o list_sort.o 25 25 26 26 ifeq ($(CONFIG_DEBUG_KOBJECT),y) 27 27 CFLAGS_kobject.o += -DDEBUG
+102
lib/list_sort.c
··· 1 + #include <linux/kernel.h> 2 + #include <linux/module.h> 3 + #include <linux/list_sort.h> 4 + #include <linux/slab.h> 5 + #include <linux/list.h> 6 + 7 + /** 8 + * list_sort - sort a list. 9 + * @priv: private data, passed to @cmp 10 + * @head: the list to sort 11 + * @cmp: the elements comparison function 12 + * 13 + * This function has been implemented by Mark J Roberts <mjr@znex.org>. It 14 + * implements "merge sort" which has O(nlog(n)) complexity. The list is sorted 15 + * in ascending order. 16 + * 17 + * The comparison function @cmp is supposed to return a negative value if @a is 18 + * less than @b, and a positive value if @a is greater than @b. If @a and @b 19 + * are equivalent, then it does not matter what this function returns. 20 + */ 21 + void list_sort(void *priv, struct list_head *head, 22 + int (*cmp)(void *priv, struct list_head *a, 23 + struct list_head *b)) 24 + { 25 + struct list_head *p, *q, *e, *list, *tail, *oldhead; 26 + int insize, nmerges, psize, qsize, i; 27 + 28 + if (list_empty(head)) 29 + return; 30 + 31 + list = head->next; 32 + list_del(head); 33 + insize = 1; 34 + for (;;) { 35 + p = oldhead = list; 36 + list = tail = NULL; 37 + nmerges = 0; 38 + 39 + while (p) { 40 + nmerges++; 41 + q = p; 42 + psize = 0; 43 + for (i = 0; i < insize; i++) { 44 + psize++; 45 + q = q->next == oldhead ? NULL : q->next; 46 + if (!q) 47 + break; 48 + } 49 + 50 + qsize = insize; 51 + while (psize > 0 || (qsize > 0 && q)) { 52 + if (!psize) { 53 + e = q; 54 + q = q->next; 55 + qsize--; 56 + if (q == oldhead) 57 + q = NULL; 58 + } else if (!qsize || !q) { 59 + e = p; 60 + p = p->next; 61 + psize--; 62 + if (p == oldhead) 63 + p = NULL; 64 + } else if (cmp(priv, p, q) <= 0) { 65 + e = p; 66 + p = p->next; 67 + psize--; 68 + if (p == oldhead) 69 + p = NULL; 70 + } else { 71 + e = q; 72 + q = q->next; 73 + qsize--; 74 + if (q == oldhead) 75 + q = NULL; 76 + } 77 + if (tail) 78 + tail->next = e; 79 + else 80 + list = e; 81 + e->prev = tail; 82 + tail = e; 83 + } 84 + p = q; 85 + } 86 + 87 + tail->next = list; 88 + list->prev = tail; 89 + 90 + if (nmerges <= 1) 91 + break; 92 + 93 + insize *= 2; 94 + } 95 + 96 + head->next = list; 97 + head->prev = list->prev; 98 + list->prev->next = head; 99 + list->prev = head; 100 + } 101 + 102 + EXPORT_SYMBOL(list_sort);