]> git.saurik.com Git - apple/libc.git/blame_incremental - stdlib/FreeBSD/qsort.c.patch
Libc-763.11.tar.gz
[apple/libc.git] / stdlib / FreeBSD / qsort.c.patch
... / ...
CommitLineData
1--- qsort.c.orig 2008-09-24 19:55:30.000000000 -0700
2+++ qsort.c 2008-09-25 12:28:18.000000000 -0700
3@@ -34,14 +34,19 @@ static char sccsid[] = "@(#)qsort.c 8.1
4 __FBSDID("$FreeBSD: src/lib/libc/stdlib/qsort.c,v 1.15 2008/01/14 09:21:34 das Exp $");
5
6 #include <stdlib.h>
7+#include <string.h>
8
9 #ifdef I_AM_QSORT_R
10 typedef int cmp_t(void *, const void *, const void *);
11 #else
12 typedef int cmp_t(const void *, const void *);
13 #endif
14-static inline char *med3(char *, char *, char *, cmp_t *, void *);
15-static inline void swapfunc(char *, char *, int, int);
16+#ifdef I_AM_QSORT_B
17+static inline char *med3(char *, char *, char *, cmp_t ^, void *) __attribute__((always_inline));
18+#else
19+static inline char *med3(char *, char *, char *, cmp_t *, void *) __attribute__((always_inline));
20+#endif
21+static inline void swapfunc(char *, char *, int, int) __attribute__((always_inline));
22
23 #define min(a, b) (a) < (b) ? a : b
24
25@@ -90,7 +95,13 @@ swapfunc(a, b, n, swaptype)
26 #endif
27
28 static inline char *
29-med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk
30+med3(char *a, char *b, char *c,
31+#ifdef I_AM_QSORT_B
32+cmp_t ^cmp,
33+#else
34+cmp_t *cmp,
35+#endif
36+void *thunk
37 #ifndef I_AM_QSORT_R
38 __unused
39 #endif
40@@ -101,21 +112,47 @@ __unused
41 :(CMP(thunk, b, c) > 0 ? b : (CMP(thunk, a, c) < 0 ? a : c ));
42 }
43
44+#ifdef __LP64__
45+#define DEPTH(x) (2 * (flsl((long)(x)) - 1))
46+#else /* !__LP64__ */
47+#define DEPTH(x) (2 * (fls((int)(x)) - 1))
48+#endif /* __LP64__ */
49+
50 #ifdef I_AM_QSORT_R
51-void
52-qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
53+int __heapsort_r(void *, size_t, size_t, void *, int (*)(void *, const void *, const void *));
54+#endif
55+
56+static void
57+_qsort(void *a, size_t n, size_t es,
58+#ifdef I_AM_QSORT_R
59+void *thunk,
60 #else
61-#define thunk NULL
62-void
63-qsort(void *a, size_t n, size_t es, cmp_t *cmp)
64+#define thunk NULL
65+#endif
66+#ifdef I_AM_QSORT_B
67+cmp_t ^cmp,
68+#else
69+cmp_t *cmp,
70 #endif
71+int depth_limit)
72 {
73 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
74 size_t d, r;
75 int cmp_result;
76 int swaptype, swap_cnt;
77
78-loop: SWAPINIT(a, es);
79+loop:
80+ if (depth_limit-- <= 0) {
81+#ifdef I_AM_QSORT_B
82+ heapsort_b(a, n, es, cmp);
83+#elif defined(I_AM_QSORT_R)
84+ __heapsort_r(a, n, es, thunk, cmp);
85+#else
86+ heapsort(a, n, es, cmp);
87+#endif
88+ return;
89+ }
90+ SWAPINIT(a, es);
91 swap_cnt = 0;
92 if (n < 7) {
93 for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
94@@ -165,25 +202,31 @@ loop: SWAPINIT(a, es);
95 pb += es;
96 pc -= es;
97 }
98+
99+ pn = (char *)a + n * es;
100+ r = min(pa - (char *)a, pb - pa);
101+ vecswap(a, pb - r, r);
102+ r = min(pd - pc, pn - pd - es);
103+ vecswap(pb, pn - r, r);
104+
105 if (swap_cnt == 0) { /* Switch to insertion sort */
106+ r = 1 + n / 4; /* n >= 7, so r >= 2 */
107 for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
108 for (pl = pm;
109 pl > (char *)a && CMP(thunk, pl - es, pl) > 0;
110- pl -= es)
111+ pl -= es) {
112 swap(pl, pl - es);
113+ if (++swap_cnt > r) goto nevermind;
114+ }
115 return;
116 }
117
118- pn = (char *)a + n * es;
119- r = min(pa - (char *)a, pb - pa);
120- vecswap(a, pb - r, r);
121- r = min(pd - pc, pn - pd - es);
122- vecswap(pb, pn - r, r);
123+nevermind:
124 if ((r = pb - pa) > es)
125 #ifdef I_AM_QSORT_R
126- qsort_r(a, r / es, es, thunk, cmp);
127+ _qsort(a, r / es, es, thunk, cmp, depth_limit);
128 #else
129- qsort(a, r / es, es, cmp);
130+ _qsort(a, r / es, es, cmp, depth_limit);
131 #endif
132 if ((r = pd - pc) > es) {
133 /* Iterate rather than recurse to save stack space */
134@@ -193,3 +236,19 @@ loop: SWAPINIT(a, es);
135 }
136 /* qsort(pn - r, r / es, es, cmp);*/
137 }
138+
139+void
140+#ifdef I_AM_QSORT_R
141+qsort_r(void *a, size_t n, size_t es, void *thunk, cmp_t *cmp)
142+#elif defined(I_AM_QSORT_B)
143+qsort_b(void *a, size_t n, size_t es, cmp_t ^cmp)
144+#else
145+qsort(void *a, size_t n, size_t es, cmp_t *cmp)
146+#endif
147+{
148+ _qsort(a, n, es,
149+#ifdef I_AM_QSORT_R
150+ thunk,
151+#endif
152+ cmp, DEPTH(n));
153+}