zalloc_malloc.c revision 39665
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 *
2939665Smsmith *	$Id$
3039665Smsmith */
3139665Smsmith
3239665Smsmith/*
3339665Smsmith * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
3439665Smsmith */
3539665Smsmith
3639665Smsmith#include "zalloc_defs.h"
3739665Smsmith
3839665Smsmithstatic MemPool	MallocPool = INITPOOL("malloc", panic, znot);
3939665Smsmith
4039665Smsmith#ifdef DMALLOCDEBUG
4139665Smsmithstatic int MallocMax;
4239665Smsmithstatic int MallocCount;
4339665Smsmith
4439665Smsmithvoid mallocstats(void);
4539665Smsmith#endif
4639665Smsmith
4739665Smsmithvoid *
4839665Smsmithmalloc(size_t bytes)
4939665Smsmith{
5039665Smsmith    Guard *res;
5139665Smsmith
5239665Smsmith#ifdef USEENDGUARD
5339665Smsmith    bytes += MALLOCALIGN + 1;
5439665Smsmith#else
5539665Smsmith    bytes += MALLOCALIGN;
5639665Smsmith#endif
5739665Smsmith
5839665Smsmith    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
5939665Smsmith	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
6039665Smsmith	char *base;
6139665Smsmith
6239665Smsmith	if ((base = sbrk(incr)) == (char *)-1)
6339665Smsmith	    return(NULL);
6439665Smsmith	zextendPool(&MallocPool, base, incr);
6539665Smsmith	zfree(&MallocPool, base, incr);
6639665Smsmith    }
6739665Smsmith#ifdef DMALLOCDEBUG
6839665Smsmith    if (++MallocCount > MallocMax)
6939665Smsmith	MallocMax = MallocCount;
7039665Smsmith#endif
7139665Smsmith#ifdef USEGUARD
7239665Smsmith    res->ga_Magic = GAMAGIC;
7339665Smsmith#endif
7439665Smsmith    res->ga_Bytes = bytes;
7539665Smsmith#ifdef USEENDGUARD
7639665Smsmith    *((char *)res + bytes - 1) = -2;
7739665Smsmith#endif
7839665Smsmith    return((char *)res + MALLOCALIGN);
7939665Smsmith}
8039665Smsmith
8139665Smsmithvoid
8239665Smsmithfree(void *ptr)
8339665Smsmith{
8439665Smsmith    size_t bytes;
8539665Smsmith
8639665Smsmith    if (ptr != NULL) {
8739665Smsmith	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
8839665Smsmith
8939665Smsmith#ifdef USEGUARD
9039665Smsmith	if (res->ga_Magic != GAMAGIC) {
9139665Smsmith#ifdef USEPANIC
9239665Smsmith	    panic("free(): guard1 fail @ %08lx\n", ptr);
9339665Smsmith#else
9439665Smsmith	    *(char *)0 = 1;
9539665Smsmith#endif
9639665Smsmith	}
9739665Smsmith	res->ga_Magic = -1;
9839665Smsmith#endif
9939665Smsmith#ifdef USEENDGUARD
10039665Smsmith	if (*((char *)res + res->ga_Bytes - 1) != -2) {
10139665Smsmith#ifdef USEPANIC
10239665Smsmith	    panic("free(): guard2 fail @ %08lx + %d\n", ptr, res->ga_Bytes - MALLOCALIGN);
10339665Smsmith#else
10439665Smsmith	    *(char *)0 = 1;
10539665Smsmith#endif
10639665Smsmith	}
10739665Smsmith	*((char *)res + res->ga_Bytes - 1) = -1;
10839665Smsmith#endif
10939665Smsmith
11039665Smsmith	bytes = res->ga_Bytes;
11139665Smsmith	zfree(&MallocPool, res, bytes);
11239665Smsmith#ifdef DMALLOCDEBUG
11339665Smsmith	--MallocCount;
11439665Smsmith#endif
11539665Smsmith    }
11639665Smsmith}
11739665Smsmith
11839665Smsmith
11939665Smsmithvoid *
12039665Smsmithcalloc(size_t n1, size_t n2)
12139665Smsmith{
12239665Smsmith    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
12339665Smsmith    void *res;
12439665Smsmith
12539665Smsmith    if ((res = malloc(bytes)) != NULL) {
12639665Smsmith	bzero(res, bytes);
12739665Smsmith#ifdef DMALLOCDEBUG
12839665Smsmith	if (++MallocCount > MallocMax)
12939665Smsmith	    MallocMax = MallocCount;
13039665Smsmith#endif
13139665Smsmith    }
13239665Smsmith    return(res);
13339665Smsmith}
13439665Smsmith
13539665Smsmith/*
13639665Smsmith * realloc() - I could be fancier here and free the old buffer before
13739665Smsmith * 	       allocating the new one (saving potential fragmentation
13839665Smsmith *	       and potential buffer copies).  But I don't bother.
13939665Smsmith */
14039665Smsmith
14139665Smsmithvoid *
14239665Smsmithrealloc(void *ptr, size_t size)
14339665Smsmith{
14439665Smsmith    void *res;
14539665Smsmith    size_t old;
14639665Smsmith
14739665Smsmith    if ((res = malloc(size)) != NULL) {
14839665Smsmith	if (ptr) {
14939665Smsmith	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
15039665Smsmith	    if (old < size)
15139665Smsmith		bcopy(ptr, res, old);
15239665Smsmith	    else
15339665Smsmith		bcopy(ptr, res, size);
15439665Smsmith	    free(ptr);
15539665Smsmith	} else {
15639665Smsmith#ifdef DMALLOCDEBUG
15739665Smsmith	    if (++MallocCount > MallocMax)
15839665Smsmith		MallocMax = MallocCount;
15939665Smsmith#ifdef EXITSTATS
16039665Smsmith	    if (DidAtExit == 0) {
16139665Smsmith		DidAtExit = 1;
16239665Smsmith		atexit(mallocstats);
16339665Smsmith	    }
16439665Smsmith#endif
16539665Smsmith#endif
16639665Smsmith	}
16739665Smsmith    }
16839665Smsmith    return(res);
16939665Smsmith}
17039665Smsmith
17139665Smsmithvoid *
17239665Smsmithreallocf(void *ptr, size_t size)
17339665Smsmith{
17439665Smsmith    void *res;
17539665Smsmith
17639665Smsmith    if ((res = realloc(ptr, size)) == NULL)
17739665Smsmith	free(ptr);
17839665Smsmith    return(res);
17939665Smsmith}
18039665Smsmith
18139665Smsmith#ifdef DMALLOCDEBUG
18239665Smsmith
18339665Smsmithvoid
18439665Smsmithmallocstats(void)
18539665Smsmith{
18639665Smsmith    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
18739665Smsmith#ifdef ZALLOCDEBUG
18839665Smsmith    zallocstats(&MallocPool);
18939665Smsmith#endif
19039665Smsmith}
19139665Smsmith
19239665Smsmith#endif
19339665Smsmith
194