zalloc_malloc.c revision 126206
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 3084221Sdillon#include <sys/cdefs.h> 3184221Sdillon__FBSDID("$FreeBSD: head/lib/libstand/zalloc_malloc.c 126206 2004-02-25 00:52:14Z grehan $"); 3284221Sdillon 3339665Smsmith/* 3439665Smsmith * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk 3539665Smsmith */ 3639665Smsmith 3739665Smsmith#include "zalloc_defs.h" 3839665Smsmith 3939863Smsmithstatic MemPool MallocPool; 4039665Smsmith 4139665Smsmith#ifdef DMALLOCDEBUG 4239665Smsmithstatic int MallocMax; 4339665Smsmithstatic int MallocCount; 4439665Smsmith 4539665Smsmithvoid mallocstats(void); 4639665Smsmith#endif 4739665Smsmith 4839672Sdfr#ifdef malloc 4939672Sdfr#undef malloc 5039672Sdfr#undef free 5139672Sdfr#endif 5239672Sdfr 5340520Sdfr#ifdef __alpha__ 5440520Sdfrvoid 5540520Sdfrfree_region(void *start, void *end) 5640520Sdfr{ 5740520Sdfr zextendPool(&MallocPool, start, (caddr_t)end - (caddr_t)start); 5840520Sdfr zfree(&MallocPool, start, (caddr_t)end - (caddr_t)start); 5940520Sdfr} 6040520Sdfr#endif 6140520Sdfr 6239665Smsmithvoid * 63100394SpeterMalloc(size_t bytes, const char *file, int line) 6439665Smsmith{ 6539665Smsmith Guard *res; 6639665Smsmith 6739665Smsmith#ifdef USEENDGUARD 6839665Smsmith bytes += MALLOCALIGN + 1; 6939665Smsmith#else 7039665Smsmith bytes += MALLOCALIGN; 7139665Smsmith#endif 7239665Smsmith 7339665Smsmith while ((res = znalloc(&MallocPool, bytes)) == NULL) { 7439665Smsmith int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK; 7539665Smsmith char *base; 7639665Smsmith 7739665Smsmith if ((base = sbrk(incr)) == (char *)-1) 7839665Smsmith return(NULL); 7939665Smsmith zextendPool(&MallocPool, base, incr); 8039665Smsmith zfree(&MallocPool, base, incr); 8139665Smsmith } 8239665Smsmith#ifdef DMALLOCDEBUG 8339665Smsmith if (++MallocCount > MallocMax) 8439665Smsmith MallocMax = MallocCount; 8539665Smsmith#endif 8639665Smsmith#ifdef USEGUARD 8739665Smsmith res->ga_Magic = GAMAGIC; 8839665Smsmith#endif 8939665Smsmith res->ga_Bytes = bytes; 9039665Smsmith#ifdef USEENDGUARD 91126206Sgrehan *((signed char *)res + bytes - 1) = -2; 9239665Smsmith#endif 93126206Sgrehan 9439665Smsmith return((char *)res + MALLOCALIGN); 9539665Smsmith} 9639665Smsmith 9739665Smsmithvoid 98100394SpeterFree(void *ptr, const char *file, int line) 9939665Smsmith{ 10039665Smsmith size_t bytes; 10139665Smsmith 10239665Smsmith if (ptr != NULL) { 10339665Smsmith Guard *res = (void *)((char *)ptr - MALLOCALIGN); 10439665Smsmith 105100394Speter if (file == NULL) 106100394Speter file = "unknown"; 10739665Smsmith#ifdef USEGUARD 108100394Speter if (res->ga_Magic == GAFREE) { 109100394Speter printf("free: duplicate free @ %p from %s:%d\n", ptr, file, line); 110100394Speter return; 111100394Speter } 11239863Smsmith if (res->ga_Magic != GAMAGIC) 113124570Sjhb panic("free: guard1 fail @ %p from %s:%d", ptr, file, line); 114100394Speter res->ga_Magic = GAFREE; 11539665Smsmith#endif 11639665Smsmith#ifdef USEENDGUARD 117126206Sgrehan if (*((signed char *)res + res->ga_Bytes - 1) == -1) { 118100394Speter printf("free: duplicate2 free @ %p from %s:%d\n", ptr, file, line); 119100394Speter return; 120100394Speter } 121126206Sgrehan if (*((signed char *)res + res->ga_Bytes - 1) != -2) 122100394Speter panic("free: guard2 fail @ %p + %d from %s:%d", ptr, res->ga_Bytes - MALLOCALIGN, file, line); 123126206Sgrehan *((signed char *)res + res->ga_Bytes - 1) = -1; 12439665Smsmith#endif 12539665Smsmith 12639665Smsmith bytes = res->ga_Bytes; 12739665Smsmith zfree(&MallocPool, res, bytes); 12839665Smsmith#ifdef DMALLOCDEBUG 12939665Smsmith --MallocCount; 13039665Smsmith#endif 13139665Smsmith } 13239665Smsmith} 13339665Smsmith 13439665Smsmith 13539665Smsmithvoid * 136100394SpeterCalloc(size_t n1, size_t n2, const char *file, int line) 13739665Smsmith{ 13839665Smsmith iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2; 13939665Smsmith void *res; 14039665Smsmith 141100394Speter if ((res = Malloc(bytes, file, line)) != NULL) { 14239665Smsmith bzero(res, bytes); 14339665Smsmith#ifdef DMALLOCDEBUG 14439665Smsmith if (++MallocCount > MallocMax) 14539665Smsmith MallocMax = MallocCount; 14639665Smsmith#endif 14739665Smsmith } 14839665Smsmith return(res); 14939665Smsmith} 15039665Smsmith 15139665Smsmith/* 15239665Smsmith * realloc() - I could be fancier here and free the old buffer before 15339665Smsmith * allocating the new one (saving potential fragmentation 15439665Smsmith * and potential buffer copies). But I don't bother. 15539665Smsmith */ 15639665Smsmith 15739665Smsmithvoid * 158100394SpeterRealloc(void *ptr, size_t size, const char *file, int line) 15939665Smsmith{ 16039665Smsmith void *res; 16139665Smsmith size_t old; 16239665Smsmith 163100394Speter if ((res = Malloc(size, file, line)) != NULL) { 16439665Smsmith if (ptr) { 16539665Smsmith old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN; 16639665Smsmith if (old < size) 16739665Smsmith bcopy(ptr, res, old); 16839665Smsmith else 16939665Smsmith bcopy(ptr, res, size); 170100394Speter Free(ptr, file, line); 17139665Smsmith } else { 17239665Smsmith#ifdef DMALLOCDEBUG 17339665Smsmith if (++MallocCount > MallocMax) 17439665Smsmith MallocMax = MallocCount; 17539665Smsmith#ifdef EXITSTATS 17639665Smsmith if (DidAtExit == 0) { 17739665Smsmith DidAtExit = 1; 17839665Smsmith atexit(mallocstats); 17939665Smsmith } 18039665Smsmith#endif 18139665Smsmith#endif 18239665Smsmith } 18339665Smsmith } 18439665Smsmith return(res); 18539665Smsmith} 18639665Smsmith 18739665Smsmithvoid * 188100394SpeterReallocf(void *ptr, size_t size, const char *file, int line) 18939665Smsmith{ 19039665Smsmith void *res; 19139665Smsmith 192100394Speter if ((res = Realloc(ptr, size, file, line)) == NULL) 193100394Speter Free(ptr, file, line); 19439665Smsmith return(res); 19539665Smsmith} 19639665Smsmith 19739665Smsmith#ifdef DMALLOCDEBUG 19839665Smsmith 19939665Smsmithvoid 20039665Smsmithmallocstats(void) 20139665Smsmith{ 20239665Smsmith printf("Active Allocations: %d/%d\n", MallocCount, MallocMax); 20339665Smsmith#ifdef ZALLOCDEBUG 20439665Smsmith zallocstats(&MallocPool); 20539665Smsmith#endif 20639665Smsmith} 20739665Smsmith 20839665Smsmith#endif 20939665Smsmith 210