Add qsort to libsa (taken from sys/dev/vinum/vinumqsort.c) and use instead of

bubblesort in acorn32 bootloader. Reduces time to sort memory on A710 equipped
RiscPC from over twenty seconds to effectively instantaneous.
Update boot version to 3.30
This commit is contained in:
abs 2004-05-19 23:37:41 +00:00
parent 7ce138ffc9
commit 3c2fbd8521
5 changed files with 189 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: boot32.c,v 1.17 2004/05/18 23:29:30 gavan Exp $ */
/* $NetBSD: boot32.c,v 1.18 2004/05/19 23:37:41 abs Exp $ */
/*-
* Copyright (c) 2002 Reinoud Zandijk
@ -133,7 +133,7 @@ void get_memory_configuration(void);
void get_memory_map(void);
void create_initial_page_tables(void);
void add_pagetables_at_top(void);
void sort_memory_map(void);
int page_info_cmp(const void *a, const void *);
void add_initvectors(void);
void create_configuration(int argc, char **argv, int start_args);
void prepare_and_check_relocation_system(void);
@ -516,7 +516,8 @@ void get_memory_map(void) {
osmemory_page_op(inout, mem_pages_info, totalpages);
printf(" ; sorting ");
sort_memory_map();
qsort(mem_pages_info, totalpages, sizeof(struct page_info),
&page_info_cmp);
printf(".\n");
/* get the first DRAM index and show the physical memory fragments we got */
@ -850,26 +851,12 @@ void *boot32_memset(void *dst, int c, size_t size) {
}
/* This sort routine needs to be re-implemented in either assembler or use other algorithm one day; its slow */
void sort_memory_map(void) {
int out, in, count;
struct page_info *out_page, *in_page, temp_page;
count = 0;
for (out = 0, out_page = mem_pages_info; out < totalpages; out++, out_page++) {
for (in = out+1, in_page = out_page+1; in < totalpages; in++, in_page++) {
if (in_page->physical < out_page->physical) {
memcpy(&temp_page, in_page, sizeof(struct page_info));
memcpy(in_page, out_page, sizeof(struct page_info));
memcpy(out_page, &temp_page, sizeof(struct page_info));
};
count++;
if ((count & 0x3ffff) == 0) twirl();
};
};
/* We can rely on the fact that two entries never have identical ->physical */
int page_info_cmp(const void *a, const void *b) {
return (((struct page_info *)a)->physical <
((struct page_info *)b)->physical) ? -1 : 1;
}
struct page_info *get_relocated_page(u_long destination, int size) {
struct page_info *page;

View File

@ -1,4 +1,4 @@
$NetBSD: version,v 1.7 2003/06/03 12:53:47 reinoud Exp $
$NetBSD: version,v 1.8 2004/05/19 23:37:41 abs Exp $
0.90: Experimental C version
0.91: General cleanup
@ -23,3 +23,4 @@ $NetBSD: version,v 1.7 2003/06/03 12:53:47 reinoud Exp $
3.06: fixed non 1Mb-alignment problems for the top 1Mb in the memorymap
3.10: Serious loading problems fixed and cleanup code
3.20: Redone videomem mapping and top memory search; esp. for smaller machines
3.30: Use qsort to significantly speed memory sort

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.54 2003/04/11 11:31:44 dsl Exp $
# $NetBSD: Makefile,v 1.55 2004/05/19 23:37:41 abs Exp $
LIB= sa
NOPIC= # defined
@ -19,7 +19,7 @@ CPPFLAGS= -I${SADIR} ${SACPPFLAGS} ${SAMISCCPPFLAGS} \
# stand routines
SRCS+= alloc.c bcmp.c bcopy.c bzero.c errno.c exit.c exec.c files.c \
getfile.c gets.c globals.c memcmp.c memcpy.c memmove.c memset.c \
panic.c printf.c snprintf.c sprintf.c strerror.c subr_prf.c \
panic.c printf.c qsort.c snprintf.c sprintf.c strerror.c subr_prf.c \
twiddle.c vsprintf.c checkpasswd.c
# io routines

173
sys/lib/libsa/qsort.c Normal file
View File

@ -0,0 +1,173 @@
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD: src/sys/libkern/qsort.c,v 1.12 2002/11/09 12:55:06 alfred Exp $
* $NetBSD: qsort.c,v 1.1 2004/05/19 23:37:41 abs Exp $
*/
#include <sys/cdefs.h>
#include <sys/types.h>
typedef int cmp_t(const void *, const void *);
static __inline char *med3(char *, char *, char *, cmp_t *);
static __inline void swapfunc(char *, char *, int, int);
#define min(a, b) (a) < (b) ? (a) : (b)
void qsort(void *a, size_t n, size_t es, cmp_t *cmp);
/*
* Qsort routine from Bentley & McIlroy's "Engineering a Sort Function".
*/
#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); \
}
#define SWAPINIT(a, es) swaptype = ((char *)a - (char *)0) % sizeof(long) || \
es % sizeof(long) ? 2 : es == sizeof(long)? 0 : 1;
static __inline void
swapfunc(a, b, n, swaptype)
char *a, *b;
int n, 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)
static __inline char *
med3(a, b, c, cmp)
char *a, *b, *c;
cmp_t *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
qsort(void *a, size_t n, size_t es, cmp_t *cmp)
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
int d, r, swaptype, swap_cnt;
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pm = (char *)a + (n / 2) * es;
if (n > 7) {
pl = a;
pn = (char *)a + (n - 1) * es;
if (n > 40) {
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);
}
swap(a, pm);
pa = pb = (char *)a + es;
pc = pd = (char *)a + (n - 1) * es;
for (;;) {
while (pb <= pc && (r = cmp(pb, a)) <= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
pb += es;
}
while (pb <= pc && (r = cmp(pc, a)) >= 0) {
if (r == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
pc -= es;
}
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *)a + es; pm < (char *)a + n * es; pm += es)
for (pl = pm; pl > (char *)a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *)a + n * es;
r = min(pa - (char *)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)
qsort(a, r / es, es, cmp);
if ((r = pd - pc) > es) {
/* Iterate rather than recurse to save stack space */
a = pn - r;
n = r / es;
goto loop;
}
/* qsort(pn - r, r / es, es, cmp);*/
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: stand.h,v 1.51 2003/10/30 22:15:28 he Exp $ */
/* $NetBSD: stand.h,v 1.52 2004/05/19 23:37:41 abs Exp $ */
/*
* Copyright (c) 1999 Christopher G. Demetriou. All rights reserved.
@ -250,6 +250,9 @@ int ioctl(int, u_long, char *);
int stat(const char *, struct stat *);
int fstat(int, struct stat *);
typedef int cmp_t __P((const void *, const void *));
void qsort(void *, size_t, size_t, cmp_t * cmp);
extern int opterr, optind, optopt, optreset;
extern char *optarg;
int getopt(int, char * const *, const char *);