zalloc_malloc.c revision 223905
1139826Simp/* 253541Sshin * This module derived from code donated to the FreeBSD Project by 353541Sshin * Matthew Dillon <dillon@backplane.com> 453541Sshin * 553541Sshin * Copyright (c) 1998 The FreeBSD Project 653541Sshin * All rights reserved. 753541Sshin * 853541Sshin * Redistribution and use in source and binary forms, with or without 953541Sshin * modification, are permitted provided that the following conditions 1053541Sshin * are met: 1153541Sshin * 1. Redistributions of source code must retain the above copyright 1253541Sshin * notice, this list of conditions and the following disclaimer. 1353541Sshin * 2. Redistributions in binary form must reproduce the above copyright 1453541Sshin * notice, this list of conditions and the following disclaimer in the 1553541Sshin * documentation and/or other materials provided with the distribution. 1653541Sshin * 1753541Sshin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 1853541Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1953541Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2053541Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2153541Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2253541Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2353541Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2453541Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2553541Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2653541Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2753541Sshin * SUCH DAMAGE. 28174510Sobrien */ 29174510Sobrien 3053541Sshin#include <sys/cdefs.h> 3153541Sshin__FBSDID("$FreeBSD: head/lib/libstand/zalloc_malloc.c 223905 2011-07-10 07:25:34Z avatar $"); 32139826Simp 3353541Sshin/* 3453541Sshin * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk 3553541Sshin */ 3653541Sshin 3753541Sshin#include "zalloc_defs.h" 3853541Sshin 3953541Sshinstatic MemPool MallocPool; 4053541Sshin 4153541Sshin#ifdef DMALLOCDEBUG 4253541Sshinstatic int MallocMax; 4353541Sshinstatic int MallocCount; 4453541Sshin 4553541Sshinvoid mallocstats(void); 4653541Sshin#endif 4753541Sshin 4853541Sshin#ifdef malloc 4953541Sshin#undef malloc 5053541Sshin#undef free 5153541Sshin#endif 5253541Sshin 5353541Sshinvoid * 5453541SshinMalloc(size_t bytes, const char *file, int line) 5553541Sshin{ 5653541Sshin Guard *res; 5753541Sshin 5853541Sshin#ifdef USEENDGUARD 5953541Sshin bytes += MALLOCALIGN + 1; 6053541Sshin#else 6153541Sshin bytes += MALLOCALIGN; 6253541Sshin#endif 63174510Sobrien 64174510Sobrien while ((res = znalloc(&MallocPool, bytes)) == NULL) { 65174510Sobrien int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK; 6662587Sitojun char *base; 6762587Sitojun 68225044Sbz if ((base = sbrk(incr)) == (char *)-1) 6955009Sshin return(NULL); 70207828Skmacy zextendPool(&MallocPool, base, incr); 7155009Sshin zfree(&MallocPool, base, incr); 7253541Sshin } 7353541Sshin#ifdef DMALLOCDEBUG 7478064Sume if (++MallocCount > MallocMax) 7553541Sshin MallocMax = MallocCount; 7683366Sjulian#endif 7753541Sshin#ifdef USEGUARD 7853541Sshin res->ga_Magic = GAMAGIC; 7953541Sshin#endif 8053541Sshin res->ga_Bytes = bytes; 8153541Sshin#ifdef USEENDGUARD 8253541Sshin *((signed char *)res + bytes - 1) = -2; 8353541Sshin#endif 8453541Sshin 8553541Sshin return((char *)res + MALLOCALIGN); 8653541Sshin} 8753541Sshin 8853541Sshinvoid 8953541SshinFree(void *ptr, const char *file, int line) 9053541Sshin{ 9164060Sdarrenr size_t bytes; 92185571Sbz 9353541Sshin if (ptr != NULL) { 9453541Sshin Guard *res = (void *)((char *)ptr - MALLOCALIGN); 95225044Sbz 9653541Sshin if (file == NULL) 97186119Sqingli file = "unknown"; 9862587Sitojun#ifdef USEGUARD 9953541Sshin if (res->ga_Magic == GAFREE) { 10053541Sshin printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line); 10195023Ssuz return; 10262587Sitojun } 10353541Sshin if (res->ga_Magic != GAMAGIC) 10453541Sshin panic("free: guard1 fail @ %p from %s:%d", ptr, file, line); 10562587Sitojun res->ga_Magic = GAFREE; 10662587Sitojun#endif 107121161Sume#ifdef USEENDGUARD 10853541Sshin if (*((signed char *)res + res->ga_Bytes - 1) == -1) { 10953541Sshin printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line); 11053541Sshin return; 111171167Sgnn } 112105199Ssam if (*((signed char *)res + res->ga_Bytes - 1) != -2) 113171133Sgnn panic("free: guard2 fail @ %p + %zu from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line); 114105199Ssam *((signed char *)res + res->ga_Bytes - 1) = -1; 115171167Sgnn#endif 116105199Ssam 11753541Sshin bytes = res->ga_Bytes; 11853541Sshin zfree(&MallocPool, res, bytes); 119207828Skmacy#ifdef DMALLOCDEBUG 120207828Skmacy --MallocCount; 121208043Skmacy#endif 122207828Skmacy } 123207828Skmacy} 124207828Skmacy 12562587Sitojun 12653541Sshinvoid * 12762587SitojunCalloc(size_t n1, size_t n2, const char *file, int line) 128207369Sbz{ 129185088Szec uintptr_t bytes = (uintptr_t)n1 * (uintptr_t)n2; 130193219Srwatson void *res; 131193219Srwatson 132193219Srwatson if ((res = Malloc(bytes, file, line)) != NULL) { 133193219Srwatson bzero(res, bytes); 134193219Srwatson#ifdef DMALLOCDEBUG 135193219Srwatson if (++MallocCount > MallocMax) 136193219Srwatson MallocMax = MallocCount; 137195699Srwatson#endif 138195727Srwatson } 13978064Sume return(res); 140207369Sbz} 141207369Sbz 142207369Sbz/* 143207369Sbz * realloc() - I could be fancier here and free the old buffer before 144194971Srwatson * allocating the new one (saving potential fragmentation 145194971Srwatson * and potential buffer copies). But I don't bother. 146194971Srwatson */ 147175162Sobrien 148175162Sobrienvoid * 149238233SbzRealloc(void *ptr, size_t size, const char *file, int line) 150238233Sbz{ 151238233Sbz void *res; 152175162Sobrien size_t old; 15362587Sitojun 154175162Sobrien if ((res = Malloc(size, file, line)) != NULL) { 15553541Sshin if (ptr) { 15653541Sshin old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN; 15753541Sshin if (old < size) 15853541Sshin bcopy(ptr, res, old); 15953541Sshin else 16053541Sshin bcopy(ptr, res, size); 16153541Sshin Free(ptr, file, line); 162171259Sdelphij } else { 16353541Sshin#ifdef DMALLOCDEBUG 16478064Sume if (++MallocCount > MallocMax) 16578064Sume MallocMax = MallocCount; 16653541Sshin#ifdef EXITSTATS 167185895Szec if (DidAtExit == 0) { 168185895Szec DidAtExit = 1; 169253239Shrs atexit(mallocstats); 170253239Shrs } 171185088Szec#endif 172207369Sbz#endif 173185088Szec } 174207369Sbz } 175207369Sbz return(res); 176207369Sbz} 177207369Sbz 178207369Sbzvoid * 179207369SbzReallocf(void *ptr, size_t size, const char *file, int line) 180185088Szec{ 181190787Szec void *res; 182190787Szec 183190787Szec if ((res = Realloc(ptr, size, file, line)) == NULL) 184190787Szec Free(ptr, file, line); 185190787Szec return(res); 186207828Skmacy} 187207902Skmacy 188207902Skmacy#ifdef DMALLOCDEBUG 189207902Skmacy 190207902Skmacyvoid 191207902Skmacymallocstats(void) 192207902Skmacy{ 193207902Skmacy printf("Active Allocations: %d/%d\n", MallocCount, MallocMax); 194207902Skmacy#ifdef ZALLOCDEBUG 195207902Skmacy zallocstats(&MallocPool); 196207902Skmacy#endif 197207902Skmacy} 198207902Skmacy 199207902Skmacy#endif 200207902Skmacy 201208171Skmacy