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