Our qsort() is inappropriate for kernel use because it makes recursive
calls. Replace it with a kheapsort() function in kernel. Pointed out by tron@.
This commit is contained in:
parent
974cf03d8d
commit
c6555ead19
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: heapsort.c,v 1.16 2008/03/11 18:04:59 rmind Exp $ */
|
||||
/* $NetBSD: heapsort.c,v 1.1 2008/11/16 16:15:58 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1991, 1993
|
||||
|
@ -46,10 +46,15 @@
|
|||
#if 0
|
||||
static char sccsid[] = "from: @(#)heapsort.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: heapsort.c,v 1.16 2008/03/11 18:04:59 rmind Exp $");
|
||||
__RCSID("$NetBSD: heapsort.c,v 1.1 2008/11/16 16:15:58 ad Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <lib/libkern/libkern.h>
|
||||
#else /* _KERNEL */
|
||||
#include "namespace.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
|
@ -65,6 +70,7 @@ __RCSID("$NetBSD: heapsort.c,v 1.16 2008/03/11 18:04:59 rmind Exp $");
|
|||
#ifdef __weak_alias
|
||||
__weak_alias(heapsort,_heapsort)
|
||||
#endif
|
||||
#endif /* _KERNEL */
|
||||
|
||||
/*
|
||||
* Swap two areas of size number of bytes. Although qsort(3) permits random
|
||||
|
@ -161,13 +167,22 @@ __weak_alias(heapsort,_heapsort)
|
|||
* a data set that will trigger the worst case is nonexistent. Heapsort's
|
||||
* only advantage over quicksort is that it requires little additional memory.
|
||||
*/
|
||||
#ifdef _KERNEL
|
||||
int
|
||||
kheapsort(void *vbase, size_t nmemb, size_t size,
|
||||
int (*compar)(const void *, const void *), void *k)
|
||||
#else
|
||||
int
|
||||
heapsort(void *vbase, size_t nmemb, size_t size,
|
||||
int (*compar) __P((const void *, const void *)))
|
||||
int (*compar)(const void *, const void *))
|
||||
#endif
|
||||
{
|
||||
size_t cnt, i, j, l;
|
||||
char tmp, *tmp1, *tmp2;
|
||||
char *base, *k, *p, *t;
|
||||
char *base, *p, *t;
|
||||
#ifndef _KERNEL
|
||||
char *k;
|
||||
#endif
|
||||
|
||||
_DIAGASSERT(vbase != NULL);
|
||||
_DIAGASSERT(compar != NULL);
|
||||
|
@ -176,12 +191,16 @@ heapsort(void *vbase, size_t nmemb, size_t size,
|
|||
return (0);
|
||||
|
||||
if (!size) {
|
||||
#ifndef _KERNEL
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
return (-1);
|
||||
}
|
||||
|
||||
#ifndef _KERNEL
|
||||
if ((k = malloc(size)) == NULL)
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Items are numbered from 1 to nmemb, so offset from size bytes
|
||||
|
@ -203,6 +222,8 @@ heapsort(void *vbase, size_t nmemb, size_t size,
|
|||
--nmemb;
|
||||
SELECT(i, j, nmemb, t, p, size, k, cnt, tmp1, tmp2);
|
||||
}
|
||||
#ifndef _KERNEL
|
||||
free(k);
|
||||
#endif
|
||||
return (0);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: qsort.c,v 1.1 2008/11/16 15:01:26 ad Exp $ */
|
||||
/* $NetBSD: qsort.c,v 1.17 2008/11/16 16:15:58 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -34,21 +34,15 @@
|
|||
#if 0
|
||||
static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93";
|
||||
#else
|
||||
__RCSID("$NetBSD: qsort.c,v 1.1 2008/11/16 15:01:26 ad Exp $");
|
||||
__RCSID("$NetBSD: qsort.c,v 1.17 2008/11/16 16:15:58 ad Exp $");
|
||||
#endif
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef _LIBC
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <lib/libkern/libkern.h>
|
||||
#endif
|
||||
|
||||
static inline char *med3 __P((char *, char *, char *,
|
||||
int (*)(const void *, const void *)));
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: kern_ksyms.c,v 1.45 2008/11/16 15:29:53 ad Exp $ */
|
||||
/* $NetBSD: kern_ksyms.c,v 1.46 2008/11/16 16:15:58 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2008 The NetBSD Foundation, Inc.
|
||||
|
@ -71,7 +71,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.45 2008/11/16 15:29:53 ad Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: kern_ksyms.c,v 1.46 2008/11/16 16:15:58 ad Exp $");
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include "opt_ddb.h"
|
||||
|
@ -250,7 +250,7 @@ addsymtab(const char *name, void *symstart, size_t symsize,
|
|||
void *strstart, size_t strsize, struct ksyms_symtab *tab,
|
||||
void *newstart)
|
||||
{
|
||||
Elf_Sym *sym, *nsym;
|
||||
Elf_Sym *sym, *nsym, ts;
|
||||
int i, j, n, nglob;
|
||||
char *str;
|
||||
|
||||
|
@ -316,7 +316,8 @@ addsymtab(const char *name, void *symstart, size_t symsize,
|
|||
tab->sd_symsize = n * sizeof(Elf_Sym);
|
||||
tab->sd_nglob = nglob;
|
||||
addsymtab_strstart = str;
|
||||
qsort(nsym, n, sizeof(Elf_Sym), addsymtab_compar);
|
||||
if (kheapsort(nsym, n, sizeof(Elf_Sym), addsymtab_compar, &ts) != 0)
|
||||
panic("addsymtab");
|
||||
|
||||
/* ksymsread() is unlocked, so membar. */
|
||||
membar_producer();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.90 2008/11/16 15:01:26 ad Exp $
|
||||
# $NetBSD: Makefile,v 1.91 2008/11/16 16:15:58 ad Exp $
|
||||
|
||||
LIB= kern
|
||||
NOPIC= # defined
|
||||
|
@ -55,7 +55,7 @@ SRCS+= strtoll.c strtoull.c strtoumax.c
|
|||
|
||||
SRCS+= xlat_mbr_fstype.c
|
||||
|
||||
SRCS+= rb.c qsort.c
|
||||
SRCS+= rb.c heapsort.c
|
||||
|
||||
# Files to clean up
|
||||
CLEANFILES+= lib${LIB}.o lib${LIB}.po
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: libkern.h,v 1.83 2008/11/16 15:01:26 ad Exp $ */
|
||||
/* $NetBSD: libkern.h,v 1.84 2008/11/16 16:15:58 ad Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -340,5 +340,6 @@ u_long strtoul __P((const char *, char **, int));
|
|||
long long strtoll __P((const char *, char **, int));
|
||||
unsigned long long strtoull __P((const char *, char **, int));
|
||||
uintmax_t strtoumax __P((const char *, char **, int));
|
||||
void qsort(void *, size_t, size_t, int (*)(const void *, const void *));
|
||||
int kheapsort(void *, size_t, size_t, int (*)(const void *, const void *),
|
||||
void *);
|
||||
#endif /* !_LIB_LIBKERN_LIBKERN_H_ */
|
||||
|
|
Loading…
Reference in New Issue