1*0e8cc8bdSWilliam Juul /* 2*0e8cc8bdSWilliam Juul * Copyright (c) 1992, 1993 3*0e8cc8bdSWilliam Juul * The Regents of the University of California. All rights reserved. 4*0e8cc8bdSWilliam Juul * 5*0e8cc8bdSWilliam Juul * Redistribution and use in source and binary forms, with or without 6*0e8cc8bdSWilliam Juul * modification, are permitted provided that the following conditions 7*0e8cc8bdSWilliam Juul * are met: 8*0e8cc8bdSWilliam Juul * 1. Redistributions of source code must retain the above copyright 9*0e8cc8bdSWilliam Juul * notice, this list of conditions and the following disclaimer. 10*0e8cc8bdSWilliam Juul * 2. Redistributions in binary form must reproduce the above copyright 11*0e8cc8bdSWilliam Juul * notice, this list of conditions and the following disclaimer in the 12*0e8cc8bdSWilliam Juul * documentation and/or other materials provided with the distribution. 13*0e8cc8bdSWilliam Juul * 3. Neither the name of the University nor the names of its contributors 14*0e8cc8bdSWilliam Juul * may be used to endorse or promote products derived from this software 15*0e8cc8bdSWilliam Juul * without specific prior written permission. 16*0e8cc8bdSWilliam Juul * 17*0e8cc8bdSWilliam Juul * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18*0e8cc8bdSWilliam Juul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19*0e8cc8bdSWilliam Juul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20*0e8cc8bdSWilliam Juul * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21*0e8cc8bdSWilliam Juul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22*0e8cc8bdSWilliam Juul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23*0e8cc8bdSWilliam Juul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24*0e8cc8bdSWilliam Juul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25*0e8cc8bdSWilliam Juul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26*0e8cc8bdSWilliam Juul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27*0e8cc8bdSWilliam Juul * SUCH DAMAGE. 28*0e8cc8bdSWilliam Juul */ 29*0e8cc8bdSWilliam Juul 30*0e8cc8bdSWilliam Juul #include "yportenv.h" 31*0e8cc8bdSWilliam Juul //#include <linux/string.h> 32*0e8cc8bdSWilliam Juul 33*0e8cc8bdSWilliam Juul /* 34*0e8cc8bdSWilliam Juul * Qsort routine from Bentley & McIlroy's "Engineering a Sort Function". 35*0e8cc8bdSWilliam Juul */ 36*0e8cc8bdSWilliam Juul #define swapcode(TYPE, parmi, parmj, n) { \ 37*0e8cc8bdSWilliam Juul long i = (n) / sizeof (TYPE); \ 38*0e8cc8bdSWilliam Juul register TYPE *pi = (TYPE *) (parmi); \ 39*0e8cc8bdSWilliam Juul register TYPE *pj = (TYPE *) (parmj); \ 40*0e8cc8bdSWilliam Juul do { \ 41*0e8cc8bdSWilliam Juul register TYPE t = *pi; \ 42*0e8cc8bdSWilliam Juul *pi++ = *pj; \ 43*0e8cc8bdSWilliam Juul *pj++ = t; \ 44*0e8cc8bdSWilliam Juul } while (--i > 0); \ 45*0e8cc8bdSWilliam Juul } 46*0e8cc8bdSWilliam Juul 47*0e8cc8bdSWilliam Juul #define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \ 48*0e8cc8bdSWilliam Juul es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1; 49*0e8cc8bdSWilliam Juul 50*0e8cc8bdSWilliam Juul static __inline void 51*0e8cc8bdSWilliam Juul swapfunc(char *a, char *b, int n, int swaptype) 52*0e8cc8bdSWilliam Juul { 53*0e8cc8bdSWilliam Juul if (swaptype <= 1) 54*0e8cc8bdSWilliam Juul swapcode(long, a, b, n) 55*0e8cc8bdSWilliam Juul else 56*0e8cc8bdSWilliam Juul swapcode(char, a, b, n) 57*0e8cc8bdSWilliam Juul } 58*0e8cc8bdSWilliam Juul 59*0e8cc8bdSWilliam Juul #define swap(a, b) \ 60*0e8cc8bdSWilliam Juul if (swaptype == 0) { \ 61*0e8cc8bdSWilliam Juul long t = *(long *)(a); \ 62*0e8cc8bdSWilliam Juul *(long *)(a) = *(long *)(b); \ 63*0e8cc8bdSWilliam Juul *(long *)(b) = t; \ 64*0e8cc8bdSWilliam Juul } else \ 65*0e8cc8bdSWilliam Juul swapfunc(a, b, es, swaptype) 66*0e8cc8bdSWilliam Juul 67*0e8cc8bdSWilliam Juul #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) 68*0e8cc8bdSWilliam Juul 69*0e8cc8bdSWilliam Juul static __inline char * 70*0e8cc8bdSWilliam Juul med3(char *a, char *b, char *c, int (*cmp)(const void *, const void *)) 71*0e8cc8bdSWilliam Juul { 72*0e8cc8bdSWilliam Juul return cmp(a, b) < 0 ? 73*0e8cc8bdSWilliam Juul (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a )) 74*0e8cc8bdSWilliam Juul :(cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c )); 75*0e8cc8bdSWilliam Juul } 76*0e8cc8bdSWilliam Juul 77*0e8cc8bdSWilliam Juul #ifndef min 78*0e8cc8bdSWilliam Juul #define min(a,b) (((a) < (b)) ? (a) : (b)) 79*0e8cc8bdSWilliam Juul #endif 80*0e8cc8bdSWilliam Juul 81*0e8cc8bdSWilliam Juul void 82*0e8cc8bdSWilliam Juul yaffs_qsort(void *aa, size_t n, size_t es, 83*0e8cc8bdSWilliam Juul int (*cmp)(const void *, const void *)) 84*0e8cc8bdSWilliam Juul { 85*0e8cc8bdSWilliam Juul char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 86*0e8cc8bdSWilliam Juul int d, r, swaptype, swap_cnt; 87*0e8cc8bdSWilliam Juul register char *a = aa; 88*0e8cc8bdSWilliam Juul 89*0e8cc8bdSWilliam Juul loop: SWAPINIT(a, es); 90*0e8cc8bdSWilliam Juul swap_cnt = 0; 91*0e8cc8bdSWilliam Juul if (n < 7) { 92*0e8cc8bdSWilliam Juul for (pm = (char *)a + es; pm < (char *) a + n * es; pm += es) 93*0e8cc8bdSWilliam Juul for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 94*0e8cc8bdSWilliam Juul pl -= es) 95*0e8cc8bdSWilliam Juul swap(pl, pl - es); 96*0e8cc8bdSWilliam Juul return; 97*0e8cc8bdSWilliam Juul } 98*0e8cc8bdSWilliam Juul pm = (char *)a + (n / 2) * es; 99*0e8cc8bdSWilliam Juul if (n > 7) { 100*0e8cc8bdSWilliam Juul pl = (char *)a; 101*0e8cc8bdSWilliam Juul pn = (char *)a + (n - 1) * es; 102*0e8cc8bdSWilliam Juul if (n > 40) { 103*0e8cc8bdSWilliam Juul d = (n / 8) * es; 104*0e8cc8bdSWilliam Juul pl = med3(pl, pl + d, pl + 2 * d, cmp); 105*0e8cc8bdSWilliam Juul pm = med3(pm - d, pm, pm + d, cmp); 106*0e8cc8bdSWilliam Juul pn = med3(pn - 2 * d, pn - d, pn, cmp); 107*0e8cc8bdSWilliam Juul } 108*0e8cc8bdSWilliam Juul pm = med3(pl, pm, pn, cmp); 109*0e8cc8bdSWilliam Juul } 110*0e8cc8bdSWilliam Juul swap(a, pm); 111*0e8cc8bdSWilliam Juul pa = pb = (char *)a + es; 112*0e8cc8bdSWilliam Juul 113*0e8cc8bdSWilliam Juul pc = pd = (char *)a + (n - 1) * es; 114*0e8cc8bdSWilliam Juul for (;;) { 115*0e8cc8bdSWilliam Juul while (pb <= pc && (r = cmp(pb, a)) <= 0) { 116*0e8cc8bdSWilliam Juul if (r == 0) { 117*0e8cc8bdSWilliam Juul swap_cnt = 1; 118*0e8cc8bdSWilliam Juul swap(pa, pb); 119*0e8cc8bdSWilliam Juul pa += es; 120*0e8cc8bdSWilliam Juul } 121*0e8cc8bdSWilliam Juul pb += es; 122*0e8cc8bdSWilliam Juul } 123*0e8cc8bdSWilliam Juul while (pb <= pc && (r = cmp(pc, a)) >= 0) { 124*0e8cc8bdSWilliam Juul if (r == 0) { 125*0e8cc8bdSWilliam Juul swap_cnt = 1; 126*0e8cc8bdSWilliam Juul swap(pc, pd); 127*0e8cc8bdSWilliam Juul pd -= es; 128*0e8cc8bdSWilliam Juul } 129*0e8cc8bdSWilliam Juul pc -= es; 130*0e8cc8bdSWilliam Juul } 131*0e8cc8bdSWilliam Juul if (pb > pc) 132*0e8cc8bdSWilliam Juul break; 133*0e8cc8bdSWilliam Juul swap(pb, pc); 134*0e8cc8bdSWilliam Juul swap_cnt = 1; 135*0e8cc8bdSWilliam Juul pb += es; 136*0e8cc8bdSWilliam Juul pc -= es; 137*0e8cc8bdSWilliam Juul } 138*0e8cc8bdSWilliam Juul if (swap_cnt == 0) { /* Switch to insertion sort */ 139*0e8cc8bdSWilliam Juul for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es) 140*0e8cc8bdSWilliam Juul for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0; 141*0e8cc8bdSWilliam Juul pl -= es) 142*0e8cc8bdSWilliam Juul swap(pl, pl - es); 143*0e8cc8bdSWilliam Juul return; 144*0e8cc8bdSWilliam Juul } 145*0e8cc8bdSWilliam Juul 146*0e8cc8bdSWilliam Juul pn = (char *)a + n * es; 147*0e8cc8bdSWilliam Juul r = min(pa - (char *)a, pb - pa); 148*0e8cc8bdSWilliam Juul vecswap(a, pb - r, r); 149*0e8cc8bdSWilliam Juul r = min((long)(pd - pc), (long)(pn - pd - es)); 150*0e8cc8bdSWilliam Juul vecswap(pb, pn - r, r); 151*0e8cc8bdSWilliam Juul if ((r = pb - pa) > es) 152*0e8cc8bdSWilliam Juul yaffs_qsort(a, r / es, es, cmp); 153*0e8cc8bdSWilliam Juul if ((r = pd - pc) > es) { 154*0e8cc8bdSWilliam Juul /* Iterate rather than recurse to save stack space */ 155*0e8cc8bdSWilliam Juul a = pn - r; 156*0e8cc8bdSWilliam Juul n = r / es; 157*0e8cc8bdSWilliam Juul goto loop; 158*0e8cc8bdSWilliam Juul } 159*0e8cc8bdSWilliam Juul /* yaffs_qsort(pn - r, r / es, es, cmp);*/ 160*0e8cc8bdSWilliam Juul } 161