diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/stdlib/qsort.c | 35 |
1 files changed, 25 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c index f16f9d0ebf..c97979ef01 100644 --- a/src/lib/libc/stdlib/qsort.c +++ b/src/lib/libc/stdlib/qsort.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: qsort.c,v 1.14 2017/01/04 15:20:30 millert Exp $ */ | 1 | /* $OpenBSD: qsort.c,v 1.15 2017/05/17 16:58:20 millert Exp $ */ |
2 | /*- | 2 | /*- |
3 | * Copyright (c) 1992, 1993 | 3 | * Copyright (c) 1992, 1993 |
4 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -85,7 +85,7 @@ qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *)) | |||
85 | { | 85 | { |
86 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; | 86 | char *pa, *pb, *pc, *pd, *pl, *pm, *pn; |
87 | int cmp_result, swaptype; | 87 | int cmp_result, swaptype; |
88 | size_t d, r; | 88 | size_t d, r, s; |
89 | char *a = aa; | 89 | char *a = aa; |
90 | 90 | ||
91 | loop: SWAPINIT(a, es); | 91 | loop: SWAPINIT(a, es); |
@@ -139,14 +139,29 @@ loop: SWAPINIT(a, es); | |||
139 | vecswap(a, pb - r, r); | 139 | vecswap(a, pb - r, r); |
140 | r = min(pd - pc, pn - pd - es); | 140 | r = min(pd - pc, pn - pd - es); |
141 | vecswap(pb, pn - r, r); | 141 | vecswap(pb, pn - r, r); |
142 | if ((r = pb - pa) > es) | 142 | /* |
143 | qsort(a, r / es, es, cmp); | 143 | * To save stack space we sort the smaller side of the partition first |
144 | if ((r = pd - pc) > es) { | 144 | * using recursion and eliminate tail recursion for the larger side. |
145 | /* Iterate rather than recurse to save stack space */ | 145 | */ |
146 | a = pn - r; | 146 | r = pb - pa; |
147 | n = r / es; | 147 | s = pd - pc; |
148 | goto loop; | 148 | if (r < s) { |
149 | /* Recurse for 1st side, iterate for 2nd side. */ | ||
150 | if (s > es) { | ||
151 | if (r > es) | ||
152 | qsort(a, r / es, es, cmp); | ||
153 | a = pn - s; | ||
154 | n = s / es; | ||
155 | goto loop; | ||
156 | } | ||
157 | } else { | ||
158 | /* Recurse for 2nd side, iterate for 1st side. */ | ||
159 | if (r > es) { | ||
160 | if (s > es) | ||
161 | qsort(pn - s, s / es, es, cmp); | ||
162 | n = r / es; | ||
163 | goto loop; | ||
164 | } | ||
149 | } | 165 | } |
150 | /* qsort(pn - r, r / es, es, cmp);*/ | ||
151 | } | 166 | } |
152 | DEF_STRONG(qsort); | 167 | DEF_STRONG(qsort); |