zalloc_malloc.c revision 84221
144301Swollman/*
244301Swollman * This module derived from code donated to the FreeBSD Project by
344301Swollman * Matthew Dillon <dillon@backplane.com>
444301Swollman *
544301Swollman * Copyright (c) 1998 The FreeBSD Project
644301Swollman * All rights reserved.
744301Swollman *
844301Swollman * Redistribution and use in source and binary forms, with or without
944301Swollman * modification, are permitted provided that the following conditions
1044301Swollman * are met:
1144301Swollman * 1. Redistributions of source code must retain the above copyright
1244301Swollman *    notice, this list of conditions and the following disclaimer.
1344301Swollman * 2. Redistributions in binary form must reproduce the above copyright
1444301Swollman *    notice, this list of conditions and the following disclaimer in the
1544301Swollman *    documentation and/or other materials provided with the distribution.
1644301Swollman *
1744301Swollman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1844301Swollman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1944301Swollman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2044301Swollman * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2144301Swollman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2244301Swollman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2344301Swollman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2444301Swollman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2544301Swollman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2644301Swollman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2744301Swollman * SUCH DAMAGE.
2844301Swollman */
2944301Swollman
3044301Swollman#include <sys/cdefs.h>
3144301Swollman__FBSDID("$FreeBSD: head/lib/libstand/zalloc_malloc.c 84221 2001-09-30 22:28:01Z dillon $");
3244301Swollman
3344301Swollman/*
3444301Swollman * MALLOC.C - malloc equivalent, runs on top of zalloc and uses sbrk
3544301Swollman */
3644301Swollman
3744301Swollman#include "zalloc_defs.h"
3844301Swollman
3944301Swollmanstatic MemPool	MallocPool;
4044301Swollman
4144301Swollman#ifdef DMALLOCDEBUG
4244301Swollmanstatic int MallocMax;
4344301Swollmanstatic int MallocCount;
4444301Swollman
4544301Swollmanvoid mallocstats(void);
4644301Swollman#endif
4744301Swollman
4844301Swollman#ifdef malloc
4944301Swollman#undef malloc
5044301Swollman#undef free
5144301Swollman#endif
5244301Swollman
5344301Swollman#ifdef __alpha__
5444301Swollmanvoid
5544301Swollmanfree_region(void *start, void *end)
5644301Swollman{
5744301Swollman    zextendPool(&MallocPool, start, (caddr_t)end - (caddr_t)start);
5844301Swollman    zfree(&MallocPool, start, (caddr_t)end - (caddr_t)start);
5974385Sphk}
6074385Sphk#endif
6174385Sphk
6274385Sphkvoid *
6344301Swollmanmalloc(size_t bytes)
6444301Swollman{
6544301Swollman    Guard *res;
6644301Swollman
6744301Swollman#ifdef USEENDGUARD
6844301Swollman    bytes += MALLOCALIGN + 1;
6944301Swollman#else
7044301Swollman    bytes += MALLOCALIGN;
7144301Swollman#endif
7244301Swollman
7344301Swollman    while ((res = znalloc(&MallocPool, bytes)) == NULL) {
7444301Swollman	int incr = (bytes + BLKEXTENDMASK) & ~BLKEXTENDMASK;
7544301Swollman	char *base;
7644301Swollman
7744301Swollman	if ((base = sbrk(incr)) == (char *)-1)
7844301Swollman	    return(NULL);
7944301Swollman	zextendPool(&MallocPool, base, incr);
8044301Swollman	zfree(&MallocPool, base, incr);
8144301Swollman    }
8244301Swollman#ifdef DMALLOCDEBUG
8344301Swollman    if (++MallocCount > MallocMax)
8444301Swollman	MallocMax = MallocCount;
85154479Sphk#endif
8644301Swollman#ifdef USEGUARD
8744301Swollman    res->ga_Magic = GAMAGIC;
8844301Swollman#endif
8944301Swollman    res->ga_Bytes = bytes;
9074385Sphk#ifdef USEENDGUARD
91154479Sphk    *((char *)res + bytes - 1) = -2;
9244301Swollman#endif
9344301Swollman    return((char *)res + MALLOCALIGN);
9444301Swollman}
95
96void
97free(void *ptr)
98{
99    size_t bytes;
100
101    if (ptr != NULL) {
102	Guard *res = (void *)((char *)ptr - MALLOCALIGN);
103
104#ifdef USEGUARD
105	if (res->ga_Magic != GAMAGIC)
106	    panic("free: guard1 fail @ %p", ptr);
107	res->ga_Magic = -1;
108#endif
109#ifdef USEENDGUARD
110	if (*((char *)res + res->ga_Bytes - 1) != -2)
111	    panic("free: guard2 fail @ %p + %d", ptr, res->ga_Bytes - MALLOCALIGN);
112	*((char *)res + res->ga_Bytes - 1) = -1;
113#endif
114
115	bytes = res->ga_Bytes;
116	zfree(&MallocPool, res, bytes);
117#ifdef DMALLOCDEBUG
118	--MallocCount;
119#endif
120    }
121}
122
123
124void *
125calloc(size_t n1, size_t n2)
126{
127    iaddr_t bytes = (iaddr_t)n1 * (iaddr_t)n2;
128    void *res;
129
130    if ((res = malloc(bytes)) != NULL) {
131	bzero(res, bytes);
132#ifdef DMALLOCDEBUG
133	if (++MallocCount > MallocMax)
134	    MallocMax = MallocCount;
135#endif
136    }
137    return(res);
138}
139
140/*
141 * realloc() - I could be fancier here and free the old buffer before
142 * 	       allocating the new one (saving potential fragmentation
143 *	       and potential buffer copies).  But I don't bother.
144 */
145
146void *
147realloc(void *ptr, size_t size)
148{
149    void *res;
150    size_t old;
151
152    if ((res = malloc(size)) != NULL) {
153	if (ptr) {
154	    old = *(size_t *)((char *)ptr - MALLOCALIGN) - MALLOCALIGN;
155	    if (old < size)
156		bcopy(ptr, res, old);
157	    else
158		bcopy(ptr, res, size);
159	    free(ptr);
160	} else {
161#ifdef DMALLOCDEBUG
162	    if (++MallocCount > MallocMax)
163		MallocMax = MallocCount;
164#ifdef EXITSTATS
165	    if (DidAtExit == 0) {
166		DidAtExit = 1;
167		atexit(mallocstats);
168	    }
169#endif
170#endif
171	}
172    }
173    return(res);
174}
175
176void *
177reallocf(void *ptr, size_t size)
178{
179    void *res;
180
181    if ((res = realloc(ptr, size)) == NULL)
182	free(ptr);
183    return(res);
184}
185
186#ifdef DMALLOCDEBUG
187
188void
189mallocstats(void)
190{
191    printf("Active Allocations: %d/%d\n", MallocCount, MallocMax);
192#ifdef ZALLOCDEBUG
193    zallocstats(&MallocPool);
194#endif
195}
196
197#endif
198
199