zalloc_malloc.c revision 39863
153889Sbrian/* 253889Sbrian * This module derived from code donated to the FreeBSD Project by 336285Sbrian * Matthew Dillon <dillon@backplane.com> 436285Sbrian * 536285Sbrian * Copyright (c) 1998 The FreeBSD Project 636285Sbrian * All rights reserved. 736285Sbrian * 836285Sbrian * Redistribution and use in source and binary forms, with or without 936285Sbrian * modification, are permitted provided that the following conditions 1036285Sbrian * are met: 1136285Sbrian * 1. Redistributions of source code must retain the above copyright 1236285Sbrian * notice, this list of conditions and the following disclaimer. 1336285Sbrian * 2. Redistributions in binary form must reproduce the above copyright 1436285Sbrian * notice, this list of conditions and the following disclaimer in the 1536285Sbrian * documentation and/or other materials provided with the distribution. 1636285Sbrian * 1736285Sbrian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1836285Sbrian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1936285Sbrian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2036285Sbrian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2136285Sbrian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2236285Sbrian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2336285Sbrian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2436285Sbrian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2536285Sbrian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2636285Sbrian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2736285Sbrian * SUCH DAMAGE. 2836285Sbrian * 2936285Sbrian * $Id: zalloc_malloc.c,v 1.2 1998/09/26 10:48:50 dfr Exp $ 3036285Sbrian */ 3136285Sbrian 3236285Sbrian/* 3336285Sbrian * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk 3436285Sbrian */ 3536285Sbrian 3636285Sbrian#include "zalloc_defs.h" 3736285Sbrian 3836285Sbrianstatic MemPool MallocPool; 3936466Sbrian 4036285Sbrian#ifdef DMALLOCDEBUG 4136285Sbrianstatic int MallocMax; 4236285Sbrianstatic int MallocCount; 4336285Sbrian 4436285Sbrianvoid mallocstats(void); 4536774Sbrian#endif 4636774Sbrian 4736285Sbrian#ifdef malloc 4836285Sbrian#undef malloc 4936285Sbrian#undef free 5036285Sbrian#endif 5136285Sbrian 5236285Sbrianvoid * 5336285Sbrianmalloc(size_t bytes) 5436285Sbrian{ 5549978Sbrian Guard *res; 5649978Sbrian 5749978Sbrian#ifdef USEENDGUARD 5836285Sbrian bytes += MALLOCALIGN + 1; 5936285Sbrian#else 6036285Sbrian bytes += MALLOCALIGN; 6136285Sbrian#endif 6236285Sbrian 6336285Sbrian while ((res = znalloc(&MallocPool, bytes)) == NULL) { 6436285Sbrian int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK; 6536285Sbrian char *base; 6636285Sbrian 6736285Sbrian if ((base = sbrk(incr)) == (char *)-1) 6836285Sbrian return(NULL); 6936285Sbrian zextendPool(&MallocPool, base, incr); 7036285Sbrian zfree(&MallocPool, base, incr); 7136285Sbrian } 7236285Sbrian#ifdef DMALLOCDEBUG 7336285Sbrian if (++MallocCount > MallocMax) 7436466Sbrian MallocMax = MallocCount; 7536466Sbrian#endif 7641754Sbrian#ifdef USEGUARD 7741754Sbrian res->ga_Magic = GAMAGIC; 7841754Sbrian#endif 7944073Sbrian res->ga_Bytes = bytes; 8044073Sbrian#ifdef USEENDGUARD 8144261Sbrian *((char *)res + bytes - 1) = -2; 8244261Sbrian#endif 8344796Sbrian return((char *)res + MALLOCALIGN); 8444796Sbrian} 8546102Sbrian 8646102Sbrianvoid 8746102Sbrianfree(void *ptr) 8853889Sbrian{ 8946686Sbrian size_t bytes; 9049140Sbrian 9149140Sbrian if (ptr != NULL) { 9253889Sbrian Guard *res = (void *)((char *)ptr - MALLOCALIGN); 9349434Sbrian 9449434Sbrian#ifdef USEGUARD 9549434Sbrian if (res->ga_Magic != GAMAGIC) 9649472Sbrian panic("free: guard1 fail @ %p", ptr); 9749472Sbrian res->ga_Magic = -1; 9853889Sbrian#endif 99#ifdef USEENDGUARD 100 if (*((char *)res + res->ga_Bytes - 1) != -2) 101 panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN); 102 *((char *)res + res->ga_Bytes - 1) = -1; 103#endif 104 105 bytes = res->ga_Bytes; 106 zfree(&MallocPool, res, bytes); 107#ifdef DMALLOCDEBUG 108 --MallocCount; 109#endif 110 } 111} 112 113 114void * 115calloc(size_t n1, size_t n2) 116{ 117 iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2; 118 void *res; 119 120 if ((res = malloc(bytes)) != NULL) { 121 bzero(res, bytes); 122#ifdef DMALLOCDEBUG 123 if (++MallocCount > MallocMax) 124 MallocMax = MallocCount; 125#endif 126 } 127 return(res); 128} 129 130/* 131 * realloc() - I could be fancier here and free the old buffer before 132 * allocating the new one (saving potential fragmentation 133 * and potential buffer copies). But I don't bother. 134 */ 135 136void * 137realloc(void *ptr, size_t size) 138{ 139 void *res; 140 size_t old; 141 142 if ((res = malloc(size)) != NULL) { 143 if (ptr) { 144 old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN; 145 if (old < size) 146 bcopy(ptr, res, old); 147 else 148 bcopy(ptr, res, size); 149 free(ptr); 150 } else { 151#ifdef DMALLOCDEBUG 152 if (++MallocCount > MallocMax) 153 MallocMax = MallocCount; 154#ifdef EXITSTATS 155 if (DidAtExit == 0) { 156 DidAtExit = 1; 157 atexit(mallocstats); 158 } 159#endif 160#endif 161 } 162 } 163 return(res); 164} 165 166void * 167reallocf(void *ptr, size_t size) 168{ 169 void *res; 170 171 if ((res = realloc(ptr, size)) == NULL) 172 free(ptr); 173 return(res); 174} 175 176#ifdef DMALLOCDEBUG 177 178void 179mallocstats(void) 180{ 181 printf("Active Allocations: %d/%d\n", MallocCount, MallocMax); 182#ifdef ZALLOCDEBUG 183 zallocstats(&MallocPool); 184#endif 185} 186 187#endif 188 189