summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/libstand/Makefile11
-rw-r--r--lib/libstand/alloc.c244
-rw-r--r--lib/libstand/environment.c75
-rw-r--r--lib/libstand/gzipfs.c6
-rw-r--r--lib/libstand/sbrk.c60
-rw-r--r--lib/libstand/stand.h21
-rw-r--r--lib/libstand/ufs.c60
-rw-r--r--lib/libstand/zalloc.c591
-rw-r--r--lib/libstand/zalloc_defs.h83
-rw-r--r--lib/libstand/zalloc_malloc.c193
-rw-r--r--lib/libstand/zalloc_mem.h60
-rw-r--r--lib/libstand/zalloc_protos.h46
-rw-r--r--lib/libstand/zipfs.c6
13 files changed, 1118 insertions, 338 deletions
diff --git a/lib/libstand/Makefile b/lib/libstand/Makefile
index fee2187..38caa1c 100644
--- a/lib/libstand/Makefile
+++ b/lib/libstand/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.2 1998/08/20 08:23:12 msmith Exp $
+# $Id: Makefile,v 1.3 1998/09/15 02:30:22 msmith Exp $
#
# Originally from $NetBSD: Makefile,v 1.21 1997/10/26 22:08:38 lukem Exp $
#
@@ -13,16 +13,17 @@ NOPIC= YES
MAN3= libstand.3
# Mostly OK, some of the libc imports are a bit noisy
-CFLAGS+= -Wall
+CFLAGS+= -Wall -g
.if ${MACHINE_ARCH} == "alpha"
CFLAGS+= -mno-fp-regs
.endif
# standalone components and stuff we have modified locally
-SRCS+= __main.c alloc.c bcd.c bswap.c environment.c getopt.c gets.c \
- globals.c pager.c printf.c strdup.c strerror.c strtol.c random.c \
- twiddle.c
+SRCS+= __main.c bcd.c bswap.c environment.c getopt.c gets.c globals.c \
+ pager.c printf.c strdup.c strerror.c strtol.c random.c sbrk.c \
+ twiddle.c zalloc.c zalloc_malloc.c
+
# string functions from libc
.PATH: ${.CURDIR}/../libc/string
diff --git a/lib/libstand/alloc.c b/lib/libstand/alloc.c
deleted file mode 100644
index 7fc63c1..0000000
--- a/lib/libstand/alloc.c
+++ /dev/null
@@ -1,244 +0,0 @@
-/* $NetBSD: alloc.c,v 1.11 1997/09/17 16:24:00 drochner 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.
- *
- * This code is derived from software contributed to Berkeley by
- * The Mach Operating System project at Carnegie-Mellon University.
- *
- * 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.
- *
- * @(#)alloc.c 8.1 (Berkeley) 6/11/93
- *
- *
- * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Author: Alessandro Forin
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * 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>
-#include "stand.h"
-
-/* Default to variable heap operation */
-#define HEAP_VARIABLE
-#define DEBUG
-
-/*
- * Each block actually has ALIGN(size_t) + ALIGN(size) bytes allocated
- * to it, as follows:
- *
- * 0 ... (sizeof(size_t) - 1)
- * allocated or unallocated: holds size of user-data part of block.
- *
- * sizeof(size_t) ... (ALIGN(sizeof(size_t)) - 1)
- * allocated: unused
- * unallocated: depends on packing of struct fl
- *
- * ALIGN(sizeof(size_t)) ... (ALIGN(sizeof(size_t)) + 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(size_t)) + ALIGN(data size) must
- * be at least 'sizeof(struct fl)', so that blocks can be used as structures
- * when on the free list.
- */
-struct fl {
- size_t size;
- struct fl *next;
-} *freelist = (struct fl *)0;
-
-#ifdef HEAP_VARIABLE
-static char *top, *heapstart, *heaplimit;
-void setheap(start, limit)
-void *start, *limit;
-{
- heapstart = top = start;
- heaplimit = limit;
-}
-#define HEAP_START heapstart
-#define HEAP_LIMIT heaplimit
-#else /* !HEAP_VARIABLE */
-#ifndef HEAP_START
-extern char end[];
-#define HEAP_START end
-#endif
-static char *top = (char*)HEAP_START;
-#endif /* HEAP_VARIABLE */
-
-void *
-malloc(size)
- size_t size;
-{
- register struct fl **f = &freelist, **bestf = NULL;
- size_t bestsize = 0xffffffff; /* greater than any real size */
- char *help;
- int failed;
-
-#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);
- }
-
- /* 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(size_t)) + ALIGN(size);
-#ifdef HEAP_LIMIT
- if (top > (char*)HEAP_LIMIT)
- panic("heap full (0x%lx+%u)", help, size);
-#endif
- *(size_t *)help = ALIGN(size);
-#ifdef ALLOC_TRACE
- printf("=%lx\n", (u_long)help + ALIGN(sizeof(size_t)));
- getchar();
-#endif
- return(help + ALIGN(sizeof(size_t)));
- }
-
- /* we take the best fit */
- f = bestf;
-
-found:
- /* remove from freelist */
- help = (char*)*f;
- *f = (*f)->next;
-#ifdef ALLOC_TRACE
- printf("=%lx (origsize %u)\n", (u_long)help + ALIGN(sizeof(size_t)),
- *(size_t *)help);
- getchar();
-#endif
- return(help + ALIGN(sizeof(size_t)));
-}
-
-void
-free(ptr)
- void *ptr;
-{
- register struct fl *f =
- (struct fl *)((char*)ptr - ALIGN(sizeof(size_t)));
-#ifdef ALLOC_TRACE
- printf("free(%lx, %u) (origsize %u)\n", (u_long)ptr, size, f->size);
- getchar();
-#endif
-#ifdef DEBUG
- if (ptr < (void *)HEAP_START)
- printf("free: %lx before start of heap.\n", (u_long)ptr);
-
-#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;
-}
-
-/*
- * Emulate sbrk(0) behaviour
- */
-char *
-sbrk(int junk)
-{
- return((char *)top);
-}
diff --git a/lib/libstand/environment.c b/lib/libstand/environment.c
index 007b6a2..72a9e06 100644
--- a/lib/libstand/environment.c
+++ b/lib/libstand/environment.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id$
+ * $Id: environment.c,v 1.1.1.1 1998/08/20 08:19:55 msmith Exp $
*
*/
@@ -70,7 +70,6 @@ env_setenv(const char *name, int flags, void *value, ev_sethook_t sethook,
struct env_var *ev, *curr, *last;
if ((ev = env_getenv(name)) != NULL) {
-
/*
* If there's a set hook, let it do the work (unless we are working
* for one already.
@@ -78,12 +77,45 @@ env_setenv(const char *name, int flags, void *value, ev_sethook_t sethook,
if ((ev->ev_sethook != NULL) && !(flags & EV_NOHOOK))
return(ev->ev_sethook(ev, flags, value));
} else {
+
+ /*
+ * New variable; create and sort into list
+ */
ev = malloc(sizeof(struct env_var));
ev->ev_name = strdup(name);
ev->ev_value = NULL;
/* hooks can only be set when the variable is instantiated */
ev->ev_sethook = sethook;
ev->ev_unsethook = unsethook;
+
+ /* Sort into list */
+ ev->ev_prev = NULL;
+ ev->ev_next = NULL;
+ /* Search for the record to insert before */
+ for (last = NULL, curr = environ;
+ curr != NULL;
+ last = curr, curr = curr->ev_next) {
+
+ if (strcmp(ev->ev_name, curr->ev_name) < 0) {
+ if (curr->ev_prev) {
+ curr->ev_prev->ev_next = ev;
+ } else {
+ environ = ev;
+ }
+ ev->ev_next = curr;
+ ev->ev_prev = curr->ev_prev;
+ curr->ev_prev = ev;
+ break;
+ }
+ }
+ if (curr == NULL) {
+ if (last == NULL) {
+ environ = ev;
+ } else {
+ last->ev_next = ev;
+ ev->ev_prev = last;
+ }
+ }
}
/* If there is data in the variable, discard it */
@@ -100,35 +132,6 @@ env_setenv(const char *name, int flags, void *value, ev_sethook_t sethook,
/* Keep the flag components that are relevant */
ev->ev_flags = flags & (EV_DYNAMIC);
- /* Sort into list */
- ev->ev_prev = NULL;
- ev->ev_next = NULL;
-
- /* Search for the record to insert before */
- for (last = NULL, curr = environ;
- curr != NULL;
- last = curr, curr = curr->ev_next) {
-
- if (strcmp(ev->ev_name, curr->ev_name) < 0) {
- if (curr->ev_prev) {
- curr->ev_prev->ev_next = ev;
- } else {
- environ = ev;
- }
- ev->ev_next = curr;
- ev->ev_prev = curr->ev_prev;
- curr->ev_prev = ev;
- break;
- }
- }
- if (curr == NULL) {
- if (last == NULL) {
- environ = ev;
- } else {
- last->ev_next = ev;
- ev->ev_prev = last;
- }
- }
return(0);
}
@@ -158,11 +161,15 @@ setenv(const char *name, char *value, int overwrite)
int
putenv(const char *string)
{
- char *value;
+ char *value, *copy;
+ int result;
- if ((value = strchr(string, '=')) != NULL)
+ copy = strdup(string);
+ if ((value = strchr(copy, '=')) != NULL)
*(value++) = 0;
- return(setenv(string, value, 1));
+ result = setenv(copy, value, 1);
+ free(copy);
+ return(result);
}
int
diff --git a/lib/libstand/gzipfs.c b/lib/libstand/gzipfs.c
index 3a9730b..fb64665 100644
--- a/lib/libstand/gzipfs.c
+++ b/lib/libstand/gzipfs.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: zipfs.c,v 1.1.1.1 1998/08/20 08:19:55 msmith Exp $
+ * $Id: zipfs.c,v 1.2 1998/09/18 22:58:01 msmith Exp $
*
*/
@@ -59,11 +59,13 @@ struct fs_ops zipfs_fsops = {
zf_stat
};
+#if 0
void *
calloc(int items, size_t size)
{
return(malloc(items * size));
}
+#endif
static int
zf_fill(struct z_file *zf)
@@ -175,7 +177,7 @@ zf_open(const char *fname, struct open_file *f)
return(ENOENT);
/* Construct new name */
- zfname = malloc(strlen(fname) + 3);
+ zfname = malloc(strlen(fname) + 4);
sprintf(zfname, "%s.gz", fname);
/* Try to open the compressed datafile */
diff --git a/lib/libstand/sbrk.c b/lib/libstand/sbrk.c
new file mode 100644
index 0000000..0655c9a
--- /dev/null
+++ b/lib/libstand/sbrk.c
@@ -0,0 +1,60 @@
+/*-
+ * Copyright (c) 1998 Michael Smith
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * Minimal sbrk() emulation required for malloc support.
+ */
+
+#include <string.h>
+#include "stand.h"
+
+static size_t maxheap, heapsize = 0;
+static void *heapbase;
+
+void
+setheap(void *base, void *top)
+{
+ heapbase = base;
+ maxheap = top - base;
+}
+
+char *
+sbrk(int incr)
+{
+ char *ret;
+
+ if ((heapsize + incr) <= maxheap) {
+ ret = heapbase + heapsize;
+ bzero(ret, incr);
+ heapsize += incr;
+ return(ret);
+ }
+ errno = ENOMEM;
+ return((char *)-1);
+}
+
diff --git a/lib/libstand/stand.h b/lib/libstand/stand.h
index e575ee4..fb9ce4a 100644
--- a/lib/libstand/stand.h
+++ b/lib/libstand/stand.h
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: stand.h,v 1.3 1998/09/18 22:58:00 msmith Exp $
+ * $Id: stand.h,v 1.4 1998/09/18 23:00:57 msmith Exp $
* From $NetBSD: stand.h,v 1.22 1997/06/26 19:17:40 drochner Exp $
*/
@@ -66,6 +66,9 @@
#include <sys/cdefs.h>
#include <sys/stat.h>
+#define CHK(fmt, args...) printf("%s(%d): " fmt "\n", __FUNCTION__, __LINE__ , ##args)
+#define PCHK(fmt, args...) {printf("%s(%d): " fmt "\n", __FUNCTION__, __LINE__ , ##args); getchar();}
+
#ifndef NULL
#define NULL 0
#endif
@@ -168,10 +171,18 @@ extern struct open_file files[];
#define toupper(c) ((c) - 'a' + 'A')
#define tolower(c) ((c) - 'A' + 'a')
-extern void setheap(void *, void *);
-extern void *malloc(size_t);
-extern void free(void *);
-extern char *sbrk(int junk);
+/* sbrk emulation */
+extern void setheap(void *base, void *top);
+extern char *sbrk(int incr);
+
+/* Matt Dillon's zalloc/zmalloc */
+extern void *malloc(size_t bytes);
+extern void free(void *ptr);
+/*#define free(p) {CHK("free %p", p); free(p);} */ /* use for catching guard violations */
+extern void *calloc(size_t n1, size_t n2);
+extern void *realloc(void *ptr, size_t size);
+extern void *reallocf(void *ptr, size_t size);
+extern void mallocstats(void);
/* disklabel support (undocumented, may be junk) */
struct disklabel;
diff --git a/lib/libstand/ufs.c b/lib/libstand/ufs.c
index a32fe06..bd7f8c7 100644
--- a/lib/libstand/ufs.c
+++ b/lib/libstand/ufs.c
@@ -84,7 +84,6 @@ struct fs_ops ufs_fsops = {
"ufs", ufs_open, ufs_close, ufs_read, null_write, ufs_seek, ufs_stat
};
-
/*
* In-core open file.
*/
@@ -113,39 +112,6 @@ static int search_directory(char *, struct open_file *, ino_t *);
static void ffs_oldfscompat(struct fs *);
#endif
-static void *buffers4 = 0;
-static void *buffers8 = 0;
-
-static void *
-getbuf(size_t size)
-{
- void *p = 0;
- if (size == 8192 && buffers8) {
- p = buffers8;
- buffers8 = *(void **) p;
- }
- if (size == 4096 && buffers4) {
- p = buffers4;
- buffers4 = *(void **) p;
- }
- if (!p)
- p = malloc(size);
- return p;
-}
-
-static void
-relbuf(void *p, size_t size)
-{
- if (size == 8192) {
- *(void**) p = buffers8;
- buffers8 = p;
- } else if (size == 4096) {
- *(void**) p = buffers4;
- buffers8 = p;
- } else
- free(p);
-}
-
/*
* Read a new inode into a file structure.
*/
@@ -160,10 +126,13 @@ read_inode(inumber, f)
size_t rsize;
int rc;
+ if (fs == NULL)
+ panic("fs == NULL");
+
/*
* Read inode and save it.
*/
- buf = getbuf(fs->fs_bsize);
+ buf = malloc(fs->fs_bsize);
twiddle();
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fs, ino_to_fsba(fs, inumber)), fs->fs_bsize,
@@ -193,7 +162,7 @@ read_inode(inumber, f)
fp->f_buf_blkno = -1;
}
out:
- relbuf(buf, fs->fs_bsize);
+ free(buf);
return (rc);
}
@@ -273,7 +242,7 @@ block_map(f, file_block, disk_block_p)
if (fp->f_blkno[level] != ind_block_num) {
if (fp->f_blk[level] == (char *)0)
fp->f_blk[level] =
- getbuf(fs->fs_bsize);
+ malloc(fs->fs_bsize);
twiddle();
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
fsbtodb(fp->f_fs, ind_block_num),
@@ -331,7 +300,7 @@ buf_read_file(f, buf_p, size_p)
return (rc);
if (fp->f_buf == (char *)0)
- fp->f_buf = getbuf(fs->fs_bsize);
+ fp->f_buf = malloc(fs->fs_bsize);
if (disk_block == 0) {
bzero(fp->f_buf, block_size);
@@ -442,7 +411,7 @@ ufs_open(upath, f)
f->f_fsdata = (void *)fp;
/* allocate space and read super block */
- fs = getbuf(SBSIZE);
+ fs = malloc(SBSIZE);
fp->f_fs = fs;
twiddle();
rc = (f->f_dev->dv_strategy)(f->f_devdata, F_READ,
@@ -563,7 +532,7 @@ ufs_open(upath, f)
register struct fs *fs = fp->f_fs;
if (!buf)
- buf = getbuf(fs->fs_bsize);
+ buf = malloc(fs->fs_bsize);
rc = block_map(f, (daddr_t)0, &disk_block);
if (rc)
goto out;
@@ -599,12 +568,12 @@ ufs_open(upath, f)
rc = 0;
out:
if (buf)
- relbuf(buf, fs->fs_bsize);
+ free(buf);
if (path)
free(path);
if (rc) {
if (fp->f_buf)
- relbuf(fp->f_buf, fs->fs_bsize);
+ free(fp->f_buf);
free(fp->f_fs);
free(fp);
}
@@ -616,7 +585,6 @@ ufs_close(f)
struct open_file *f;
{
register struct file *fp = (struct file *)f->f_fsdata;
- struct fs *fs = fp->f_fs;
int level;
f->f_fsdata = (void *)0;
@@ -625,11 +593,11 @@ ufs_close(f)
for (level = 0; level < NIADDR; level++) {
if (fp->f_blk[level])
- relbuf(fp->f_blk[level], fs->fs_bsize);
+ free(fp->f_blk[level]);
}
if (fp->f_buf)
- relbuf(fp->f_buf, fs->fs_bsize);
- relbuf(fp->f_fs, SBSIZE);
+ free(fp->f_buf);
+ free(fp->f_fs);
free(fp);
return (0);
}
diff --git a/lib/libstand/zalloc.c b/lib/libstand/zalloc.c
new file mode 100644
index 0000000..b441702
--- /dev/null
+++ b/lib/libstand/zalloc.c
@@ -0,0 +1,591 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * LIB/MEMORY/ZALLOC.C - self contained low-overhead memory pool/allocation
+ * subsystem
+ *
+ * This subsystem implements memory pools and memory allocation
+ * routines.
+ *
+ * Pools are managed via a linked list of 'free' areas. Allocating
+ * memory creates holes in the freelist, freeing memory fills them.
+ * Since the freelist consists only of free memory areas, it is possible
+ * to allocate the entire pool without incuring any structural overhead.
+ *
+ * The system works best when allocating similarly-sized chunks of
+ * memory. Care must be taken to avoid fragmentation when
+ * allocating/deallocating dissimilar chunks.
+ *
+ * When a memory pool is first allocated, the entire pool is marked as
+ * allocated. This is done mainly because we do not want to modify any
+ * portion of a pool's data area until we are given permission. The
+ * caller must explicitly deallocate portions of the pool to make them
+ * available.
+ *
+ * z[n]xalloc() works like z[n]alloc() but the allocation is made from
+ * within the specified address range. If the segment could not be
+ * allocated, NULL is returned. WARNING! The address range will be
+ * aligned to an 8 or 16 byte boundry depending on the cpu so if you
+ * give an unaligned address range, unexpected results may occur.
+ *
+ * If a standard allocation fails, the reclaim function will be called
+ * to recover some space. This usually causes other portions of the
+ * same pool to be released. Memory allocations at this low level
+ * should not block but you can do that too in your reclaim function
+ * if you want. Reclaim does not function when z[n]xalloc() is used,
+ * only for z[n]alloc().
+ *
+ * Allocation and frees of 0 bytes are valid operations.
+ */
+
+#include "zalloc_defs.h"
+
+Prototype struct MemPool *DummyStructMemPool;
+Library void *znalloc(struct MemPool *mpool, iaddr_t bytes);
+Library void *zalloc(struct MemPool *mpool, iaddr_t bytes);
+Library void *zallocAlign(struct MemPool *mpool, iaddr_t bytes, iaddr_t align);
+Library void *zxalloc(struct MemPool *mp, void *addr1, void *addr2, iaddr_t bytes);
+Library void *znxalloc(struct MemPool *mp, void *addr1, void *addr2, iaddr_t bytes);
+Library char *zallocStr(struct MemPool *mpool, const char *s, int slen);
+Library void zfree(struct MemPool *mpool, void *ptr, iaddr_t bytes);
+Library void zfreeStr(struct MemPool *mpool, char *s);
+Library void zinitPool(struct MemPool *mp, const char *id, void (*fpanic)(const char *ctl, ...), int (*freclaim)(struct MemPool *memPool, iaddr_t bytes), void *pBase, iaddr_t pSize);
+Library void zclearPool(struct MemPool *mp);
+Library void znop(const char *ctl, ...);
+Library int znot(struct MemPool *memPool, iaddr_t bytes);
+Library void zallocstats(struct MemPool *mp);
+
+/*
+ * znop() - panic function if none supplied.
+ */
+
+void
+znop(const char *ctl, ...)
+{
+}
+
+/*
+ * znot() - reclaim function if none supplied
+ */
+
+int
+znot(struct MemPool *memPool, iaddr_t bytes)
+{
+ return(-1);
+}
+
+#ifndef MALLOCLIB
+
+/*
+ * zalloc() - allocate and zero memory from pool. Call reclaim
+ * and retry if appropriate, return NULL if unable to allocate
+ * memory.
+ */
+
+void *
+zalloc(MemPool *mp, iaddr_t bytes)
+{
+ void *ptr;
+
+ if ((ptr = znalloc(mp, bytes)) != NULL)
+ bzero(ptr, bytes);
+ return(ptr);
+}
+
+/*
+ * zallocAlign() - allocate and zero memory from pool, enforce specified
+ * alignment (must be power of 2) on allocated memory.
+ */
+
+void *
+zallocAlign(struct MemPool *mp, iaddr_t bytes, iaddr_t align)
+{
+ void *ptr;
+
+ --align;
+ bytes = (bytes + align) & ~align;
+
+ if ((ptr = znalloc(mp, bytes)) != NULL) {
+ bzero(ptr, bytes);
+ }
+ return(ptr);
+}
+
+#endif
+
+/*
+ * znalloc() - allocate memory (without zeroing) from pool. Call reclaim
+ * and retry if appropriate, return NULL if unable to allocate
+ * memory.
+ */
+
+void *
+znalloc(MemPool *mp, iaddr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ *
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return((void *)-1);
+
+ do {
+ /*
+ * locate freelist entry big enough to hold the object. If all objects
+ * are the same size, this is a constant-time function.
+ */
+
+ if (bytes <= mp->mp_Size - mp->mp_Used) {
+ MemNode **pmn;
+ MemNode *mn;
+
+ for (pmn = &mp->mp_First; (mn=*pmn) != NULL; pmn = &mn->mr_Next) {
+ if (bytes > mn->mr_Bytes)
+ continue;
+
+ /*
+ * Cut a chunk of memory out of the beginning of this
+ * block and fixup the link appropriately.
+ */
+
+ {
+ char *ptr = (char *)mn;
+
+ if (mn->mr_Bytes == bytes) {
+ *pmn = mn->mr_Next;
+ } else {
+ mn = (MemNode *)((char *)mn + bytes);
+ mn->mr_Next = ((MemNode *)ptr)->mr_Next;
+ mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
+ *pmn = mn;
+ }
+ mp->mp_Used += bytes;
+ return(ptr);
+ }
+ }
+ }
+ } while (mp->mp_Reclaim(mp, bytes) == 0);
+
+ /*
+ * Memory pool is full, return NULL.
+ */
+
+ return(NULL);
+}
+
+#ifndef MALLOCLIB
+
+/*
+ * z[n]xalloc() - allocate memory from within a specific address region.
+ * If allocating AT a specific address, then addr2 must be
+ * set to addr1 + bytes (and this only works if addr1 is
+ * already aligned). addr1 and addr2 are aligned by
+ * MEMNODE_SIZE_MASK + 1 (i.e. they wlill be 8 or 16 byte
+ * aligned depending on the machine core).
+ */
+
+void *
+zxalloc(MemPool *mp, void *addr1, void *addr2, iaddr_t bytes)
+{
+ void *ptr;
+
+ if ((ptr = znxalloc(mp, addr1, addr2, bytes)) != NULL)
+ bzero(ptr, bytes);
+ return(ptr);
+}
+
+void *
+znxalloc(MemPool *mp, void *addr1, void *addr2, iaddr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+ addr1= (void *)(((iaddr_t)addr1 + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK);
+ addr2= (void *)(((iaddr_t)addr2 + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK);
+
+ if (bytes == 0)
+ return((void *)addr1);
+
+ /*
+ * Locate freelist entry big enough to hold the object that is within
+ * the allowed address range.
+ */
+
+ if (bytes <= mp->mp_Size - mp->mp_Used) {
+ MemNode **pmn;
+ MemNode *mn;
+
+ for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
+ int mrbytes = mn->mr_Bytes;
+ int offset = 0;
+
+ /*
+ * offset from base of mn to satisfy addr1. 0 or positive
+ */
+
+ if ((char *)mn < (char *)addr1)
+ offset = (char *)addr1 - (char *)mn;
+
+ /*
+ * truncate mrbytes to satisfy addr2. mrbytes may go negative
+ * if the mn is beyond the last acceptable address.
+ */
+
+ if ((char *)mn + mrbytes > (char *)addr2)
+ mrbytes = (saddr_t)((iaddr_t)addr2 - (iaddr_t)mn); /* signed */
+
+ /*
+ * beyond last acceptable address.
+ *
+ * before first acceptable address (if offset > mrbytes, the
+ * second conditional will always succeed).
+ *
+ * area overlapping acceptable address range is not big enough.
+ */
+
+ if (mrbytes < 0)
+ break;
+
+ if (mrbytes - offset < bytes)
+ continue;
+
+ /*
+ * Cut a chunk of memory out of the block and fixup the link
+ * appropriately.
+ *
+ * If offset != 0, we have to cut a chunk out from the middle of
+ * the block.
+ */
+
+ if (offset) {
+ MemNode *mnew = (MemNode *)((char *)mn + offset);
+
+ mnew->mr_Bytes = mn->mr_Bytes - offset;
+ mnew->mr_Next = mn->mr_Next;
+ mn->mr_Bytes = offset;
+ mn->mr_Next = mnew;
+ pmn = &mn->mr_Next;
+ mn = mnew;
+ }
+ {
+ char *ptr = (char *)mn;
+ if (mn->mr_Bytes == bytes) {
+ *pmn = mn->mr_Next;
+ } else {
+ mn = (MemNode *)((char *)mn + bytes);
+ mn->mr_Next = ((MemNode *)ptr)->mr_Next;
+ mn->mr_Bytes = ((MemNode *)ptr)->mr_Bytes - bytes;
+ *pmn = mn;
+ }
+ mp->mp_Used += bytes;
+ return(ptr);
+ }
+ }
+ }
+ return(NULL);
+}
+
+#endif
+
+/*
+ * zfree() - free previously allocated memory
+ */
+
+void
+zfree(MemPool *mp, void *ptr, iaddr_t bytes)
+{
+ /*
+ * align according to pool object size (can be 0). This is
+ * inclusive of the MEMNODE_SIZE_MASK minimum alignment.
+ */
+ bytes = (bytes + MEMNODE_SIZE_MASK) & ~MEMNODE_SIZE_MASK;
+
+ if (bytes == 0)
+ return;
+
+ /*
+ * panic if illegal pointer
+ */
+
+ if ((char *)ptr < (char *)mp->mp_Base ||
+ (char *)ptr + bytes > (char *)mp->mp_End ||
+ ((iaddr_t)ptr & MEMNODE_SIZE_MASK) != 0
+ ) {
+ mp->mp_Panic(
+ "zfree(%s,0x%08lx,%d): wild pointer",
+ mp->mp_Ident,
+ (long)ptr,
+ bytes
+ );
+ }
+
+ /*
+ * free the segment
+ */
+
+ {
+ MemNode **pmn;
+ MemNode *mn;
+
+ mp->mp_Used -= bytes;
+
+ for (pmn = &mp->mp_First; (mn = *pmn) != NULL; pmn = &mn->mr_Next) {
+ /*
+ * If area between last node and current node
+ * - check range
+ * - check merge with next area
+ * - check merge with previous area
+ */
+ if ((char *)ptr <= (char *)mn) {
+ /*
+ * range check
+ */
+ if ((char *)ptr + bytes > (char *)mn) {
+ mp->mp_Panic("zfree(%s,0x%08lx,%d): corrupt memlist1",
+ mp->mp_Ident,
+ (long)ptr,
+ bytes
+ );
+ }
+
+ /*
+ * merge against next area or create independant area
+ */
+
+ if ((char *)ptr + bytes == (char *)mn) {
+ ((MemNode *)ptr)->mr_Next = mn->mr_Next;
+ ((MemNode *)ptr)->mr_Bytes= bytes + mn->mr_Bytes;
+ } else {
+ ((MemNode *)ptr)->mr_Next = mn;
+ ((MemNode *)ptr)->mr_Bytes= bytes;
+ }
+ *pmn = mn = (MemNode *)ptr;
+
+ /*
+ * merge against previous area (if there is a previous
+ * area).
+ */
+
+ if (pmn != &mp->mp_First) {
+ if ((char*)pmn + ((MemNode*)pmn)->mr_Bytes == (char*)ptr) {
+ ((MemNode *)pmn)->mr_Next = mn->mr_Next;
+ ((MemNode *)pmn)->mr_Bytes += mn->mr_Bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+ return;
+ /* NOT REACHED */
+ }
+ if ((char *)ptr < (char *)mn + mn->mr_Bytes) {
+ mp->mp_Panic("zfree(%s,0x%08lx,%d): corrupt memlist2",
+ mp->mp_Ident,
+ (long)ptr,
+ bytes
+ );
+ }
+ }
+ /*
+ * We are beyond the last MemNode, append new MemNode. Merge against
+ * previous area if possible.
+ */
+ if (pmn == &mp->mp_First ||
+ (char *)pmn + ((MemNode *)pmn)->mr_Bytes != (char *)ptr
+ ) {
+ ((MemNode *)ptr)->mr_Next = NULL;
+ ((MemNode *)ptr)->mr_Bytes = bytes;
+ *pmn = (MemNode *)ptr;
+ mn = (MemNode *)ptr;
+ } else {
+ ((MemNode *)pmn)->mr_Bytes += bytes;
+ mn = (MemNode *)pmn;
+ }
+ }
+}
+
+#ifndef MALLOCLIB
+
+/*
+ * zallocStr() - allocate memory and copy string.
+ */
+
+char *
+zallocStr(MemPool *mp, const char *s, int slen)
+{
+ char *ptr;
+
+ if (slen < 0)
+ slen = strlen(s);
+ if ((ptr = znalloc(mp, slen + 1)) != NULL) {
+ bcopy(s, ptr, slen);
+ ptr[slen] = 0;
+ }
+ return(ptr);
+}
+
+/*
+ * zfreeStr() - free memory associated with an allocated string.
+ */
+
+void
+zfreeStr(MemPool *mp, char *s)
+{
+ zfree(mp, s, strlen(s) + 1);
+}
+
+#endif
+
+/*
+ * zinitpool() - initialize a memory pool
+ */
+
+void
+zinitPool(
+ MemPool *mp,
+ const char *id,
+ void (*fpanic)(const char *ctl, ...),
+ int (*freclaim)(MemPool *memPool, iaddr_t bytes),
+ void *pBase,
+ iaddr_t pSize
+) {
+ if (fpanic == NULL)
+ fpanic = znop;
+ if (freclaim == NULL)
+ freclaim = znot;
+
+ if (id != (const char *)-1)
+ mp->mp_Ident = id;
+ mp->mp_Base = pBase;
+ mp->mp_End = (char *)pBase + pSize;
+ mp->mp_First = NULL;
+ mp->mp_Size = pSize;
+ mp->mp_Used = pSize;
+ mp->mp_Panic = fpanic;
+ mp->mp_Reclaim = freclaim;
+}
+
+/*
+ * zextendPool() - extend memory pool to cover additional space.
+ *
+ * Note: the added memory starts out as allocated, you
+ * must free it to make it available to the memory subsystem.
+ *
+ * Note: mp_Size may not reflect (mp_End - mp_Base) range
+ * due to other parts of the system doing their own sbrk()
+ * calls.
+ */
+
+void
+zextendPool(MemPool *mp, void *base, iaddr_t bytes)
+{
+ if (mp->mp_Size == 0) {
+ mp->mp_Base = base;
+ mp->mp_Used = bytes;
+ } else {
+ void *pend = (char *)mp->mp_Base + mp->mp_Size;
+
+ if (base < mp->mp_Base) {
+ /* mp->mp_Size += (char *)mp->mp_Base - (char *)base; */
+ mp->mp_Used += (char *)mp->mp_Base - (char *)base;
+ mp->mp_Base = base;
+ }
+ base = (char *)base + bytes;
+ if (base > pend) {
+ /* mp->mp_Size += (char *)base - (char *)pend; */
+ mp->mp_Used += (char *)base - (char *)pend;
+ }
+ mp->mp_End = (char *)mp->mp_Base + mp->mp_Size;
+ }
+ mp->mp_Size += bytes;
+}
+
+#ifndef MALLOCLIB
+
+/*
+ * zclearpool() - Free all memory associated with a memory pool,
+ * destroying any previous allocations. Commonly
+ * called afte zinitPool() to make a pool available
+ * for use.
+ */
+
+void
+zclearPool(MemPool *mp)
+{
+ MemNode *mn = mp->mp_Base;
+
+ mn->mr_Next = NULL;
+ mn->mr_Bytes = mp->mp_Size;
+ mp->mp_First = mn;
+}
+
+#endif
+
+#ifdef ZALLOCDEBUG
+
+void
+zallocstats(MemPool *mp)
+{
+ int abytes = 0;
+ int hbytes = 0;
+ int fcount = 0;
+ MemNode *mn;
+
+ printf("Pool %s, %d bytes reserved", mp->mp_Ident, mp->mp_Size);
+
+ mn = mp->mp_First;
+
+ if ((void *)mn != (void *)mp->mp_Base) {
+ abytes += (char *)mn - (char *)mp->mp_Base;
+ }
+
+ while (mn) {
+ if ((char *)mn + mn->mr_Bytes != mp->mp_End) {
+ hbytes += mn->mr_Bytes;
+ ++fcount;
+ }
+ if (mn->mr_Next)
+ abytes += (char *)mn->mr_Next - ((char *)mn + mn->mr_Bytes);
+ mn = mn->mr_Next;
+ }
+ printf(" %d bytes allocated\n%d fragments (%d bytes fragmented)\n",
+ abytes,
+ fcount,
+ hbytes
+ );
+}
+
+#endif
+
diff --git a/lib/libstand/zalloc_defs.h b/lib/libstand/zalloc_defs.h
new file mode 100644
index 0000000..d80d3a0
--- /dev/null
+++ b/lib/libstand/zalloc_defs.h
@@ -0,0 +1,83 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * DEFS.H
+ */
+
+#define USEPANIC /* call panic() to register errors */
+#define USEGUARD /* use stard/end guard bytes */
+#define USEENDGUARD
+#define DMALLOCDEBUG /* add debugging code to gather stats */
+#define ZALLOCDEBUG
+#define MALLOCLIB /* don't build unnecessary zalloc parts */
+
+#include <string.h>
+#include "stand.h"
+
+typedef unsigned int iaddr_t; /* unsigned int same size as pointer */
+typedef int saddr_t; /* signed int same size as pointer */
+
+#include "zalloc_mem.h"
+
+#define Prototype extern
+#define Library extern
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+/*
+ * block extension for sbrk()
+ */
+
+#define BLKEXTEND (64 * 1024)
+#define BLKEXTENDMASK (BLKEXTEND - 1)
+
+/*
+ * required malloc alignment. Use sizeof(long double) for architecture
+ * independance.
+ *
+ * Note: if we implement a more sophisticated realloc, we should ensure that
+ * MALLOCALIGN is at least as large as MemNode.
+ */
+
+typedef struct Guard {
+ size_t ga_Bytes;
+ size_t ga_Magic; /* must be at least 32 bits */
+} Guard;
+
+#define MATYPE long double
+#define MALLOCALIGN ((sizeof(MATYPE) > sizeof(Guard)) ? sizeof(MATYPE) : sizeof(Guard))
+#define GAMAGIC 0x55FF44FD
+
+#include "zalloc_protos.h"
+
diff --git a/lib/libstand/zalloc_malloc.c b/lib/libstand/zalloc_malloc.c
new file mode 100644
index 0000000..79e6c80
--- /dev/null
+++ b/lib/libstand/zalloc_malloc.c
@@ -0,0 +1,193 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
+ */
+
+#include "zalloc_defs.h"
+
+static MemPool MallocPool = INITPOOL("malloc", panic, znot);
+
+#ifdef DMALLOCDEBUG
+static int MallocMax;
+static int MallocCount;
+
+void mallocstats(void);
+#endif
+
+void *
+malloc(size_t bytes)
+{
+ Guard *res;
+
+#ifdef USEENDGUARD
+ bytes += MALLOCALIGN + 1;
+#else
+ bytes += MALLOCALIGN;
+#endif
+
+ while ((res = znalloc(&MallocPool, bytes)) == NULL) {
+ int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
+ char *base;
+
+ if ((base = sbrk(incr)) == (char *)-1)
+ return(NULL);
+ zextendPool(&MallocPool, base, incr);
+ zfree(&MallocPool, base, incr);
+ }
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+#ifdef USEGUARD
+ res->ga_Magic = GAMAGIC;
+#endif
+ res->ga_Bytes = bytes;
+#ifdef USEENDGUARD
+ *((char *)res + bytes - 1) = -2;
+#endif
+ return((char *)res + MALLOCALIGN);
+}
+
+void
+free(void *ptr)
+{
+ size_t bytes;
+
+ if (ptr != NULL) {
+ Guard *res = (void *)((char *)ptr - MALLOCALIGN);
+
+#ifdef USEGUARD
+ if (res->ga_Magic != GAMAGIC) {
+#ifdef USEPANIC
+ panic("free(): guard1 fail @ %08lx\n", ptr);
+#else
+ *(char *)0 = 1;
+#endif
+ }
+ res->ga_Magic = -1;
+#endif
+#ifdef USEENDGUARD
+ if (*((char *)res + res->ga_Bytes - 1) != -2) {
+#ifdef USEPANIC
+ panic("free(): guard2 fail @ %08lx + %d\n", ptr, res->ga_Bytes - MALLOCALIGN);
+#else
+ *(char *)0 = 1;
+#endif
+ }
+ *((char *)res + res->ga_Bytes - 1) = -1;
+#endif
+
+ bytes = res->ga_Bytes;
+ zfree(&MallocPool, res, bytes);
+#ifdef DMALLOCDEBUG
+ --MallocCount;
+#endif
+ }
+}
+
+
+void *
+calloc(size_t n1, size_t n2)
+{
+ iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
+ void *res;
+
+ if ((res = malloc(bytes)) != NULL) {
+ bzero(res, bytes);
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#endif
+ }
+ return(res);
+}
+
+/*
+ * realloc() - I could be fancier here and free the old buffer before
+ * allocating the new one (saving potential fragmentation
+ * and potential buffer copies). But I don't bother.
+ */
+
+void *
+realloc(void *ptr, size_t size)
+{
+ void *res;
+ size_t old;
+
+ if ((res = malloc(size)) != NULL) {
+ if (ptr) {
+ old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
+ if (old < size)
+ bcopy(ptr, res, old);
+ else
+ bcopy(ptr, res, size);
+ free(ptr);
+ } else {
+#ifdef DMALLOCDEBUG
+ if (++MallocCount > MallocMax)
+ MallocMax = MallocCount;
+#ifdef EXITSTATS
+ if (DidAtExit == 0) {
+ DidAtExit = 1;
+ atexit(mallocstats);
+ }
+#endif
+#endif
+ }
+ }
+ return(res);
+}
+
+void *
+reallocf(void *ptr, size_t size)
+{
+ void *res;
+
+ if ((res = realloc(ptr, size)) == NULL)
+ free(ptr);
+ return(res);
+}
+
+#ifdef DMALLOCDEBUG
+
+void
+mallocstats(void)
+{
+ printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
+#ifdef ZALLOCDEBUG
+ zallocstats(&MallocPool);
+#endif
+}
+
+#endif
+
diff --git a/lib/libstand/zalloc_mem.h b/lib/libstand/zalloc_mem.h
new file mode 100644
index 0000000..8655e7b
--- /dev/null
+++ b/lib/libstand/zalloc_mem.h
@@ -0,0 +1,60 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+/*
+ * H/MEM.H
+ *
+ * Basic memory pool / memory node structures.
+ */
+
+typedef struct MemNode {
+ struct MemNode *mr_Next;
+ iaddr_t mr_Bytes;
+} MemNode;
+
+typedef struct MemPool {
+ const char *mp_Ident;
+ void *mp_Base;
+ void *mp_End;
+ MemNode *mp_First;
+ void (*mp_Panic)(const char *ctl, ...);
+ int (*mp_Reclaim)(struct MemPool *memPool, iaddr_t bytes);
+ iaddr_t mp_Size;
+ iaddr_t mp_Used;
+} MemPool;
+
+#define MEMNODE_SIZE_MASK ((sizeof(MemNode) <= 8) ? 7 : 15)
+
+#define INITPOOL(name,panic,reclaim) { name, NULL, NULL, NULL, panic, reclaim }
+
+#define ZNOTE_FREE 0
+#define ZNOTE_REUSE 1
+
diff --git a/lib/libstand/zalloc_protos.h b/lib/libstand/zalloc_protos.h
new file mode 100644
index 0000000..e49a871
--- /dev/null
+++ b/lib/libstand/zalloc_protos.h
@@ -0,0 +1,46 @@
+/*
+ * This module derived from code donated to the FreeBSD Project by
+ * Matthew Dillon <dillon@backplane.com>
+ *
+ * Copyright (c) 1998 The FreeBSD Project
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $Id$
+ */
+
+Prototype struct MemPool *DummyStructMemPool;
+Library void *znalloc(struct MemPool *mpool, iaddr_t bytes);
+Library void *zalloc(struct MemPool *mpool, iaddr_t bytes);
+Library void *zallocAlign(struct MemPool *mpool, iaddr_t bytes, iaddr_t align);
+Library void *zxalloc(struct MemPool *mp, void *addr1, void *addr2, iaddr_t bytes);
+Library void *znxalloc(struct MemPool *mp, void *addr1, void *addr2, iaddr_t bytes);
+Library char *zallocStr(struct MemPool *mpool, const char *s, int slen);
+Library void zfree(struct MemPool *mpool, void *ptr, iaddr_t bytes);
+Library void zfreeStr(struct MemPool *mpool, char *s);
+Library void zinitPool(struct MemPool *mp, const char *id, void (*fpanic)(const char *ctl, ...), int (*freclaim)(struct MemPool *memPool, iaddr_t bytes), void *pBase, iaddr_t pSize);
+Library void zextendPool(MemPool *mp, void *base, iaddr_t bytes);
+Library void zclearPool(struct MemPool *mp);
+Library void znop(const char *ctl, ...);
+Library int znot(struct MemPool *memPool, iaddr_t bytes);
+Library void zallocstats(struct MemPool *mp);
diff --git a/lib/libstand/zipfs.c b/lib/libstand/zipfs.c
index 3a9730b..fb64665 100644
--- a/lib/libstand/zipfs.c
+++ b/lib/libstand/zipfs.c
@@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: zipfs.c,v 1.1.1.1 1998/08/20 08:19:55 msmith Exp $
+ * $Id: zipfs.c,v 1.2 1998/09/18 22:58:01 msmith Exp $
*
*/
@@ -59,11 +59,13 @@ struct fs_ops zipfs_fsops = {
zf_stat
};
+#if 0
void *
calloc(int items, size_t size)
{
return(malloc(items * size));
}
+#endif
static int
zf_fill(struct z_file *zf)
@@ -175,7 +177,7 @@ zf_open(const char *fname, struct open_file *f)
return(ENOENT);
/* Construct new name */
- zfname = malloc(strlen(fname) + 3);
+ zfname = malloc(strlen(fname) + 4);
sprintf(zfname, "%s.gz", fname);
/* Try to open the compressed datafile */
OpenPOWER on IntegriCloud