1 /* 2 * This module derived from code donated to the FreeBSD Project by 3 * Matthew Dillon <dillon@backplane.com> 4 * 5 * Copyright (c) 1998 The FreeBSD Project 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD: src/lib/libstand/zalloc_malloc.c,v 1.5 1999/08/28 00:05:35 peter Exp $ 30 * $DragonFly: src/lib/libstand/zalloc_malloc.c,v 1.3 2005/03/13 15:10:03 swildner Exp $ 31 */ 32 33 /* 34 * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk 35 */ 36 37 #include "zalloc_defs.h" 38 39 static MemPool MallocPool; 40 41 #ifdef DMALLOCDEBUG 42 static int MallocMax; 43 static int MallocCount; 44 45 void mallocstats(void); 46 #endif 47 48 #ifdef malloc 49 #undef malloc 50 #undef free 51 #endif 52 53 void * 54 malloc(size_t bytes) 55 { 56 Guard *res; 57 58 #ifdef USEENDGUARD 59 bytes += MALLOCALIGN + 1; 60 #else 61 bytes += MALLOCALIGN; 62 #endif 63 64 while ((res = znalloc(&MallocPool, bytes)) == NULL) { 65 int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK; 66 char *base; 67 68 if ((base = sbrk(incr)) == (char *)-1) 69 return(NULL); 70 zextendPool(&MallocPool, base, incr); 71 zfree(&MallocPool, base, incr); 72 } 73 #ifdef DMALLOCDEBUG 74 if (++MallocCount > MallocMax) 75 MallocMax = MallocCount; 76 #endif 77 #ifdef USEGUARD 78 res->ga_Magic = GAMAGIC; 79 #endif 80 res->ga_Bytes = bytes; 81 #ifdef USEENDGUARD 82 *((char *)res + bytes - 1) = -2; 83 #endif 84 return((char *)res + MALLOCALIGN); 85 } 86 87 void 88 free(void *ptr) 89 { 90 size_t bytes; 91 92 if (ptr != NULL) { 93 Guard *res = (void *)((char *)ptr - MALLOCALIGN); 94 95 #ifdef USEGUARD 96 if (res->ga_Magic != GAMAGIC) 97 panic("free: guard1x fail @ %p", ptr); 98 res->ga_Magic = -1; 99 #endif 100 #ifdef USEENDGUARD 101 if (*((char *)res + res->ga_Bytes - 1) != -2) { 102 panic("free: guard2 fail @ %p + %zu %d/-2", 103 ptr, 104 res->ga_Bytes - MALLOCALIGN - 1, 105 *((char *)res + res->ga_Bytes - 1)); 106 } 107 *((char *)res + res->ga_Bytes - 1) = -1; 108 #endif 109 110 bytes = res->ga_Bytes; 111 zfree(&MallocPool, res, bytes); 112 #ifdef DMALLOCDEBUG 113 --MallocCount; 114 #endif 115 } 116 } 117 118 119 void * 120 calloc(size_t n1, size_t n2) 121 { 122 uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2; 123 void *res; 124 125 if ((res = malloc(bytes)) != NULL) { 126 bzero(res, bytes); 127 } 128 return(res); 129 } 130 131 /* 132 * realloc() - I could be fancier here and free the old buffer before 133 * allocating the new one (saving potential fragmentation 134 * and potential buffer copies). But I don't bother. 135 */ 136 137 void * 138 realloc(void *ptr, size_t size) 139 { 140 void *res; 141 size_t old; 142 143 if ((res = malloc(size)) != NULL) { 144 if (ptr) { 145 old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN; 146 #ifdef USEENDGUARD 147 --old; 148 #endif 149 if (old < size) 150 bcopy(ptr, res, old); 151 else 152 bcopy(ptr, res, size); 153 free(ptr); 154 } else { 155 #ifdef DMALLOCDEBUG 156 #ifdef EXITSTATS 157 if (DidAtExit == 0) { 158 DidAtExit = 1; 159 atexit(mallocstats); 160 } 161 #endif 162 #endif 163 } 164 } 165 return(res); 166 } 167 168 void * 169 reallocf(void *ptr, size_t size) 170 { 171 void *res; 172 173 if ((res = realloc(ptr, size)) == NULL) 174 free(ptr); 175 return(res); 176 } 177 178 #ifdef DMALLOCDEBUG 179 180 void 181 mallocstats(void) 182 { 183 printf("Active Allocations: %d/%d\n", MallocCount, MallocMax); 184 #ifdef ZALLOCDEBUG 185 zallocstats(&MallocPool); 186 #endif 187 } 188 189 #endif 190 191