summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/lib/libsa/Makefile7
-rw-r--r--sys/lib/libsa/Makefile.inc14
-rw-r--r--sys/lib/libsa/alloc.c156
-rw-r--r--sys/lib/libsa/printf.c4
4 files changed, 150 insertions, 31 deletions
diff --git a/sys/lib/libsa/Makefile b/sys/lib/libsa/Makefile
index 0c419f43c33..26e1a0fff13 100644
--- a/sys/lib/libsa/Makefile
+++ b/sys/lib/libsa/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.12 1997/02/06 07:05:48 mickey Exp $
+# $OpenBSD: Makefile,v 1.13 1997/02/06 14:22:32 mickey Exp $
# $NetBSD: Makefile,v 1.13 1996/10/02 16:19:51 ws Exp $
LIB= sa
@@ -34,7 +34,7 @@ SRCS+= divdi3.c qdivrem.c
.PATH: ${DIR}/../../lib/libkern
# io routines
-SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c ioctl.c \
+SRCS+= close.c closeall.c dev.c disklabel.c dkcksum.c cons.c ioctl.c \
lseek.c open.c nullfs.c read.c stat.c fstat.c write.c
# boot filesystems
@@ -42,9 +42,6 @@ SRCS+= ufs.c cd9660.c fat.c
.if defined(SA_ZLIB)
SRCS+= cread.c
-SRCS+= zlib.c
-.PATH: ${DIR}/../../net
-CFLAGS+=-DNO_DEFALTE -I${DIR}/../../net
.endif
.if !defined(NO_NET)
diff --git a/sys/lib/libsa/Makefile.inc b/sys/lib/libsa/Makefile.inc
index 95e1c5373ed..d45b9d2710b 100644
--- a/sys/lib/libsa/Makefile.inc
+++ b/sys/lib/libsa/Makefile.inc
@@ -1,10 +1,10 @@
-# $OpenBSD: Makefile.inc,v 1.4 1996/12/08 15:15:44 niklas Exp $
+# $OpenBSD: Makefile.inc,v 1.5 1997/02/06 14:22:32 mickey Exp $
# $NetBSD: Makefile.inc,v 1.5 1996/09/30 16:01:18 ws Exp $
#
# NOTE: $S must correspond to the top of the 'sys' tree
SADIR= $S/lib/libsa
-SADST= lib/sa
+SADST?= lib/sa
SAREL?= ../../
SALIB?= ${SADST}/libsa.a
@@ -17,14 +17,16 @@ SAMAKE= \
SAREL="${SAREL}" \
SADIR="${SADIR}" \
EXTRACFLAGS="${EXTRACFLAGS}"
+.if defined(NO_NET)
+SAMAKE+= NO_NET=""
+.endif
+.if defined(SA_ZLIB)
+SAMAKE+= SA_ZLIB=""
+.endif
${SALIB}: .NOTMAIN __always_make_salib
@echo making sure the stand-alone library is up to date...
-.if !defined(NO_NET)
@${SAMAKE} libsa.a
-.else
- @${SAMAKE} NO_NET="" libsa.a
-.endif
clean:: .NOTMAIN __always_make_salib
@echo cleaning the stand-alone library objects
diff --git a/sys/lib/libsa/alloc.c b/sys/lib/libsa/alloc.c
index 785b4a77d73..d985a1930fe 100644
--- a/sys/lib/libsa/alloc.c
+++ b/sys/lib/libsa/alloc.c
@@ -1,7 +1,10 @@
-/* $OpenBSD: alloc.c,v 1.3 1996/12/08 15:15:45 niklas Exp $ */
-/* $NetBSD: alloc.c,v 1.4 1996/09/26 23:15:00 cgd Exp $ */
+/* $OpenBSD: alloc.c,v 1.4 1997/02/06 14:22:33 mickey Exp $ */
+/* $NetBSD: alloc.c,v 1.6 1997/02/04 18:36:33 thorpej Exp $ */
-/*-
+/*
+ * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved.
+ * Copyright (c) 1996
+ * Matthias Drochner. All rights reserved.
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
@@ -65,46 +68,161 @@
* rights to redistribute these changes.
*/
+/*
+ * Dynamic memory allocator.
+ *
+ * Compile options:
+ *
+ * ALLOC_TRACE enable tracing of allocations/deallocations
+ *
+ * ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than
+ * the default best-fit algorithm.
+ *
+ * HEAP_LIMIT heap limit address (defaults to "no limit").
+ *
+ * HEAP_START start address of heap (defaults to '&end').
+ *
+ * DEBUG enable debugging sanity checks.
+ */
+
#include <sys/param.h>
/*
- * Dynamic memory allocator
+ * Each block actually has ALIGN(unsigned) + ALIGN(size) bytes allocated
+ * to it, as follows:
+ *
+ * 0 ... (sizeof(unsigned) - 1)
+ * allocated or unallocated: holds size of user-data part of block.
+ *
+ * sizeof(unsigned) ... (ALIGN(sizeof(unsigned)) - 1)
+ * allocated: unused
+ * unallocated: depends on packing of struct fl
+ *
+ * ALIGN(sizeof(unsigned)) ... (ALIGN(sizeof(unsigned)) + ALIGN(data size) - 1)
+ * allocated: user data
+ * unallocated: depends on packing of struct fl
+ *
+ * 'next' is only used when the block is unallocated (i.e. on the free list).
+ * However, note that ALIGN(sizeof(unsigned)) + ALIGN(data size) must
+ * be at least 'sizeof(struct fl)', so that blocks can be used as structures
+ * when on the free list.
*/
+
+#include "stand.h"
+
struct fl {
- struct fl *next;
unsigned size;
+ struct fl *next;
} *freelist = (struct fl *)0;
+#ifdef HEAP_START
+static char *top = (char*)HEAP_START;
+#else
extern char end[];
static char *top = end;
+#endif
void *
alloc(size)
unsigned size;
{
- register struct fl *f = freelist, **prev;
+ register struct fl **f = &freelist, **bestf = NULL;
+ unsigned bestsize = 0xffffffff; /* greater than any real size */
+ char *help;
+ int failed;
- prev = &freelist;
- while (f && f->size < size) {
- prev = &f->next;
- f = f->next;
+#ifdef ALLOC_TRACE
+ printf("alloc(%u)", size);
+#endif
+
+#ifdef ALLOC_FIRST_FIT
+ while (*f != (struct fl *)0 && (*f)->size < size)
+ f = &((*f)->next);
+ bestf = f;
+ failed = (*bestf == (struct fl *)0);
+#else
+ /* scan freelist */
+ while (*f) {
+ if ((*f)->size >= size) {
+ if ((*f)->size == size) /* exact match */
+ goto found;
+
+ if ((*f)->size < bestsize) {
+ /* keep best fit */
+ bestf = f;
+ bestsize = (*f)->size;
+ }
+ }
+ f = &((*f)->next);
}
- if (f == (struct fl *)0) {
- f = (struct fl *)ALIGN(top);
- top = (char *)f + ALIGN(size);
- } else
- *prev = f->next;
- return ((void *)f);
+
+ /* no match in freelist if bestsize unchanged */
+ failed = (bestsize == 0xffffffff);
+#endif
+
+ if (failed) { /* nothing found */
+ /*
+ * allocate from heap, keep chunk len in
+ * first word
+ */
+ help = top;
+
+ /* make _sure_ the region can hold a struct fl. */
+ if (size < ALIGN(sizeof (struct fl *)))
+ size = ALIGN(sizeof (struct fl *));
+ top += ALIGN(sizeof(unsigned)) + ALIGN(size);
+#ifdef HEAP_LIMIT
+ if (top > (char*)HEAP_LIMIT)
+ panic("heap full (0x%lx+%u)", help, size);
+#endif
+ *(unsigned *)help = ALIGN(size);
+#ifdef ALLOC_TRACE
+ printf("=%p\n", help + ALIGN(sizeof(unsigned)));
+#endif
+ return(help + ALIGN(sizeof(unsigned)));
+ }
+
+ /* we take the best fit */
+ f = bestf;
+
+found:
+ /* remove from freelist */
+ help = (char*)*f;
+ *f = (*f)->next;
+#ifdef ALLOC_TRACE
+ printf("=%p (origsize %u)\n", help + ALIGN(sizeof(unsigned)),
+ *(unsigned *)help);
+#endif
+ return(help + ALIGN(sizeof(unsigned)));
}
void
free(ptr, size)
void *ptr;
- unsigned size;
+ unsigned size; /* only for consistence check */
{
- register struct fl *f = (struct fl *)ptr;
+ register struct fl *f =
+ (struct fl *)((char*)ptr - ALIGN(sizeof(unsigned)));
+#ifdef ALLOC_TRACE
+ printf("free(%p, %u) (origsize %u)\n", ptr, size, f->size);
+#endif
+#ifdef DEBUG
+ if (size > f->size)
+ printf("free %u bytes @%p, should be <=%u\n",
+ size, ptr, f->size);
+#ifdef HEAP_START
+ if (ptr < (void *)HEAP_START)
+#else
+ if (ptr < (void *)end)
+#endif
+ printf("free: %lx before start of heap.\n", (u_long)ptr);
- f->size = ALIGN(size);
+#ifdef HEAP_LIMIT
+ if (ptr > (void *)HEAP_LIMIT)
+ printf("free: %lx beyond end of heap.\n", (u_long)ptr);
+#endif
+#endif /* DEBUG */
+ /* put into freelist */
f->next = freelist;
freelist = f;
}
diff --git a/sys/lib/libsa/printf.c b/sys/lib/libsa/printf.c
index b5f6317ef02..1bfc3b18621 100644
--- a/sys/lib/libsa/printf.c
+++ b/sys/lib/libsa/printf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printf.c,v 1.6 1996/12/08 15:15:54 niklas Exp $ */
+/* $OpenBSD: printf.c,v 1.7 1997/02/06 14:22:33 mickey Exp $ */
/* $NetBSD: printf.c,v 1.10 1996/11/30 04:19:21 gwr Exp $ */
/*-
@@ -205,6 +205,8 @@ reswitch: switch (ch = *fmt++) {
va_arg(ap, u_long) : va_arg(ap, u_int);
kprintn(put, ul, 10);
break;
+ case 'p':
+ lflag++;
case 'x':
ul = lflag ?
va_arg(ap, u_long) : va_arg(ap, u_int);