Re: qsort fix

From: Date: Fri, 28 May 1999 13:22:51 +0000
Subject: Re: qsort fix
References: 1  Groups: php.dev 
Request: Send a blank email to php-dev+get-6148@lists.php.net to get a copy of this message
Zeev Suraski wrote: > You've sent this to php3-dev@, which isn't php-dev@. Oops, sorry. > > About the fix, what does it come to fix exactly? A broken libc qsort() > implementation? > Yes, on Solaris 7 qsort causes the program to segfault about 75% of the time when using a comparison function that randomly returns -1 or 1. I played around with several arrays, and it doesn't seem to be related to array size or content. I don't have any boxes running older versions of solaris, so I don't know if they are affected. > > Zeev > > On Thu, 27 May 1999, Chad Cunningham wrote: > > > Below is the function I used for qsort to get it working on solaris. > > Note that I took the cheap way out and just threw it in php3_hash.c. I > > tested it on Solaris7 and RedHat6, works very well (i.e. no core dumps > > :). I also did some tests with a c program and found it to be faster > > than the standard c qsort function. > > > > > > [ccunning@NEW93109230 src]$ diff php-3.0.8-devel/php3_hash.c > > php-3.0.8/php3_hash.c > > 37a38 > > > > > 93,176d93 > > < #include <stdlib.h> > > < > > < #define SWAPINIT(a, es) swaptype = \ > > < (a - (char*) 0) % sizeof(long) || es % sizeof(long) ? 2 : \ > > < es == sizeof(long) ? 0 : 1; > > < #define swapcode(TYPE, parmi, parmj, n) { \ > > < long i = (n) / sizeof(TYPE); \ > > < register TYPE *pi = (TYPE *) (parmi); \ > > < register TYPE *pj = (TYPE *) (parmj); \ > > < do { \ > > < register TYPE t = *pi; \ > > < *pi++ = *pj; \ > > < *pj++ = t; \ > > < } while (--i > 0); \ > > < } > > < void swapfunc(char *a, char *b, int n, int swaptype) > > < { if (swaptype <= 1) swapcode(long, a, b, n) > > < else swapcode(char, a, b, n) > > < } > > < #define swap(a, b) \ > > < if (swaptype == 0) { \ > > < long t = * (long *) (a); \ > > < * (long *) (a) = * (long *) (b); \ > > < * (long *) (b) = t; \ > > < } else \ > > < swapfunc(a, b, es, swaptype) > > < #define vecswap(a, b, n) if (n > 0) swapfunc(a, b, n, swaptype) > > < > > < #define min(x, y) ((x)<=(y) ? (x) : (y)) > > < > > < char *med3(char *a, char *b, char *c, int (*cmp)()) > > < { return cmp(a, b) < 0 ? > > < (cmp(b, c) < 0 ? b : (cmp(a, c) < 0 ? c : a ) ) > > < : (cmp(b, c) > 0 ? b : (cmp(a, c) < 0 ? a : c ) > > ); > > < } > > < > > < void php_qsort(char *a, unsigned n, int es, int (*cmp)()) > > < { > > < char *pa, *pb, *pc, *pd, *pl, *pm, *pn; > > < int d, r, swaptype; > > < > > < SWAPINIT(a, es); > > < if (n < 7) { /* Insertion sort on small arrays */ > > < for (pm = a + es; pm < a + n*es; pm += es) > > < for (pl = pm; pl > a && cmp(pl-es, pl) > 0; pl > > -= es) > > < swap(pl, pl-es); > > < return; > > < } > > < pm = a + (n/2) * es; > > < if (n > 7) { > > < pl = a; > > < pn = a + (n-1) * es; > > < if (n > 40) { /* On big arrays, pseudomedian of 9 */ > > < d = (n/8) * es; > > < pl = med3(pl, pl+d, pl+2*d, cmp); > > < pm = med3(pm-d, pm, pm+d, cmp); > > < pn = med3(pn-2*d, pn-d, pn, cmp); > > < } > > < pm = med3(pl, pm, pn, cmp); /* On mid arrays, med of 3 > > */ > > < } > > < swap(a, pm); /* On tiny arrays, partition around middle */ > > < pa = pb = a + es; > > < pc = pd = a + (n-1)*es; > > < for (;;) { > > < while (pb <= pc && (r = cmp(pb, a)) <= 0) { > > < if (r == 0) { swap(pa, pb); pa += es; } > > < pb += es; > > < } > > < while (pb <= pc && (r = cmp(pc, a)) >= 0) { > > < if (r == 0) { swap(pc, pd); pd -= es; } > > < pc -= es; > > < } > > < if (pb > pc) break; > > < swap(pb, pc); > > < pb += es; > > < pc -= es; > > < } > > < pn = a + n*es; > > < r = min(pa-a, pb-pa); vecswap(a, pb-r, r); > > < r = min(pd-pc, pn-pd-es); vecswap(pb, pn-r, r); > > < if ((r = pb-pa) > es) php_qsort(a, r/es, es, cmp); > > < if ((r = pd-pc) > es) php_qsort(pn-r, r/es, es, cmp); > > < } > > < > > 1084c1001 > > < php_qsort((void *) arTmp, i, sizeof(Bucket *), compar); > > --- > > > qsort((void *) arTmp, i, sizeof(Bucket *), compar); > > > > > > > > -- > > > > Chad Cunningham > > ccunning@math.ohio-state.edu > > > > > > -- > ----------------------------------------------------- > Zeev Suraski <zeev@zend.com> > For a PGP public key, finger bourbon@netvision.net.il -- Chad Cunningham ccunning@math.ohio-state.edu -- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net For help: php-dev-help@lists.php.net

« previous php.dev (#6148) next »