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