zalloc_malloc.c revision 39863
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 *
2939863Smsmith *	$Id: zalloc_malloc.c,v 1.2 1998/09/26 10:48:50 dfr 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
5239665Smsmithvoid *
5339665Smsmithmalloc(size_t bytes)
5439665Smsmith{
5539665Smsmith    Guard *res;
5639665Smsmith
5739665Smsmith#ifdef USEENDGUARD
5839665Smsmith    bytes += MALLOCALIGN + 1;
5939665Smsmith#else
6039665Smsmith    bytes += MALLOCALIGN;
6139665Smsmith#endif
6239665Smsmith
6339665Smsmith    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
6439665Smsmith	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
6539665Smsmith	char *base;
6639665Smsmith
6739665Smsmith	if ((base = sbrk(incr)) == (char *)-1)
6839665Smsmith	    return(NULL);
6939665Smsmith	zextendPool(&MallocPool, base, incr);
7039665Smsmith	zfree(&MallocPool, base, incr);
7139665Smsmith    }
7239665Smsmith#ifdef DMALLOCDEBUG
7339665Smsmith    if (++MallocCount > MallocMax)
7439665Smsmith	MallocMax = MallocCount;
7539665Smsmith#endif
7639665Smsmith#ifdef USEGUARD
7739665Smsmith    res->ga_Magic = GAMAGIC;
7839665Smsmith#endif
7939665Smsmith    res->ga_Bytes = bytes;
8039665Smsmith#ifdef USEENDGUARD
8139665Smsmith    *((char *)res + bytes - 1) = -2;
8239665Smsmith#endif
8339665Smsmith    return((char *)res + MALLOCALIGN);
8439665Smsmith}
8539665Smsmith
8639665Smsmithvoid
8739665Smsmithfree(void *ptr)
8839665Smsmith{
8939665Smsmith    size_t bytes;
9039665Smsmith
9139665Smsmith    if (ptr != NULL) {
9239665Smsmith	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
9339665Smsmith
9439665Smsmith#ifdef USEGUARD
9539863Smsmith	if (res->ga_Magic != GAMAGIC)
9639863Smsmith	    panic("free: guard1 fail @ %p", ptr);
9739665Smsmith	res->ga_Magic = -1;
9839665Smsmith#endif
9939665Smsmith#ifdef USEENDGUARD
10039863Smsmith	if (*((char *)res + res->ga_Bytes - 1) != -2)
10139863Smsmith	    panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
10239665Smsmith	*((char *)res + res->ga_Bytes - 1) = -1;
10339665Smsmith#endif
10439665Smsmith
10539665Smsmith	bytes = res->ga_Bytes;
10639665Smsmith	zfree(&MallocPool, res, bytes);
10739665Smsmith#ifdef DMALLOCDEBUG
10839665Smsmith	--MallocCount;
10939665Smsmith#endif
11039665Smsmith    }
11139665Smsmith}
11239665Smsmith
11339665Smsmith
11439665Smsmithvoid *
11539665Smsmithcalloc(size_t n1, size_t n2)
11639665Smsmith{
11739665Smsmith    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
11839665Smsmith    void *res;
11939665Smsmith
12039665Smsmith    if ((res = malloc(bytes)) != NULL) {
12139665Smsmith	bzero(res, bytes);
12239665Smsmith#ifdef DMALLOCDEBUG
12339665Smsmith	if (++MallocCount > MallocMax)
12439665Smsmith	    MallocMax = MallocCount;
12539665Smsmith#endif
12639665Smsmith    }
12739665Smsmith    return(res);
12839665Smsmith}
12939665Smsmith
13039665Smsmith/*
13139665Smsmith * realloc() - I could be fancier here and free the old buffer before
13239665Smsmith * 	       allocating the new one (saving potential fragmentation
13339665Smsmith *	       and potential buffer copies).  But I don't bother.
13439665Smsmith */
13539665Smsmith
13639665Smsmithvoid *
13739665Smsmithrealloc(void *ptr, size_t size)
13839665Smsmith{
13939665Smsmith    void *res;
14039665Smsmith    size_t old;
14139665Smsmith
14239665Smsmith    if ((res = malloc(size)) != NULL) {
14339665Smsmith	if (ptr) {
14439665Smsmith	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
14539665Smsmith	    if (old < size)
14639665Smsmith		bcopy(ptr, res, old);
14739665Smsmith	    else
14839665Smsmith		bcopy(ptr, res, size);
14939665Smsmith	    free(ptr);
15039665Smsmith	} else {
15139665Smsmith#ifdef DMALLOCDEBUG
15239665Smsmith	    if (++MallocCount > MallocMax)
15339665Smsmith		MallocMax = MallocCount;
15439665Smsmith#ifdef EXITSTATS
15539665Smsmith	    if (DidAtExit == 0) {
15639665Smsmith		DidAtExit = 1;
15739665Smsmith		atexit(mallocstats);
15839665Smsmith	    }
15939665Smsmith#endif
16039665Smsmith#endif
16139665Smsmith	}
16239665Smsmith    }
16339665Smsmith    return(res);
16439665Smsmith}
16539665Smsmith
16639665Smsmithvoid *
16739665Smsmithreallocf(void *ptr, size_t size)
16839665Smsmith{
16939665Smsmith    void *res;
17039665Smsmith
17139665Smsmith    if ((res = realloc(ptr, size)) == NULL)
17239665Smsmith	free(ptr);
17339665Smsmith    return(res);
17439665Smsmith}
17539665Smsmith
17639665Smsmith#ifdef DMALLOCDEBUG
17739665Smsmith
17839665Smsmithvoid
17939665Smsmithmallocstats(void)
18039665Smsmith{
18139665Smsmith    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
18239665Smsmith#ifdef ZALLOCDEBUG
18339665Smsmith    zallocstats(&MallocPool);
18439665Smsmith#endif
18539665Smsmith}
18639665Smsmith
18739665Smsmith#endif
18839665Smsmith
189