zalloc_malloc.c revision 40520
139665Smsmith/*
239665Smsmith * This module derived from code donated to the FreeBSD Project by
339665Smsmith * Matthew Dillon <dillon@backplane.com>
439665Smsmith *
539665Smsmith * Copyright (c) 1998 The FreeBSD Project
639665Smsmith * All rights reserved.
739665Smsmith *
839665Smsmith * Redistribution and use in source and binary forms, with or without
939665Smsmith * modification, are permitted provided that the following conditions
1039665Smsmith * are met:
1139665Smsmith * 1. Redistributions of source code must retain the above copyright
1239665Smsmith *    notice, this list of conditions and the following disclaimer.
1339665Smsmith * 2. Redistributions in binary form must reproduce the above copyright
1439665Smsmith *    notice, this list of conditions and the following disclaimer in the
1539665Smsmith *    documentation and/or other materials provided with the distribution.
1639665Smsmith *
1739665Smsmith * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1839665Smsmith * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1939665Smsmith * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2039665Smsmith * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2139665Smsmith * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2239665Smsmith * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2339665Smsmith * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2439665Smsmith * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2539665Smsmith * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2639665Smsmith * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2739665Smsmith * SUCH DAMAGE.
2839665Smsmith *
2940520Sdfr *	$Id: zalloc_malloc.c,v 1.3 1998/10/01 17:35:08 msmith Exp $
3039665Smsmith */
3139665Smsmith
3239665Smsmith/*
3339665Smsmith * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
3439665Smsmith */
3539665Smsmith
3639665Smsmith#include "zalloc_defs.h"
3739665Smsmith
3839863Smsmithstatic MemPool	MallocPool;
3939665Smsmith
4039665Smsmith#ifdef DMALLOCDEBUG
4139665Smsmithstatic int MallocMax;
4239665Smsmithstatic int MallocCount;
4339665Smsmith
4439665Smsmithvoid mallocstats(void);
4539665Smsmith#endif
4639665Smsmith
4739672Sdfr#ifdef malloc
4839672Sdfr#undef malloc
4939672Sdfr#undef free
5039672Sdfr#endif
5139672Sdfr
5240520Sdfr#ifdef __alpha__
5340520Sdfrvoid
5440520Sdfrfree_region(void *start, void *end)
5540520Sdfr{
5640520Sdfr    zextendPool(&MallocPool, start, (caddr_t)end - (caddr_t)start);
5740520Sdfr    zfree(&MallocPool, start, (caddr_t)end - (caddr_t)start);
5840520Sdfr}
5940520Sdfr#endif
6040520Sdfr
6139665Smsmithvoid *
6239665Smsmithmalloc(size_t bytes)
6339665Smsmith{
6439665Smsmith    Guard *res;
6539665Smsmith
6639665Smsmith#ifdef USEENDGUARD
6739665Smsmith    bytes += MALLOCALIGN + 1;
6839665Smsmith#else
6939665Smsmith    bytes += MALLOCALIGN;
7039665Smsmith#endif
7139665Smsmith
7239665Smsmith    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
7339665Smsmith	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
7439665Smsmith	char *base;
7539665Smsmith
7639665Smsmith	if ((base = sbrk(incr)) == (char *)-1)
7739665Smsmith	    return(NULL);
7839665Smsmith	zextendPool(&MallocPool, base, incr);
7939665Smsmith	zfree(&MallocPool, base, incr);
8039665Smsmith    }
8139665Smsmith#ifdef DMALLOCDEBUG
8239665Smsmith    if (++MallocCount > MallocMax)
8339665Smsmith	MallocMax = MallocCount;
8439665Smsmith#endif
8539665Smsmith#ifdef USEGUARD
8639665Smsmith    res->ga_Magic = GAMAGIC;
8739665Smsmith#endif
8839665Smsmith    res->ga_Bytes = bytes;
8939665Smsmith#ifdef USEENDGUARD
9039665Smsmith    *((char *)res + bytes - 1) = -2;
9139665Smsmith#endif
9239665Smsmith    return((char *)res + MALLOCALIGN);
9339665Smsmith}
9439665Smsmith
9539665Smsmithvoid
9639665Smsmithfree(void *ptr)
9739665Smsmith{
9839665Smsmith    size_t bytes;
9939665Smsmith
10039665Smsmith    if (ptr != NULL) {
10139665Smsmith	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
10239665Smsmith
10339665Smsmith#ifdef USEGUARD
10439863Smsmith	if (res->ga_Magic != GAMAGIC)
10539863Smsmith	    panic("free: guard1 fail @ %p", ptr);
10639665Smsmith	res->ga_Magic = -1;
10739665Smsmith#endif
10839665Smsmith#ifdef USEENDGUARD
10939863Smsmith	if (*((char *)res + res->ga_Bytes - 1) != -2)
11039863Smsmith	    panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
11139665Smsmith	*((char *)res + res->ga_Bytes - 1) = -1;
11239665Smsmith#endif
11339665Smsmith
11439665Smsmith	bytes = res->ga_Bytes;
11539665Smsmith	zfree(&MallocPool, res, bytes);
11639665Smsmith#ifdef DMALLOCDEBUG
11739665Smsmith	--MallocCount;
11839665Smsmith#endif
11939665Smsmith    }
12039665Smsmith}
12139665Smsmith
12239665Smsmith
12339665Smsmithvoid *
12439665Smsmithcalloc(size_t n1, size_t n2)
12539665Smsmith{
12639665Smsmith    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
12739665Smsmith    void *res;
12839665Smsmith
12939665Smsmith    if ((res = malloc(bytes)) != NULL) {
13039665Smsmith	bzero(res, bytes);
13139665Smsmith#ifdef DMALLOCDEBUG
13239665Smsmith	if (++MallocCount > MallocMax)
13339665Smsmith	    MallocMax = MallocCount;
13439665Smsmith#endif
13539665Smsmith    }
13639665Smsmith    return(res);
13739665Smsmith}
13839665Smsmith
13939665Smsmith/*
14039665Smsmith * realloc() - I could be fancier here and free the old buffer before
14139665Smsmith * 	       allocating the new one (saving potential fragmentation
14239665Smsmith *	       and potential buffer copies).  But I don't bother.
14339665Smsmith */
14439665Smsmith
14539665Smsmithvoid *
14639665Smsmithrealloc(void *ptr, size_t size)
14739665Smsmith{
14839665Smsmith    void *res;
14939665Smsmith    size_t old;
15039665Smsmith
15139665Smsmith    if ((res = malloc(size)) != NULL) {
15239665Smsmith	if (ptr) {
15339665Smsmith	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
15439665Smsmith	    if (old < size)
15539665Smsmith		bcopy(ptr, res, old);
15639665Smsmith	    else
15739665Smsmith		bcopy(ptr, res, size);
15839665Smsmith	    free(ptr);
15939665Smsmith	} else {
16039665Smsmith#ifdef DMALLOCDEBUG
16139665Smsmith	    if (++MallocCount > MallocMax)
16239665Smsmith		MallocMax = MallocCount;
16339665Smsmith#ifdef EXITSTATS
16439665Smsmith	    if (DidAtExit == 0) {
16539665Smsmith		DidAtExit = 1;
16639665Smsmith		atexit(mallocstats);
16739665Smsmith	    }
16839665Smsmith#endif
16939665Smsmith#endif
17039665Smsmith	}
17139665Smsmith    }
17239665Smsmith    return(res);
17339665Smsmith}
17439665Smsmith
17539665Smsmithvoid *
17639665Smsmithreallocf(void *ptr, size_t size)
17739665Smsmith{
17839665Smsmith    void *res;
17939665Smsmith
18039665Smsmith    if ((res = realloc(ptr, size)) == NULL)
18139665Smsmith	free(ptr);
18239665Smsmith    return(res);
18339665Smsmith}
18439665Smsmith
18539665Smsmith#ifdef DMALLOCDEBUG
18639665Smsmith
18739665Smsmithvoid
18839665Smsmithmallocstats(void)
18939665Smsmith{
19039665Smsmith    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
19139665Smsmith#ifdef ZALLOCDEBUG
19239665Smsmith    zallocstats(&MallocPool);
19339665Smsmith#endif
19439665Smsmith}
19539665Smsmith
19639665Smsmith#endif
19739665Smsmith
198